All of lore.kernel.org
 help / color / mirror / Atom feed
From: Charlie Jenkins <charlie@rivosinc.com>
To: Atish Patra <atishp@atishpatra.org>
Cc: "Paul Walmsley" <paul.walmsley@sifive.com>,
	"Palmer Dabbelt" <palmer@dabbelt.com>,
	"Albert Ou" <aou@eecs.berkeley.edu>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Conor Dooley" <conor.dooley@microchip.com>,
	"Clément Léger" <cleger@rivosinc.com>,
	linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
	linux-doc@vger.kernel.org
Subject: Re: [PATCH v3 2/2] documentation: Document PR_RISCV_SET_ICACHE_FLUSH_CTX prctl
Date: Fri, 5 Jan 2024 19:52:55 -0800	[thread overview]
Message-ID: <ZZjOl1zDhUYbzpF9@ghost> (raw)
In-Reply-To: <CAOnJCULhAMmz22bH6A5AXv7aaJpH8SVGBATQyx-bfKAn4eFxsQ@mail.gmail.com>

On Fri, Jan 05, 2024 at 06:52:12PM -0800, Atish Patra wrote:
> On Wed, Dec 13, 2023 at 2:48 PM Charlie Jenkins <charlie@rivosinc.com> wrote:
> >
> > Provide documentation that explains how to properly do CMODX in riscv.
> >
> > Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
> > ---
> >  Documentation/arch/riscv/cmodx.rst | 98 ++++++++++++++++++++++++++++++++++++++
> >  Documentation/arch/riscv/index.rst |  1 +
> >  2 files changed, 99 insertions(+)
> >
> > diff --git a/Documentation/arch/riscv/cmodx.rst b/Documentation/arch/riscv/cmodx.rst
> > new file mode 100644
> > index 000000000000..20f327d85116
> > --- /dev/null
> > +++ b/Documentation/arch/riscv/cmodx.rst
> > @@ -0,0 +1,98 @@
> > +.. SPDX-License-Identifier: GPL-2.0
> > +
> > +==============================================================================
> > +Concurrent Modification and Execution of Instructions (CMODX) for RISC-V Linux
> > +==============================================================================
> > +
> > +CMODX is a programming technique where a program executes instructions that were
> > +modified by the program itself. Instruction storage and the instruction cache
> > +(icache) is not guaranteed to be synchronized on RISC-V hardware. Therefore, the
> > +program must enforce its own synchonization with the unprivileged fence.i/
> 
> /s/synchonization/synchronization
> 
> > +instruction.
> > +
> > +However, the default Linux ABI prohibits the use of fence.i in userspace
> > +applications. At any point the scheduler may migrate a task onto a new hart. If
> > +migration occurs after the userspace synchronized the icache and instruction
> > +storage with fence.i, the icache will no longer be clean. This is due to the
> > +behavior of fence.i only affecting the hart that it is called on. Thus, the hart
> > +that the task has been migrated to, may not have synchronized instruction
> > +storage and icache.
> > +
> > +There are two ways to solve this problem: use the riscv_flush_icache() syscall,
> > +or use the ``PR_RISCV_SET_ICACHE_FLUSH_CTX`` prctl(). The syscall should be used
> > +when the application very rarely needs to flush the icache. If the icache will
> 
> The syscall is a one time operation while prctl is sticky.
> It would be great if we can add a little more context why the syscall
> behaves this way compared to prctl.

I can highlight the point that the prctl is sticky and the syscall is
not.

As for "why", they simply fill different roles. It is useful to have
both a sticky and a non-sticky option. I chose the sticky operation to
be a prctl rather than a generic syscall because the semantics of prctl
is that they operate on process or thread scoped behavior which is what
was needed.

- Charlie

> 
> > +need to be flushed many times in the lifetime of the application, the prctl
> > +should be used.
> > +
> > +The prctl informs the kernel that it must emit synchronizing instructions upon
> > +task migration. The program itself must emit synchonizing instructions when
> 
> /s/synchonizing/synchronizing
> 
> > +necessary as well.
> > +
> > +1.  prctl() Interface
> > +---------------------
> > +
> > +Before the program emits their first icache flushing instruction, the program
> > +must call this prctl().
> > +
> > +* prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX, unsigned long ctx, unsigned long per_thread)
> > +
> > +       Sets the icache flushing context. If per_thread is 0, context will be
> > +       applied per process, otherwise if per_thread is 1 context will be
> > +       per-thread. Any other number will have undefined behavior.
> > +
> > +       * :c:macro:`PR_RISCV_CTX_SW_FENCEI`: Allow fence.i to be called in
> > +         userspace.
> > +
> > +Example usage:
> > +
> > +The following files are meant to be compiled and linked with each other. The
> > +modify_instruction() function replaces an add with 0 with an add with one,
> > +causing the instruction sequence in get_value() to change from returning a zero
> > +to returning a one.
> > +
> > +cmodx.c::
> > +
> > +       #include <stdio.h>
> > +       #include <sys/prctl.h>
> > +
> > +       extern int get_value();
> > +       extern void modify_instruction();
> > +
> > +       int main()
> > +       {
> > +               int value = get_value();
> > +               printf("Value before cmodx: %d\n", value);
> > +
> > +               // Call prctl before first fence.i is called inside modify_instruction
> > +               prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX, PR_RISCV_CTX_SW_FENCEI, 0);
> > +               modify_instruction();
> > +
> > +               value = get_value();
> > +               printf("Value after cmodx: %d\n", value);
> > +               return 0;
> > +       }
> > +
> > +cmodx.S::
> > +
> > +       .option norvc
> > +
> > +       .text
> > +       .global modify_instruction
> > +       modify_instruction:
> > +       lw a0, new_insn
> > +       lui a5,%hi(old_insn)
> > +       sw  a0,%lo(old_insn)(a5)
> > +       fence.i
> > +       ret
> > +
> > +       .section modifiable, "awx"
> > +       .global get_value
> > +       get_value:
> > +       li a0, 0
> > +       old_insn:
> > +       addi a0, a0, 0
> > +       ret
> > +
> > +       .data
> > +       new_insn:
> > +       addi a0, a0, 1
> > diff --git a/Documentation/arch/riscv/index.rst b/Documentation/arch/riscv/index.rst
> > index 4dab0cb4b900..eecf347ce849 100644
> > --- a/Documentation/arch/riscv/index.rst
> > +++ b/Documentation/arch/riscv/index.rst
> > @@ -13,6 +13,7 @@ RISC-V architecture
> >      patch-acceptance
> >      uabi
> >      vector
> > +    cmodx
> >
> >      features
> >
> >
> > --
> > 2.43.0
> >
> >
> > _______________________________________________
> > linux-riscv mailing list
> > linux-riscv@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-riscv
> 
> 
> 
> -- 
> Regards,
> Atish

WARNING: multiple messages have this Message-ID (diff)
From: Charlie Jenkins <charlie@rivosinc.com>
To: Atish Patra <atishp@atishpatra.org>
Cc: "Paul Walmsley" <paul.walmsley@sifive.com>,
	"Palmer Dabbelt" <palmer@dabbelt.com>,
	"Albert Ou" <aou@eecs.berkeley.edu>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Conor Dooley" <conor.dooley@microchip.com>,
	"Clément Léger" <cleger@rivosinc.com>,
	linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
	linux-doc@vger.kernel.org
Subject: Re: [PATCH v3 2/2] documentation: Document PR_RISCV_SET_ICACHE_FLUSH_CTX prctl
Date: Fri, 5 Jan 2024 19:52:55 -0800	[thread overview]
Message-ID: <ZZjOl1zDhUYbzpF9@ghost> (raw)
In-Reply-To: <CAOnJCULhAMmz22bH6A5AXv7aaJpH8SVGBATQyx-bfKAn4eFxsQ@mail.gmail.com>

On Fri, Jan 05, 2024 at 06:52:12PM -0800, Atish Patra wrote:
> On Wed, Dec 13, 2023 at 2:48 PM Charlie Jenkins <charlie@rivosinc.com> wrote:
> >
> > Provide documentation that explains how to properly do CMODX in riscv.
> >
> > Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
> > ---
> >  Documentation/arch/riscv/cmodx.rst | 98 ++++++++++++++++++++++++++++++++++++++
> >  Documentation/arch/riscv/index.rst |  1 +
> >  2 files changed, 99 insertions(+)
> >
> > diff --git a/Documentation/arch/riscv/cmodx.rst b/Documentation/arch/riscv/cmodx.rst
> > new file mode 100644
> > index 000000000000..20f327d85116
> > --- /dev/null
> > +++ b/Documentation/arch/riscv/cmodx.rst
> > @@ -0,0 +1,98 @@
> > +.. SPDX-License-Identifier: GPL-2.0
> > +
> > +==============================================================================
> > +Concurrent Modification and Execution of Instructions (CMODX) for RISC-V Linux
> > +==============================================================================
> > +
> > +CMODX is a programming technique where a program executes instructions that were
> > +modified by the program itself. Instruction storage and the instruction cache
> > +(icache) is not guaranteed to be synchronized on RISC-V hardware. Therefore, the
> > +program must enforce its own synchonization with the unprivileged fence.i/
> 
> /s/synchonization/synchronization
> 
> > +instruction.
> > +
> > +However, the default Linux ABI prohibits the use of fence.i in userspace
> > +applications. At any point the scheduler may migrate a task onto a new hart. If
> > +migration occurs after the userspace synchronized the icache and instruction
> > +storage with fence.i, the icache will no longer be clean. This is due to the
> > +behavior of fence.i only affecting the hart that it is called on. Thus, the hart
> > +that the task has been migrated to, may not have synchronized instruction
> > +storage and icache.
> > +
> > +There are two ways to solve this problem: use the riscv_flush_icache() syscall,
> > +or use the ``PR_RISCV_SET_ICACHE_FLUSH_CTX`` prctl(). The syscall should be used
> > +when the application very rarely needs to flush the icache. If the icache will
> 
> The syscall is a one time operation while prctl is sticky.
> It would be great if we can add a little more context why the syscall
> behaves this way compared to prctl.

I can highlight the point that the prctl is sticky and the syscall is
not.

As for "why", they simply fill different roles. It is useful to have
both a sticky and a non-sticky option. I chose the sticky operation to
be a prctl rather than a generic syscall because the semantics of prctl
is that they operate on process or thread scoped behavior which is what
was needed.

- Charlie

> 
> > +need to be flushed many times in the lifetime of the application, the prctl
> > +should be used.
> > +
> > +The prctl informs the kernel that it must emit synchronizing instructions upon
> > +task migration. The program itself must emit synchonizing instructions when
> 
> /s/synchonizing/synchronizing
> 
> > +necessary as well.
> > +
> > +1.  prctl() Interface
> > +---------------------
> > +
> > +Before the program emits their first icache flushing instruction, the program
> > +must call this prctl().
> > +
> > +* prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX, unsigned long ctx, unsigned long per_thread)
> > +
> > +       Sets the icache flushing context. If per_thread is 0, context will be
> > +       applied per process, otherwise if per_thread is 1 context will be
> > +       per-thread. Any other number will have undefined behavior.
> > +
> > +       * :c:macro:`PR_RISCV_CTX_SW_FENCEI`: Allow fence.i to be called in
> > +         userspace.
> > +
> > +Example usage:
> > +
> > +The following files are meant to be compiled and linked with each other. The
> > +modify_instruction() function replaces an add with 0 with an add with one,
> > +causing the instruction sequence in get_value() to change from returning a zero
> > +to returning a one.
> > +
> > +cmodx.c::
> > +
> > +       #include <stdio.h>
> > +       #include <sys/prctl.h>
> > +
> > +       extern int get_value();
> > +       extern void modify_instruction();
> > +
> > +       int main()
> > +       {
> > +               int value = get_value();
> > +               printf("Value before cmodx: %d\n", value);
> > +
> > +               // Call prctl before first fence.i is called inside modify_instruction
> > +               prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX, PR_RISCV_CTX_SW_FENCEI, 0);
> > +               modify_instruction();
> > +
> > +               value = get_value();
> > +               printf("Value after cmodx: %d\n", value);
> > +               return 0;
> > +       }
> > +
> > +cmodx.S::
> > +
> > +       .option norvc
> > +
> > +       .text
> > +       .global modify_instruction
> > +       modify_instruction:
> > +       lw a0, new_insn
> > +       lui a5,%hi(old_insn)
> > +       sw  a0,%lo(old_insn)(a5)
> > +       fence.i
> > +       ret
> > +
> > +       .section modifiable, "awx"
> > +       .global get_value
> > +       get_value:
> > +       li a0, 0
> > +       old_insn:
> > +       addi a0, a0, 0
> > +       ret
> > +
> > +       .data
> > +       new_insn:
> > +       addi a0, a0, 1
> > diff --git a/Documentation/arch/riscv/index.rst b/Documentation/arch/riscv/index.rst
> > index 4dab0cb4b900..eecf347ce849 100644
> > --- a/Documentation/arch/riscv/index.rst
> > +++ b/Documentation/arch/riscv/index.rst
> > @@ -13,6 +13,7 @@ RISC-V architecture
> >      patch-acceptance
> >      uabi
> >      vector
> > +    cmodx
> >
> >      features
> >
> >
> > --
> > 2.43.0
> >
> >
> > _______________________________________________
> > linux-riscv mailing list
> > linux-riscv@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-riscv
> 
> 
> 
> -- 
> Regards,
> Atish

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

  reply	other threads:[~2024-01-06  3:52 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-13 22:47 [PATCH v3 0/2] riscv: Create and document PR_RISCV_SET_ICACHE_FLUSH_CTX prctl Charlie Jenkins
2023-12-13 22:47 ` Charlie Jenkins
2023-12-13 22:47 ` [PATCH v3 1/2] riscv: Include riscv_set_icache_flush_ctx prctl Charlie Jenkins
2023-12-13 22:47   ` Charlie Jenkins
2024-01-06  2:55   ` Atish Patra
2024-01-06  2:55     ` Atish Patra
2024-01-06  3:36     ` Charlie Jenkins
2024-01-06  3:36       ` Charlie Jenkins
2023-12-13 22:47 ` [PATCH v3 2/2] documentation: Document PR_RISCV_SET_ICACHE_FLUSH_CTX prctl Charlie Jenkins
2023-12-13 22:47   ` Charlie Jenkins
2024-01-06  2:52   ` Atish Patra
2024-01-06  2:52     ` Atish Patra
2024-01-06  3:52     ` Charlie Jenkins [this message]
2024-01-06  3:52       ` Charlie Jenkins
2024-01-06  5:07       ` Atish Patra
2024-01-06  5:07         ` Atish Patra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZZjOl1zDhUYbzpF9@ghost \
    --to=charlie@rivosinc.com \
    --cc=aou@eecs.berkeley.edu \
    --cc=atishp@atishpatra.org \
    --cc=cleger@rivosinc.com \
    --cc=conor.dooley@microchip.com \
    --cc=corbet@lwn.net \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=palmer@dabbelt.com \
    --cc=paul.walmsley@sifive.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.