Skip to content

Commit 9ddfc3c

Browse files
AndybnACTpalmer-dabbelt
authored andcommitted
riscv: jump_label: Fixup unaligned arch_static_branch function
Runtime code patching must be done at a naturally aligned address, or we may execute on a partial instruction. We have encountered problems traced back to static jump functions during the test. We switched the tracer randomly for every 1~5 seconds on a dual-core QEMU setup and found the kernel sucking at a static branch where it jumps to itself. The reason is that the static branch was 2-byte but not 4-byte aligned. Then, the kernel would patch the instruction, either J or NOP, with two half-word stores if the machine does not have efficient unaligned accesses. Thus, moments exist where half of the NOP mixes with the other half of the J when transitioning the branch. In our particular case, on a little-endian machine, the upper half of the NOP was mixed with the lower part of the J when enabling the branch, resulting in a jump that jumped to itself. Conversely, it would result in a HINT instruction when disabling the branch, but it might not be observable. ARM64 does not have this problem since all instructions must be 4-byte aligned. Fixes: ebc00dd ("riscv: Add jump-label implementation") Link: https://lore.kernel.org/linux-riscv/[email protected]/ Reviewed-by: Greentime Hu <[email protected]> Signed-off-by: Andy Chiu <[email protected]> Signed-off-by: Guo Ren <[email protected]> Link: https://lore.kernel.org/r/[email protected] Cc: [email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 2350bd1 commit 9ddfc3c

File tree

1 file changed

+2
-0
lines changed

1 file changed

+2
-0
lines changed

arch/riscv/include/asm/jump_label.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ static __always_inline bool arch_static_branch(struct static_key * const key,
1818
const bool branch)
1919
{
2020
asm_volatile_goto(
21+
" .align 2 \n\t"
2122
" .option push \n\t"
2223
" .option norelax \n\t"
2324
" .option norvc \n\t"
@@ -39,6 +40,7 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke
3940
const bool branch)
4041
{
4142
asm_volatile_goto(
43+
" .align 2 \n\t"
4244
" .option push \n\t"
4345
" .option norelax \n\t"
4446
" .option norvc \n\t"

0 commit comments

Comments
 (0)