Skip to contentSkip to conversation

riscv, bpf: fix reads of thread_info.cpu

PATCH Applied Radim Krčmář 5 participants 10 messages Aug 12, 2025 – Sep 17, 2025

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover riscv, bpf: fix reads of thread_info.cpu

Hello,

These patches are related to a recently queued series [1] that fixes the same bugs in normal code. That series finishes with a patch that would have exposed the BPF bugs, but luckily it won't get merged until v6.18.

I don't know enough about BPF to verify that it emits the correct code now, so any pointers are welcome.

1: https://lore.kernel.org/linux-riscv/[email protected]/

Radim Krčmář (2):
riscv, bpf: use lw when reading int cpu in BPF_MOV64_PERCPU_REG riscv, bpf: use lw when reading int cpu in bpf_get_smp_processor_id

 arch/riscv/net/bpf_jit_comp64.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
Signature · 1 line
2.50.0
#1 lore raw

PATCH 1/2 riscv, bpf: use lw when reading int cpu in BPF_MOV64_PERCPU_REG

emit_ld is wrong, because thread_info.cpu is 32-bit, not xlen-bit wide. The struct currently has a hole after cpu, so little endian accesses seemed fine.

Fixes 19c56d4e5be1 ("riscv, bpf: add internal-only MOV instruction to resolve per-CPU addrs")
---
 arch/riscv/net/bpf_jit_comp64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/net/bpf_jit_comp64.c +1 -1
index 10e01ff06312..6e1554d89681 100644
@@ -1356,7 +1356,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 				emit_mv(rd, rs, ctx);
 #ifdef CONFIG_SMP
 			/* Load current CPU number in T1 */
-			emit_ld(RV_REG_T1, offsetof(struct thread_info, cpu),
+			emit_lw(RV_REG_T1, offsetof(struct thread_info, cpu),
 				RV_REG_TP, ctx);
 			/* Load address of __per_cpu_offset array in T2 */
 			emit_addr(RV_REG_T2, (u64)&__per_cpu_offset, extra_pass, ctx);
Signature · 1 line
2.50.0
maintainer Reviewed-by on v1 1/2
#2 lore raw

Re: [PATCH 1/2] riscv, bpf: use lw when reading int cpu in BPF_MOV64_PERCPU_REG

Quoted 16 lines · Radim Krčmář

emit_ld is wrong, because thread_info.cpu is 32-bit, not xlen-bit wide. The struct currently has a hole after cpu, so little endian accesses seemed fine.

Fixes 19c56d4e5be1 ("riscv, bpf: add internal-only MOV instruction to resolve per-CPU addrs")
---
  arch/riscv/net/bpf_jit_comp64.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/net/bpf_jit_comp64.c +0 -0
index 10e01ff06312..6e1554d89681 100644

arch/riscv/net/bpf_jit_comp64.c int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx, · line 1362

Quoted 8 lines
arch/riscv/net/bpf_jit_comp64.c +1 -1
@@ -1356,7 +1356,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
  				emit_mv(rd, rs, ctx);
  #ifdef CONFIG_SMP
  			/* Load current CPU number in T1 */
-			emit_ld(RV_REG_T1, offsetof(struct thread_info, cpu),
+			emit_lw(RV_REG_T1, offsetof(struct thread_info, cpu),
  				RV_REG_TP, ctx);
  			/* Load address of __per_cpu_offset array in T2 */
  			emit_addr(RV_REG_T2, (u64)&__per_cpu_offset, extra_pass, ctx);
#3 lore raw

PATCH 2/2 riscv, bpf: use lw when reading int cpu in bpf_get_smp_processor_id

In reply to Radim Krčmář

emit_ld is wrong, because thread_info.cpu is 32-bit, not xlen-bit wide. The struct currently has a hole after cpu, so little endian accesses seemed fine.

Fixes 2ddec2c80b44 ("riscv, bpf: inline bpf_get_smp_processor_id()")
---
 arch/riscv/net/bpf_jit_comp64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/net/bpf_jit_comp64.c +1 -1
index 6e1554d89681..9883a55d61b5 100644
@@ -1763,7 +1763,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 		 */
 		if (insn->src_reg == 0 && insn->imm == BPF_FUNC_get_smp_processor_id) {
 			/* Load current CPU number in R0 */
-			emit_ld(bpf_to_rv_reg(BPF_REG_0, ctx), offsetof(struct thread_info, cpu),
+			emit_lw(bpf_to_rv_reg(BPF_REG_0, ctx), offsetof(struct thread_info, cpu),
 				RV_REG_TP, ctx);
 			break;
 		}
Signature · 1 line
2.50.0
maintainer Reviewed-by on v1 2/2
#4 lore raw

Re: [PATCH 2/2] riscv, bpf: use lw when reading int cpu in bpf_get_smp_processor_id

Quoted 16 lines · Radim Krčmář

emit_ld is wrong, because thread_info.cpu is 32-bit, not xlen-bit wide. The struct currently has a hole after cpu, so little endian accesses seemed fine.

Fixes 2ddec2c80b44 ("riscv, bpf: inline bpf_get_smp_processor_id()")
---
  arch/riscv/net/bpf_jit_comp64.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/net/bpf_jit_comp64.c +0 -0
index 6e1554d89681..9883a55d61b5 100644

arch/riscv/net/bpf_jit_comp64.c int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx, · line 1769

Quoted 8 lines
arch/riscv/net/bpf_jit_comp64.c +1 -1
@@ -1763,7 +1763,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
  		 */
  		if (insn->src_reg == 0 && insn->imm == BPF_FUNC_get_smp_processor_id) {
  			/* Load current CPU number in R0 */
-			emit_ld(bpf_to_rv_reg(BPF_REG_0, ctx), offsetof(struct thread_info, cpu),
+			emit_lw(bpf_to_rv_reg(BPF_REG_0, ctx), offsetof(struct thread_info, cpu),
  				RV_REG_TP, ctx);
  			break;
  		}
reviewer Reviewed-by on the v1 series
#5 lore raw
In reply to Radim Krčmář

Hi Radim,

Quoted 9 lines · Radim Krčmář

Hello,

These patches are related to a recently queued series [1] that fixes the same bugs in normal code. That series finishes with a patch that would have exposed the BPF bugs, but luckily it won't get merged until v6.18.

I don't know enough about BPF to verify that it emits the correct code now, so any pointers are welcome.

Quoted 9 lines

1: https://lore.kernel.org/linux-riscv/[email protected]/

Radim Krčmář (2):
riscv, bpf: use lw when reading int cpu in BPF_MOV64_PERCPU_REG riscv, bpf: use lw when reading int cpu in bpf_get_smp_processor_id

  arch/riscv/net/bpf_jit_comp64.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

Both patches look good so:

Since this only touches riscv and I have a bunch of fixes pending, I propose to take those patches through the riscv tree, I'll just wait for Björn to confirm it is correct.

@Radim: This is the third similar bug, did you check all assembly code (and bpf) to make sure we don't have anymore left or should I?

Thanks,

Alex

#6 lore raw
2025-08-12T13:37:16+02:00, Alexandre Ghiti <[email protected]>:
Quoted 2 lines

@Radim: This is the third similar bug, did you check all assembly code (and bpf) to make sure we don't have anymore left or should I?

I looked at load/store instructions, including bpf, and focussed on patterns where we access non-xlen sized data through an offset.

(Nothing else popped up, but I mostly used grep and cscope as I don't
know of any semantic tool, so my confidence levels are low.)

#7 lore raw

Hi Radim,

Quoted 8 lines · Radim Krčmář
2025-08-12T13:37:16+02:00, Alexandre Ghiti <[email protected]>:
Quoted 2 lines

@Radim: This is the third similar bug, did you check all assembly code (and bpf) to make sure we don't have anymore left or should I?

I looked at load/store instructions, including bpf, and focussed on patterns where we access non-xlen sized data through an offset.

(Nothing else popped up, but I mostly used grep and cscope as I don't
know of any semantic tool, so my confidence levels are low.)

Ok thanks, I don't have any better idea than eye scrubbing so I'll take another look to improve our confidence. One good thing is that now I don't let them pass in reviews :)

Thanks for noticing this class of bugs!

Alex

Quoted 5 lines

_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv

maintainer Acked-by Tested-by on the v1 series
#8 lore raw
In reply to Radim Krčmář

Radim!

Quoted 10 lines · Radim Krčmář

Hello,

These patches are related to a recently queued series [1] that fixes the same bugs in normal code. That series finishes with a patch that would have exposed the BPF bugs, but luckily it won't get merged until v6.18.

I don't know enough about BPF to verify that it emits the correct code now, so any pointers are welcome.

1: https://lore.kernel.org/linux-riscv/[email protected]/

Apologies for the slow review!

For the series:

#9 lore raw
In reply to Radim Krčmář
This series was applied to riscv/linux.git (for-next) by Paul Walmsley <[email protected]>:

Hello:

This series was applied to riscv/linux.git (for-next) by Paul Walmsley <[email protected]>:

Quoted 10 lines · On Tue, 12 Aug 2025 11:02:54 +0200 you wrote:

Hello,

These patches are related to a recently queued series [1] that fixes the same bugs in normal code. That series finishes with a patch that would have exposed the BPF bugs, but luckily it won't get merged until v6.18.

I don't know enough about BPF to verify that it emits the correct code now, so any pointers are welcome.

[...]

Here is the summary with links:
- [1/2] riscv, bpf: use lw when reading int cpu in BPF_MOV64_PERCPU_REG

    https://git.kernel.org/riscv/c/ad5348c76591
  - [2/2] riscv, bpf: use lw when reading int cpu in bpf_get_smp_processor_id
    https://git.kernel.org/riscv/c/8a16586fa7b8

You are awesome, thank you!

Signature · 2 lines
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html