Skip to content

Commit d8ac85d

Browse files
AndybnACTpalmer-dabbelt
authored andcommitted
riscv: Documentation: add a description about dynamic ftrace
Add a section in cmodx to describe how dynamic ftrace works on riscv, limitations, and assumptions. Signed-off-by: Andy Chiu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Ghiti <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent b21cdb9 commit d8ac85d

File tree

1 file changed

+39
-7
lines changed

1 file changed

+39
-7
lines changed

Documentation/arch/riscv/cmodx.rst

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,45 @@ modified by the program itself. Instruction storage and the instruction cache
1010
program must enforce its own synchronization with the unprivileged fence.i
1111
instruction.
1212

13-
However, the default Linux ABI prohibits the use of fence.i in userspace
14-
applications. At any point the scheduler may migrate a task onto a new hart. If
15-
migration occurs after the userspace synchronized the icache and instruction
16-
storage with fence.i, the icache on the new hart will no longer be clean. This
17-
is due to the behavior of fence.i only affecting the hart that it is called on.
18-
Thus, the hart that the task has been migrated to may not have synchronized
19-
instruction storage and icache.
13+
CMODX in the Kernel Space
14+
---------------------
15+
16+
Dynamic ftrace
17+
---------------------
18+
19+
Essentially, dynamic ftrace directs the control flow by inserting a function
20+
call at each patchable function entry, and patches it dynamically at runtime to
21+
enable or disable the redirection. In the case of RISC-V, 2 instructions,
22+
AUIPC + JALR, are required to compose a function call. However, it is impossible
23+
to patch 2 instructions and expect that a concurrent read-side executes them
24+
without a race condition. This series makes atmoic code patching possible in
25+
RISC-V ftrace. Kernel preemption makes things even worse as it allows the old
26+
state to persist across the patching process with stop_machine().
27+
28+
In order to get rid of stop_machine() and run dynamic ftrace with full kernel
29+
preemption, we partially initialize each patchable function entry at boot-time,
30+
setting the first instruction to AUIPC, and the second to NOP. Now, atmoic
31+
patching is possible because the kernel only has to update one instruction.
32+
According to Ziccif, as long as an instruction is naturally aligned, the ISA
33+
guarantee an atomic update.
34+
35+
By fixing down the first instruction, AUIPC, the range of the ftrace trampoline
36+
is limited to +-2K from the predetermined target, ftrace_caller, due to the lack
37+
of immediate encoding space in RISC-V. To address the issue, we introduce
38+
CALL_OPS, where an 8B naturally align metadata is added in front of each
39+
pacthable function. The metadata is resolved at the first trampoline, then the
40+
execution can be derect to another custom trampoline.
41+
42+
CMODX in the User Space
43+
---------------------
44+
45+
Though fence.i is an unprivileged instruction, the default Linux ABI prohibits
46+
the use of fence.i in userspace applications. At any point the scheduler may
47+
migrate a task onto a new hart. If migration occurs after the userspace
48+
synchronized the icache and instruction storage with fence.i, the icache on the
49+
new hart will no longer be clean. This is due to the behavior of fence.i only
50+
affecting the hart that it is called on. Thus, the hart that the task has been
51+
migrated to may not have synchronized instruction storage and icache.
2052

2153
There are two ways to solve this problem: use the riscv_flush_icache() syscall,
2254
or use the ``PR_RISCV_SET_ICACHE_FLUSH_CTX`` prctl() and emit fence.i in

0 commit comments

Comments
 (0)