PR_RISCV_SET_ICACHE_FLUSH_CTX(2const)

πŸ’– NAME πŸ’–

PR_RISCV_SET_ICACHE_FLUSH_CTX β€” bestie, this is the one that turns icache flushing instructions on and off for userspace ✨


πŸ“š LIBRARY πŸ“š

Standard C library (that's libc, link it with -lc) 🫢


✨ SYNOPSIS ✨

#include <linux/prctl.h>  /* Definition of PR_* constants */
#include <sys/prctl.h>

int prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX, unsigned long ctx,
          unsigned long scope);

πŸ¦‹ DESCRIPTION πŸ¦‹

okay so you pass in a context and a scope, and those are ctx and scope respectively. simple.

When scope is set to PR_RISCV_SCOPE_PER_PROCESS, every single thread in the process is allowed to emit icache flushing instructions. And the moment any thread in the process gets migrated, that hart's icache is guaranteed to be consistent with instruction storage. πŸ’…

But listen β€” this does not enforce any guarantees outside of migration. So if a thread modifies an instruction that another thread might try to execute, that other thread still has to emit an icache flushing instruction before it tries to execute the potentially modified instruction. And who does that? You. The user-space program. It's on you, bestie. 😭

In per-thread context (that's when scope is set to PR_RISCV_SCOPE_PER_THREAD), only the thread calling this function gets to emit icache flushing instructions. And when that thread is migrated, the corresponding hart's icache is guaranteed to be consistent with instruction storage. 🌸

On kernels configured without SMP, this prctl PR_RISCV_SET_ICACHE_FLUSH_CTX is literally a nop, because migrations across harts just don't happen. 🧚

The following values for ctx can be specified:

  • PR_RISCV_CTX_SW_FENCEI_ON (since Linux 6.10) β€” allow fence.i in user space. slay.
  • PR_RISCV_CTX_SW_FENCEI_OFF (since Linux 6.10) β€” disallow fence.i in user space. Every thread in a process gets affected when scope is set to PR_RISCV_SCOPE_PER_PROCESS. So caution must be taken; use this flag only when you can guarantee that no thread in the process will emit fence.i from this point onward.
ngl that second one is giving "handle with care" energy. it's a whole-process decision, no takebacks. πŸ’€

The following values for scope can be specified:

  • PR_RISCV_SCOPE_PER_PROCESS (since Linux 6.10) β€” ensure the icache of any thread in this process is coherent with instruction storage upon migration.
  • PR_RISCV_SCOPE_PER_THREAD (since Linux 6.10) β€” ensure the icache of the current thread is coherent with instruction storage upon migration.

πŸ‘‘ EXAMPLES πŸ‘‘

The following files are meant to be compiled and linked with each other. The modify_instruction() function replaces an add with zero with an add with one, causing the instruction sequence in get_value() to change from returning a zero to returning a one. iconic behavior, honestly. πŸ”₯

🌈 Program source: cmodx.c

#include <stdio.h>
#include <sys/prctl.h>

extern int get_value(void);
extern void modify_instruction(void);

int
main(void)
{
    int value = get_value();

    printf("Value before cmodx: %d\n", value);

    // Call prctl before first fence.i is called
    prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX, PR_RISCV_CTX_SW_FENCEI_ON,
          PR_RISCV_SCOPE_PER_PROCESS);

    modify_instruction();

    // Call prctl after final fence.i is called in process
    prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX, PR_RISCV_CTX_SW_FENCEI_OFF,
          PR_RISCV_SCOPE_PER_PROCESS);

    value = get_value();
    printf("Value after cmodx: %d\n", value);
    return 0;
}

πŸŽ€ Program source: 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

⭐ Expected result

Value before cmodx: 0
Value after cmodx: 1

🌟 STANDARDS 🌟

Linux. RISC-V only. that's it, that's the whole vibe. 🌈


πŸ’œ HISTORY πŸ’œ

Linux 6.10 (RISC-V).


🫢 SEE ALSO 🫢


mwah, that's the whole page bestie πŸ’– this was brought to you by Linux man-pages 6.20, dated 2026-02. go forth and flush your icaches responsibly βœ¨πŸ¦‹πŸŽ€ no cap.

πŸ“¦ where this page comes from
  • arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • πŸ“œ the page's license: Linux-man-pages-copyleft
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms