public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC
@ 2025-12-28 17:37 Lukas Gerlach
  2026-01-05 23:28 ` Paul Walmsley
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Lukas Gerlach @ 2025-12-28 17:37 UTC (permalink / raw)
  To: bpf, linux-riscv
  Cc: bjorn, ast, daniel, luke.r.nels, xi.wang, palmer, luis.gerhorst,
	daniel.weber, marton.bognar, jo.vanbulck, michael.schwarz,
	Lukas Gerlach

The BPF verifier inserts BPF_NOSPEC instructions to create speculation
barriers. However, the RISC-V BPF JIT emits nothing for this
instruction, leaving programs vulnerable to speculative execution
attacks.

Originally, BPF_NOSPEC was used only for Spectre v4 mitigation, programs
containing potential Spectre v1 gadgets were rejected by the verifier.
With the VeriFence changes, the verifier now accepts these
programs and inserts BPF_NOSPEC barriers for Spectre v1 mitigation as
well. On RISC-V, this means programs that were previously rejected are
now accepted but left unprotected against both v1 and v4 attacks.

RISC-V lacks a dedicated speculation barrier instruction.
This patch uses the fence.i instruction as a stopgap solution.
However an alternative and safer approach would be to reject vulnerable bpf
programs again.

Fixes: f5e81d111750 ("bpf: Introduce BPF nospec instruction for mitigating Spectre v4")
Fixes: 5fcf896efe28 ("Merge branch 'bpf-mitigate-spectre-v1-using-barriers'")
Signed-off-by: Lukas Gerlach <lukas.gerlach@cispa.de>
---
 arch/riscv/net/bpf_jit.h        | 10 ++++++++++
 arch/riscv/net/bpf_jit_comp32.c |  6 +++++-
 arch/riscv/net/bpf_jit_comp64.c |  6 +++++-
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h
index 632ced07bca4..e70b3bc19206 100644
--- a/arch/riscv/net/bpf_jit.h
+++ b/arch/riscv/net/bpf_jit.h
@@ -619,6 +619,16 @@ static inline void emit_fence_rw_rw(struct rv_jit_context *ctx)
 	emit(rv_fence(0x3, 0x3), ctx);
 }
 
+static inline u32 rv_fence_i(void)
+{
+	return rv_i_insn(0, 0, 1, 0, 0x0f);
+}
+
+static inline void emit_fence_i(struct rv_jit_context *ctx)
+{
+	emit(rv_fence_i(), ctx);
+}
+
 static inline u32 rv_nop(void)
 {
 	return rv_i_insn(0, 0, 0, 0, 0x13);
diff --git a/arch/riscv/net/bpf_jit_comp32.c b/arch/riscv/net/bpf_jit_comp32.c
index 592dd86fbf81..d9a6f55a7e8e 100644
--- a/arch/riscv/net/bpf_jit_comp32.c
+++ b/arch/riscv/net/bpf_jit_comp32.c
@@ -1248,8 +1248,12 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 			return -1;
 		break;
 
-	/* speculation barrier */
+	/*
+	 * Speculation barrier using fence.i for pipeline serialization.
+	 * RISC-V lacks a dedicated speculation barrier instruction.
+	 */
 	case BPF_ST | BPF_NOSPEC:
+		emit_fence_i(ctx);
 		break;
 
 	case BPF_ST | BPF_MEM | BPF_B:
diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
index 45cbc7c6fe49..fabafbebde0c 100644
--- a/arch/riscv/net/bpf_jit_comp64.c
+++ b/arch/riscv/net/bpf_jit_comp64.c
@@ -1864,8 +1864,12 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 		break;
 	}
 
-	/* speculation barrier */
+	/*
+	 * Speculation barrier using fence.i for pipeline serialization.
+	 * RISC-V lacks a dedicated speculation barrier instruction.
+	 */
 	case BPF_ST | BPF_NOSPEC:
+		emit_fence_i(ctx);
 		break;
 
 	/* ST: *(size *)(dst + off) = imm */
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC
  2025-12-28 17:37 [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC Lukas Gerlach
@ 2026-01-05 23:28 ` Paul Walmsley
  2026-01-06  8:44   ` [PATCH] riscv, bpf: add a speculation barrier " Lukas Gerlach
  2026-01-09  3:41 ` Bo Gan
  2026-01-12 18:33 ` Bo Gan
  2 siblings, 1 reply; 14+ messages in thread
From: Paul Walmsley @ 2026-01-05 23:28 UTC (permalink / raw)
  To: Lukas Gerlach
  Cc: bpf, linux-riscv, bjorn, ast, daniel, luke.r.nels, xi.wang,
	palmer, luis.gerhorst, daniel.weber, marton.bognar, jo.vanbulck,
	michael.schwarz

Hi Lukas, 

thanks for the patch,

On Sun, 28 Dec 2025, Lukas Gerlach wrote:

> The BPF verifier inserts BPF_NOSPEC instructions to create speculation
> barriers. However, the RISC-V BPF JIT emits nothing for this
> instruction, leaving programs vulnerable to speculative execution
> attacks.
> 
> Originally, BPF_NOSPEC was used only for Spectre v4 mitigation, programs
> containing potential Spectre v1 gadgets were rejected by the verifier.
> With the VeriFence changes, the verifier now accepts these
> programs and inserts BPF_NOSPEC barriers for Spectre v1 mitigation as
> well. On RISC-V, this means programs that were previously rejected are
> now accepted but left unprotected against both v1 and v4 attacks.
> 
> RISC-V lacks a dedicated speculation barrier instruction.
> This patch uses the fence.i instruction as a stopgap solution.
> However an alternative and safer approach would be to reject vulnerable bpf
> programs again.
> 
> Fixes: f5e81d111750 ("bpf: Introduce BPF nospec instruction for mitigating Spectre v4")
> Fixes: 5fcf896efe28 ("Merge branch 'bpf-mitigate-spectre-v1-using-barriers'")
> Signed-off-by: Lukas Gerlach <lukas.gerlach@cispa.de>

Have you been able to measure whether this change results in a performance 
regression on cores that might not need these barriers, for example, 
in-order cores with limited speculation?

Am thinking that we probably should make this conditional using code 
similar to arch/arm64/kernel/proton-pack.c - and avoiding the fence.i when 
cores that aren't likely to be susceptible are detected.

Thoughts?  


- Paul

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] riscv, bpf: add a speculation barrier for BPF_NOSPEC
  2026-01-05 23:28 ` Paul Walmsley
@ 2026-01-06  8:44   ` Lukas Gerlach
  2026-01-07  8:26     ` Luis Gerhorst
  0 siblings, 1 reply; 14+ messages in thread
From: Lukas Gerlach @ 2026-01-06  8:44 UTC (permalink / raw)
  To: pjw
  Cc: ast, bjorn, bpf, daniel.weber, daniel, jo.vanbulck, linux-riscv,
	luis.gerhorst, lukas.gerlach, luke.r.nels, marton.bognar,
	michael.schwarz, palmer, xi.wang

Hi Paul,

thanks for the feedback.

I have not benchmarked fence.i in the eBPF context specifically, but
from my other work on Spectre mitigations on RISC-V I can confirm that
fence.i flushes the instruction cache on all cores I have tested, both
in-order and out-of-order, so there is a performance impact.

I agree that making this conditional similar to ARM64's proton-pack.c
is the right approach. Getting this infrastructure in place is a good
idea regardless, as the RISC-V hardware landscape is very diverse, and
we will likely need conditional mitigation support for other Spectre
defenses as well.

Thanks,
Lukas

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] riscv, bpf: add a speculation barrier for BPF_NOSPEC
  2026-01-06  8:44   ` [PATCH] riscv, bpf: add a speculation barrier " Lukas Gerlach
@ 2026-01-07  8:26     ` Luis Gerhorst
  2026-01-07  9:54       ` [PATCH] riscv, bpf: Emit fence.i " Lukas Gerlach
  0 siblings, 1 reply; 14+ messages in thread
From: Luis Gerhorst @ 2026-01-07  8:26 UTC (permalink / raw)
  To: Lukas Gerlach
  Cc: pjw, ast, bjorn, bpf, daniel.weber, daniel, jo.vanbulck,
	linux-riscv, luke.r.nels, marton.bognar, michael.schwarz, palmer,
	xi.wang

Lukas Gerlach <lukas.gerlach@cispa.de> writes:

> I have not benchmarked fence.i in the eBPF context specifically, but
> from my other work on Spectre mitigations on RISC-V I can confirm that
> fence.i flushes the instruction cache on all cores I have tested, both
> in-order and out-of-order, so there is a performance impact.
>
> I agree that making this conditional similar to ARM64's proton-pack.c
> is the right approach. Getting this infrastructure in place is a good
> idea regardless, as the RISC-V hardware landscape is very diverse, and
> we will likely need conditional mitigation support for other Spectre
> defenses as well.

Thanks for the patch, I believe this approach makes sense.

For eBPF, you can make them conditional by implementing
bpf_jit_bypass_spec_v1/v4() similarly to how powerpc does it [1]. They
default to false for archs that do not implement them. Setting them will
not only avoid the performance bumb, but also speed up verification and
improve expressiveness (i.e., fewer programs are rejected for some edge
cases).

I am not familiar with RISC-V, but could the be any problem from fence.i
being an extension [2]? Or do all RISC-V CPUs supported by the kernel
implement this?

[1] https://lwn.net/ml/all/20250603211318.337474-1-luis.gerhorst@fau.de/
[2] https://docs.riscv.org/reference/isa/unpriv/zifencei.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC
  2026-01-07  8:26     ` Luis Gerhorst
@ 2026-01-07  9:54       ` Lukas Gerlach
  2026-01-07 17:52         ` Luis Gerhorst
  0 siblings, 1 reply; 14+ messages in thread
From: Lukas Gerlach @ 2026-01-07  9:54 UTC (permalink / raw)
  To: luis.gerhorst
  Cc: ast, bjorn, bpf, daniel.weber, daniel, jo.vanbulck, linux-riscv,
	lukas.gerlach, luke.r.nels, marton.bognar, michael.schwarz,
	palmer, pjw, xi.wang

Hi Luis,

thanks for the feedback and pointer to the powerpc implementation.

Regarding bpf_jit_bypass_spec_v1/v4(): currently this is per-architecture.
What we need is per-processor granularity, so we can disable mitigations
on in-order cores and keep them enabled on vulnerable out-of-order processors.

Regarding fence.i being an extension: all RISC-V processors supported by the
kernel that are vulnerable to these attacks support this instruction. Also,
if a dedicated speculation barrier becomes available in the future, it would
be easy to switch to that.

Thanks,
Lukas

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC
  2026-01-07  9:54       ` [PATCH] riscv, bpf: Emit fence.i " Lukas Gerlach
@ 2026-01-07 17:52         ` Luis Gerhorst
  2026-01-07 23:30           ` Samuel Holland
  0 siblings, 1 reply; 14+ messages in thread
From: Luis Gerhorst @ 2026-01-07 17:52 UTC (permalink / raw)
  To: Lukas Gerlach
  Cc: ast, bjorn, bpf, daniel.weber, daniel, jo.vanbulck, linux-riscv,
	luke.r.nels, marton.bognar, michael.schwarz, palmer, pjw, xi.wang,
	cleger, palmer, conor.dooley, andrew

Lukas Gerlach <lukas.gerlach@cispa.de> writes:

> Regarding bpf_jit_bypass_spec_v1/v4(): currently this is per-architecture.
> What we need is per-processor granularity, so we can disable mitigations
> on in-order cores and keep them enabled on vulnerable out-of-order processors.

Yes, sorry this was unclear. I just wanted to point out that once you
have that infrastructure you can implement them as follows:

bpf_jit_bypass_spec_v1/v4() {
  if (RV_CPU_IN_ORDER())
    return true;
  else
    return false;
}

But you are right that the definition of RV_CPU_IN_ORDER() is still
missing of course.

> Regarding fence.i being an extension: all RISC-V processors supported by the
> kernel that are vulnerable to these attacks support this instruction.

I am not sure if I misunderstand the "that are vulnerable to these
attacks".

If you mean that vulnerable CPUs always have fence.i: What if a CPU
still does not support the instruction (no matter if it is vulnerable or
not)?

If I understand the RISC-V JIT correctly, it will then still generate
fence.i with this patch. When this eBPF program is then invoked the
CPU will panic upon reaching the fence.i which is a invalid opcode as
far as this CPU is concerned. Or is there some ifdef I am missing here?

I would assume you need something like this:

case BPF_ST | BPF_NOSPEC:
  if (riscv_has_extension_likely(RISCV_ISA_EXT_ZIFENCEI))
    emit_fence_i(ctx);
  break;

Or is there some guarantee that this extension is always available? I
read [3] as implying that this is no longer the case with the 2.0
instruction set for unprivileged. Does this also mean it is an optional
extension for the privileged ISA?

RISC-V cpufeature.c had this in [2]:

		/*
		 * Linux requires the following extensions, so we may as well
		 * always set them.
		 */
		set_bit(RISCV_ISA_EXT_ZICSR, this_isa);
		set_bit(RISCV_ISA_EXT_ZIFENCEI, this_isa);

But as of [1] it was changed to:

		if (acpi_disabled) {
			set_bit(RISCV_ISA_EXT_ZICSR, source_isa);
			set_bit(RISCV_ISA_EXT_ZIFENCEI, source_isa);

So based on that I would assume fence.i may not always be supported.

But I also found that 921ebd8f2c08 ("RISC-V: Allow userspace to flush
the instruction cache") seems to assume that fence.i always works (see
local_flush_icache_all() which I assume runs in the kernel).

Even if the CPU is known vulnerable but does not support the extension,
it will be better not to generate the instruction. If we still want to
do something about these CPUs, maybe add a warning message to advise the
user that unpriv eBPF should definately be kept disabled on this CPU?

[1] https://lore.kernel.org/all/20230711224600.10879-1-palmer@rivosinc.com/
[2] https://lore.kernel.org/all/20230607-nest-collision-5796b6be8be6@spud/
[3] https://docs.riscv.org/reference/isa/unpriv/zifencei.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC
  2026-01-07 17:52         ` Luis Gerhorst
@ 2026-01-07 23:30           ` Samuel Holland
  2026-01-08 10:05             ` Luis Gerhorst
  0 siblings, 1 reply; 14+ messages in thread
From: Samuel Holland @ 2026-01-07 23:30 UTC (permalink / raw)
  To: Luis Gerhorst, Lukas Gerlach
  Cc: ast, bjorn, bpf, daniel.weber, daniel, jo.vanbulck, linux-riscv,
	luke.r.nels, marton.bognar, michael.schwarz, palmer, pjw, xi.wang,
	cleger, palmer, conor.dooley, andrew

On 2026-01-07 11:52 AM, Luis Gerhorst wrote:
> Lukas Gerlach <lukas.gerlach@cispa.de> writes:
> 
>> Regarding bpf_jit_bypass_spec_v1/v4(): currently this is per-architecture.
>> What we need is per-processor granularity, so we can disable mitigations
>> on in-order cores and keep them enabled on vulnerable out-of-order processors.
> 
> Yes, sorry this was unclear. I just wanted to point out that once you
> have that infrastructure you can implement them as follows:
> 
> bpf_jit_bypass_spec_v1/v4() {
>   if (RV_CPU_IN_ORDER())
>     return true;
>   else
>     return false;
> }
> 
> But you are right that the definition of RV_CPU_IN_ORDER() is still
> missing of course.
> 
>> Regarding fence.i being an extension: all RISC-V processors supported by the
>> kernel that are vulnerable to these attacks support this instruction.
> 
> I am not sure if I misunderstand the "that are vulnerable to these
> attacks".
> 
> If you mean that vulnerable CPUs always have fence.i: What if a CPU
> still does not support the instruction (no matter if it is vulnerable or
> not)?
> 
> If I understand the RISC-V JIT correctly, it will then still generate
> fence.i with this patch. When this eBPF program is then invoked the
> CPU will panic upon reaching the fence.i which is a invalid opcode as
> far as this CPU is concerned. Or is there some ifdef I am missing here?
> 
> I would assume you need something like this:
> 
> case BPF_ST | BPF_NOSPEC:
>   if (riscv_has_extension_likely(RISCV_ISA_EXT_ZIFENCEI))
>     emit_fence_i(ctx);
>   break;
> 
> Or is there some guarantee that this extension is always available? I
> read [3] as implying that this is no longer the case with the 2.0
> instruction set for unprivileged. Does this also mean it is an optional
> extension for the privileged ISA?

The Zifencei extension is no longer a mandatory part of the ISA, but it is
mandatory for Linux. Linux requires at least "rv32ima or rv64ima, as defined by
version 2.2 of the user ISA and version 1.10 of the privileged ISA".

Notably, in version 2.2 of the user ISA, the Zifencei extension was still an
unnamed subset of the I extension, so it is included in the above requirement.
It was later removed from the I extension and given its own name, which is why
we have weirdness like the code below. (You can see in arch/riscv/Makefile where
we unconditionally add either ISA version 2.2 or Zifencei to CFLAGS.)

> 
> RISC-V cpufeature.c had this in [2]:
> 
> 		/*
> 		 * Linux requires the following extensions, so we may as well
> 		 * always set them.
> 		 */
> 		set_bit(RISCV_ISA_EXT_ZICSR, this_isa);
> 		set_bit(RISCV_ISA_EXT_ZIFENCEI, this_isa);
> 
> But as of [1] it was changed to:
> 
> 		if (acpi_disabled) {
> 			set_bit(RISCV_ISA_EXT_ZICSR, source_isa);
> 			set_bit(RISCV_ISA_EXT_ZIFENCEI, source_isa);
> 
> So based on that I would assume fence.i may not always be supported.

This is just a quirk of the parsing code. As mentioned in [1], older devicetrees
were written while Zifencei was an implicit part of I, so we don't expect it to
appear in the devicetree. The ACPI table definition was written after Zifencei
was a separate extension, so we do expect Zifencei to appear on its own in the
ACPI table. But it is still required. (We don't currently check that all
extensions required by the kernel are actually present; this will be done as
part of the RVA23 enablement.)

> But I also found that 921ebd8f2c08 ("RISC-V: Allow userspace to flush
> the instruction cache") seems to assume that fence.i always works (see
> local_flush_icache_all() which I assume runs in the kernel).

Yes, the kernel definitely won't run if fence.i is missing, so we don't need to
worry about such hardware. We could probably document this better.

Regards,
Samuel

> Even if the CPU is known vulnerable but does not support the extension,
> it will be better not to generate the instruction. If we still want to
> do something about these CPUs, maybe add a warning message to advise the
> user that unpriv eBPF should definately be kept disabled on this CPU?
> 
> [1] https://lore.kernel.org/all/20230711224600.10879-1-palmer@rivosinc.com/
> [2] https://lore.kernel.org/all/20230607-nest-collision-5796b6be8be6@spud/
> [3] https://docs.riscv.org/reference/isa/unpriv/zifencei.html
> 
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC
  2026-01-07 23:30           ` Samuel Holland
@ 2026-01-08 10:05             ` Luis Gerhorst
  0 siblings, 0 replies; 14+ messages in thread
From: Luis Gerhorst @ 2026-01-08 10:05 UTC (permalink / raw)
  To: Samuel Holland
  Cc: Lukas Gerlach, ast, bjorn, bpf, daniel.weber, daniel, jo.vanbulck,
	linux-riscv, luke.r.nels, marton.bognar, michael.schwarz, palmer,
	pjw, xi.wang, cleger, palmer, conor.dooley, andrew

Samuel Holland <samuel.holland@sifive.com> writes:

> The Zifencei extension is no longer a mandatory part of the ISA, but it is
> mandatory for Linux. Linux requires at least "rv32ima or rv64ima, as defined by
> version 2.2 of the user ISA and version 1.10 of the privileged ISA".
>
> Notably, in version 2.2 of the user ISA, the Zifencei extension was still an
> unnamed subset of the I extension, so it is included in the above requirement.
> It was later removed from the I extension and given its own name, which is why
> we have weirdness like the code below. (You can see in arch/riscv/Makefile where
> we unconditionally add either ISA version 2.2 or Zifencei to CFLAGS.)
>
>> RISC-V cpufeature.c had this in [2]:
>> 
>> 		/*
>> 		 * Linux requires the following extensions, so we may as well
>> 		 * always set them.
>> 		 */
>> 		set_bit(RISCV_ISA_EXT_ZICSR, this_isa);
>> 		set_bit(RISCV_ISA_EXT_ZIFENCEI, this_isa);
>> 
>> But as of [1] it was changed to:
>> 
>> 		if (acpi_disabled) {
>> 			set_bit(RISCV_ISA_EXT_ZICSR, source_isa);
>> 			set_bit(RISCV_ISA_EXT_ZIFENCEI, source_isa);
>> 
>> So based on that I would assume fence.i may not always be supported.
>
> This is just a quirk of the parsing code. As mentioned in [1], older devicetrees
> were written while Zifencei was an implicit part of I, so we don't expect it to
> appear in the devicetree. The ACPI table definition was written after Zifencei
> was a separate extension, so we do expect Zifencei to appear on its own in the
> ACPI table. But it is still required. (We don't currently check that all
> extensions required by the kernel are actually present; this will be done as
> part of the RVA23 enablement.)
>
>> But I also found that 921ebd8f2c08 ("RISC-V: Allow userspace to flush
>> the instruction cache") seems to assume that fence.i always works (see
>> local_flush_icache_all() which I assume runs in the kernel).
>
> Yes, the kernel definitely won't run if fence.i is missing, so we don't need to
> worry about such hardware. We could probably document this better.

Thanks for clarifying this! In that case the patch looks good to me.

I assume some testing has been done to ensure the instruction coding
works. (I think the eBPF CI does not have RISC-V yet but [1] previously
worked fine for me.)

Acked-by: Luis Gerhorst <luis.gerhorst@fau.de>

[1] https://github.com/pulehui/riscv-bpf-vmtest

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC
  2025-12-28 17:37 [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC Lukas Gerlach
  2026-01-05 23:28 ` Paul Walmsley
@ 2026-01-09  3:41 ` Bo Gan
  2026-01-09  5:36   ` [tech-speculation-barriers] " Stefan O'Rear
  2026-01-12 18:33 ` Bo Gan
  2 siblings, 1 reply; 14+ messages in thread
From: Bo Gan @ 2026-01-09  3:41 UTC (permalink / raw)
  To: Lukas Gerlach, bpf, linux-riscv, sorear,
	tech-speculation-barriers
  Cc: bjorn, ast, daniel, luke.r.nels, xi.wang, palmer, luis.gerhorst,
	daniel.weber, marton.bognar, jo.vanbulck, michael.schwarz

Hi Lukas,

Stefan and I have some doubts on fence.i's effectiveness as speculation
barrier. Flushing entire local instruction cache and instruction pipeline
is not absolutely necessary on impl having coherent I/D caches. Quoting
from Unprivileged SPEC ver. 20250508:

"The FENCE.I instruction was designed to support a wide variety of
  implementations. A simple implementation can flush the local instruction
  cache and the instruction pipeline when the FENCE.I is executed. A more
  complex implementation might snoop the instruction (data) cache on every
  data (instruction) cache miss, or use an inclusive unified private L2
  cache to invalidate lines from the primary instruction cache when they
  are being written by a local store instruction. If instruction and data
  caches are kept coherent in this way, or if the memory system consists of
  only uncached RAMs, then just the fetch pipeline needs to be flushed at a
  FENCE.I"

There's the question on overhead, too. Perhaps there's a more accurate and
lightweight insn available? I'm not an expert in u-arch. My gut feeling is
that we should not be dependent on specific impl's behavior and the riscv
SPEC should provide guidelines on speculation barrier instructions and how
to use them. Thus, I'm forwarding this to the Speculation Barriers Task-
Group, which I hope should be the perfect place to discuss such kind of
issues. @Speculation Barriers TG Please share your thoughts. Note that we
are dealing with existing HW, so we expect something to be working with
current SPEC and actual silicon. I'd be happy if I'm proven wrong, and
fence.i can actually be a speculation barrier. That's also a relief. Thank
you everyone.

BTW, per SPEC:

  "The FENCE.I only synchronizes the local hart, and the OS can reschedule
   the user hart to a different physical hart after the FENCE.I. This would
   require the OS to execute an additional FENCE.I as part of every context
   migration"

fence.i is local. I know some core does a broadcast and try to make it a
global fence.i, but this is not required by the SPEC.

Bo

On 12/28/25 09:37, Lukas Gerlach wrote:
> The BPF verifier inserts BPF_NOSPEC instructions to create speculation
> barriers. However, the RISC-V BPF JIT emits nothing for this
> instruction, leaving programs vulnerable to speculative execution
> attacks.
> 
> Originally, BPF_NOSPEC was used only for Spectre v4 mitigation, programs
> containing potential Spectre v1 gadgets were rejected by the verifier.
> With the VeriFence changes, the verifier now accepts these
> programs and inserts BPF_NOSPEC barriers for Spectre v1 mitigation as
> well. On RISC-V, this means programs that were previously rejected are
> now accepted but left unprotected against both v1 and v4 attacks.
> 
> RISC-V lacks a dedicated speculation barrier instruction.
> This patch uses the fence.i instruction as a stopgap solution.
> However an alternative and safer approach would be to reject vulnerable bpf
> programs again.
> 
> Fixes: f5e81d111750 ("bpf: Introduce BPF nospec instruction for mitigating Spectre v4")
> Fixes: 5fcf896efe28 ("Merge branch 'bpf-mitigate-spectre-v1-using-barriers'")
> Signed-off-by: Lukas Gerlach <lukas.gerlach@cispa.de>
> ---
>   arch/riscv/net/bpf_jit.h        | 10 ++++++++++
>   arch/riscv/net/bpf_jit_comp32.c |  6 +++++-
>   arch/riscv/net/bpf_jit_comp64.c |  6 +++++-
>   3 files changed, 20 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h
> index 632ced07bca4..e70b3bc19206 100644
> --- a/arch/riscv/net/bpf_jit.h
> +++ b/arch/riscv/net/bpf_jit.h
> @@ -619,6 +619,16 @@ static inline void emit_fence_rw_rw(struct rv_jit_context *ctx)
>   	emit(rv_fence(0x3, 0x3), ctx);
>   }
>   
> +static inline u32 rv_fence_i(void)
> +{
> +	return rv_i_insn(0, 0, 1, 0, 0x0f);
> +}
> +
> +static inline void emit_fence_i(struct rv_jit_context *ctx)
> +{
> +	emit(rv_fence_i(), ctx);
> +}
> +
>   static inline u32 rv_nop(void)
>   {
>   	return rv_i_insn(0, 0, 0, 0, 0x13);
> diff --git a/arch/riscv/net/bpf_jit_comp32.c b/arch/riscv/net/bpf_jit_comp32.c
> index 592dd86fbf81..d9a6f55a7e8e 100644
> --- a/arch/riscv/net/bpf_jit_comp32.c
> +++ b/arch/riscv/net/bpf_jit_comp32.c
> @@ -1248,8 +1248,12 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
>   			return -1;
>   		break;
>   
> -	/* speculation barrier */
> +	/*
> +	 * Speculation barrier using fence.i for pipeline serialization.
> +	 * RISC-V lacks a dedicated speculation barrier instruction.
> +	 */
>   	case BPF_ST | BPF_NOSPEC:
> +		emit_fence_i(ctx);
>   		break;
>   
>   	case BPF_ST | BPF_MEM | BPF_B:
> diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
> index 45cbc7c6fe49..fabafbebde0c 100644
> --- a/arch/riscv/net/bpf_jit_comp64.c
> +++ b/arch/riscv/net/bpf_jit_comp64.c
> @@ -1864,8 +1864,12 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
>   		break;
>   	}
>   
> -	/* speculation barrier */
> +	/*
> +	 * Speculation barrier using fence.i for pipeline serialization.
> +	 * RISC-V lacks a dedicated speculation barrier instruction.
> +	 */
>   	case BPF_ST | BPF_NOSPEC:
> +		emit_fence_i(ctx);
>   		break;
>   
>   	/* ST: *(size *)(dst + off) = imm */


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [tech-speculation-barriers] [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC
  2026-01-09  3:41 ` Bo Gan
@ 2026-01-09  5:36   ` Stefan O'Rear
  2026-01-12 16:19     ` Luis Gerhorst
  0 siblings, 1 reply; 14+ messages in thread
From: Stefan O'Rear @ 2026-01-09  5:36 UTC (permalink / raw)
  To: tech-speculation-barriers, Lukas Gerlach, bpf, linux-riscv
  Cc: Björn Töpel, Alexei Starovoitov, Daniel Borkmann,
	luke.r.nels, xi.wang, Palmer Dabbelt, luis.gerhorst, daniel.weber,
	marton.bognar, jo.vanbulck, michael.schwarz

On Thu, Jan 8, 2026, at 10:37 PM, Bo Gan via lists.riscv.org wrote:
> Hi Lukas,
>
> Stefan and I have some doubts on fence.i's effectiveness as speculation
> barrier. Flushing entire local instruction cache and instruction pipeline
> is not absolutely necessary on impl having coherent I/D caches. Quoting
> from Unprivileged SPEC ver. 20250508:
>
> "The FENCE.I instruction was designed to support a wide variety of
>   implementations. A simple implementation can flush the local instruction
>   cache and the instruction pipeline when the FENCE.I is executed. A more
>   complex implementation might snoop the instruction (data) cache on every
>   data (instruction) cache miss, or use an inclusive unified private L2
>   cache to invalidate lines from the primary instruction cache when they
>   are being written by a local store instruction. If instruction and data
>   caches are kept coherent in this way, or if the memory system consists of
>   only uncached RAMs, then just the fetch pipeline needs to be flushed at a
>   FENCE.I"

Note that this is non-normative text and the actual range of allowed
implementations is wider than this.

I'm particularly concerned that the security property we appear to need (I am
more familiar with u-arch vulnerabilities than BPF ISA details) is an _issue
barrier_, but correctness for FENCE.I as currently specified only requires
a _retirement barrier_.

FENCE.I requires that instructions after the FENCE.I in program order not
retire unless the hart can verify that they were not overwritten in memory
between the time they were fetched and the memory-order point of the FENCE.I.
Simple implementations will probably achieve this by re-fetching and
preventing retirement of all instructions after the FENCE.I, but if the
instructions speculatively execute then it is not useful for a Spectre v1
barrier. Issuing an instruction which cannot possibly retire wastes energy,
but if FENCE.I is assumed to be an extremely rare operation this may not be
a priority.

Particularly complex implementations can go as far as to treat FENCE.I as a
no-op if they snoop the reorder buffer as well as the instruction cache.

> There's the question on overhead, too. Perhaps there's a more accurate and
> lightweight insn available? I'm not an expert in u-arch. My gut feeling is
> that we should not be dependent on specific impl's behavior and the riscv
> SPEC should provide guidelines on speculation barrier instructions and how
> to use them. Thus, I'm forwarding this to the Speculation Barriers Task-
> Group, which I hope should be the perfect place to discuss such kind of
> issues. @Speculation Barriers TG Please share your thoughts. Note that we
> are dealing with existing HW, so we expect something to be working with
> current SPEC and actual silicon. I'd be happy if I'm proven wrong, and
> fence.i can actually be a speculation barrier. That's also a relief. Thank
> you everyone.

The JH7110 has 512 I-cache lines per core, all of which must be invalidated
on a FENCE.I. I'm not sure how many cycles that takes for the invalidation,
but some fraction of those will subsequently be needed before they would
otherwise be evicted, which could add up to several thousand cycles of
overhead depending on the cache miss latency, for a BPF program with a single
BPF_NOSPEC. Compared to roughly one thousand cycles for a kernel entry and
exit, it may be more practical to disable BPF and rely on userspace event
processing for affected hardware, even if FENCE.I is otherwise useful as a
speculation barrier.

I don't think it's possible to define a set of speculation barriers that apply
to all possible existing and future hardware with the current specifications,
because the ratified specifications cannot be changed and other than Zkt/Zvkt
do not constrain uarch side channels.

The TG is defining a new specification which includes semantically rich
barriers that can have optimal overhead on new hardware. If we find a set of
speculation barriers that work on some or (optimistically) all existing
hardware, we would need to define a retroactive specification which documents
that behavior, much like Zkt/Zvkt or many of the extensions defined in the
profiles specification.

> BTW, per SPEC:
>
>   "The FENCE.I only synchronizes the local hart, and the OS can reschedule
>    the user hart to a different physical hart after the FENCE.I. This would
>    require the OS to execute an additional FENCE.I as part of every context
>    migration"
>
> fence.i is local. I know some core does a broadcast and try to make it a
> global fence.i, but this is not required by the SPEC.

The speculation fences that are used on other architectures are all core-local
operations so I don't think this is, itself, a problem.

-s

> Bo
>
> On 12/28/25 09:37, Lukas Gerlach wrote:
>> The BPF verifier inserts BPF_NOSPEC instructions to create speculation
>> barriers. However, the RISC-V BPF JIT emits nothing for this
>> instruction, leaving programs vulnerable to speculative execution
>> attacks.
>> 
>> Originally, BPF_NOSPEC was used only for Spectre v4 mitigation, programs
>> containing potential Spectre v1 gadgets were rejected by the verifier.
>> With the VeriFence changes, the verifier now accepts these
>> programs and inserts BPF_NOSPEC barriers for Spectre v1 mitigation as
>> well. On RISC-V, this means programs that were previously rejected are
>> now accepted but left unprotected against both v1 and v4 attacks.
>> 
>> RISC-V lacks a dedicated speculation barrier instruction.
>> This patch uses the fence.i instruction as a stopgap solution.
>> However an alternative and safer approach would be to reject vulnerable bpf
>> programs again.
>> 
>> Fixes: f5e81d111750 ("bpf: Introduce BPF nospec instruction for mitigating Spectre v4")
>> Fixes: 5fcf896efe28 ("Merge branch 'bpf-mitigate-spectre-v1-using-barriers'")
>> Signed-off-by: Lukas Gerlach <lukas.gerlach@cispa.de>
>> ---
>>   arch/riscv/net/bpf_jit.h        | 10 ++++++++++
>>   arch/riscv/net/bpf_jit_comp32.c |  6 +++++-
>>   arch/riscv/net/bpf_jit_comp64.c |  6 +++++-
>>   3 files changed, 20 insertions(+), 2 deletions(-)
>> 
>> diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h
>> index 632ced07bca4..e70b3bc19206 100644
>> --- a/arch/riscv/net/bpf_jit.h
>> +++ b/arch/riscv/net/bpf_jit.h
>> @@ -619,6 +619,16 @@ static inline void emit_fence_rw_rw(struct rv_jit_context *ctx)
>>   	emit(rv_fence(0x3, 0x3), ctx);
>>   }
>>   
>> +static inline u32 rv_fence_i(void)
>> +{
>> +	return rv_i_insn(0, 0, 1, 0, 0x0f);
>> +}
>> +
>> +static inline void emit_fence_i(struct rv_jit_context *ctx)
>> +{
>> +	emit(rv_fence_i(), ctx);
>> +}
>> +
>>   static inline u32 rv_nop(void)
>>   {
>>   	return rv_i_insn(0, 0, 0, 0, 0x13);
>> diff --git a/arch/riscv/net/bpf_jit_comp32.c b/arch/riscv/net/bpf_jit_comp32.c
>> index 592dd86fbf81..d9a6f55a7e8e 100644
>> --- a/arch/riscv/net/bpf_jit_comp32.c
>> +++ b/arch/riscv/net/bpf_jit_comp32.c
>> @@ -1248,8 +1248,12 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
>>   			return -1;
>>   		break;
>>   
>> -	/* speculation barrier */
>> +	/*
>> +	 * Speculation barrier using fence.i for pipeline serialization.
>> +	 * RISC-V lacks a dedicated speculation barrier instruction.
>> +	 */
>>   	case BPF_ST | BPF_NOSPEC:
>> +		emit_fence_i(ctx);
>>   		break;
>>   
>>   	case BPF_ST | BPF_MEM | BPF_B:
>> diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
>> index 45cbc7c6fe49..fabafbebde0c 100644
>> --- a/arch/riscv/net/bpf_jit_comp64.c
>> +++ b/arch/riscv/net/bpf_jit_comp64.c
>> @@ -1864,8 +1864,12 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
>>   		break;
>>   	}
>>   
>> -	/* speculation barrier */
>> +	/*
>> +	 * Speculation barrier using fence.i for pipeline serialization.
>> +	 * RISC-V lacks a dedicated speculation barrier instruction.
>> +	 */
>>   	case BPF_ST | BPF_NOSPEC:
>> +		emit_fence_i(ctx);
>>   		break;
>>   
>>   	/* ST: *(size *)(dst + off) = imm */
>
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#19): 
> https://lists.riscv.org/g/tech-speculation-barriers/message/19
> Mute This Topic: https://lists.riscv.org/mt/117170030/7725087
> Group Owner: tech-speculation-barriers+owner@lists.riscv.org
> Unsubscribe: 
> https://lists.riscv.org/g/tech-speculation-barriers/leave/14814957/7725087/301854996/xyzzy 
> [sorear@fastmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [tech-speculation-barriers] [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC
  2026-01-09  5:36   ` [tech-speculation-barriers] " Stefan O'Rear
@ 2026-01-12 16:19     ` Luis Gerhorst
  0 siblings, 0 replies; 14+ messages in thread
From: Luis Gerhorst @ 2026-01-12 16:19 UTC (permalink / raw)
  To: Stefan O'Rear, Lukas Gerlach
  Cc: tech-speculation-barriers, bpf, linux-riscv,
	Björn Töpel, Alexei Starovoitov, Daniel Borkmann,
	luke.r.nels, xi.wang, Palmer Dabbelt, daniel.weber, marton.bognar,
	jo.vanbulck, michael.schwarz

"Stefan O'Rear" <sorear@fastmail.com> writes:

> On Thu, Jan 8, 2026, at 10:37 PM, Bo Gan via lists.riscv.org wrote:
>> Hi Lukas,
>>
>> Stefan and I have some doubts on fence.i's effectiveness as speculation
>> barrier. Flushing entire local instruction cache and instruction pipeline
>> is not absolutely necessary on impl having coherent I/D caches. Quoting
>> from Unprivileged SPEC ver. 20250508:
>>
>> "The FENCE.I instruction was designed to support a wide variety of
>>   implementations. A simple implementation can flush the local instruction
>>   cache and the instruction pipeline when the FENCE.I is executed. A more
>>   complex implementation might snoop the instruction (data) cache on every
>>   data (instruction) cache miss, or use an inclusive unified private L2
>>   cache to invalidate lines from the primary instruction cache when they
>>   are being written by a local store instruction. If instruction and data
>>   caches are kept coherent in this way, or if the memory system consists of
>>   only uncached RAMs, then just the fetch pipeline needs to be flushed at a
>>   FENCE.I"
>
> Note that this is non-normative text and the actual range of allowed
> implementations is wider than this.
>
> I'm particularly concerned that the security property we appear to need (I am
> more familiar with u-arch vulnerabilities than BPF ISA details) is an _issue
> barrier_, but correctness for FENCE.I as currently specified only requires
> a _retirement barrier_.

> FENCE.I requires that instructions after the FENCE.I in program order not
> retire unless the hart can verify that they were not overwritten in memory
> between the time they were fetched and the memory-order point of the FENCE.I.
> Simple implementations will probably achieve this by re-fetching and
> preventing retirement of all instructions after the FENCE.I,

Are you aware of any CPU implementation that works like this?

> but if the
> instructions speculatively execute then it is not useful for a Spectre v1
> barrier.

You are correct. However, I believe a retirement barrier would still
already be useful as a stopgap solution as it should still reduce the
success rate and therefore the bandwith of the exploit. Also, because
the verifier currently adds barriers very early (it does not only add
the barrier before the non-CT operation on a secret but already when
anything that is not allowed architecturally happens), it might actually
prevent some exploits. This does of course not offer full protection,
but it still makes it harder to develop working exploits.

> Issuing an instruction which cannot possibly retire wastes energy,
> but if FENCE.I is assumed to be an extremely rare operation this may not be
> a priority.
>
> Particularly complex implementations can go as far as to treat FENCE.I as a
> no-op if they snoop the reorder buffer as well as the instruction cache.
>
>> There's the question on overhead, too. Perhaps there's a more accurate and
>> lightweight insn available? I'm not an expert in u-arch. My gut feeling is
>> that we should not be dependent on specific impl's behavior and the riscv
>> SPEC should provide guidelines on speculation barrier instructions and how
>> to use them. Thus, I'm forwarding this to the Speculation Barriers Task-
>> Group, which I hope should be the perfect place to discuss such kind of
>> issues. @Speculation Barriers TG Please share your thoughts. Note that we
>> are dealing with existing HW, so we expect something to be working with
>> current SPEC and actual silicon. I'd be happy if I'm proven wrong, and
>> fence.i can actually be a speculation barrier. That's also a relief. Thank
>> you everyone.
>
> The JH7110 has 512 I-cache lines per core, all of which must be invalidated
> on a FENCE.I. I'm not sure how many cycles that takes for the invalidation,
> but some fraction of those will subsequently be needed before they would
> otherwise be evicted, which could add up to several thousand cycles of
> overhead depending on the cache miss latency, for a BPF program with a single
> BPF_NOSPEC. Compared to roughly one thousand cycles for a kernel entry and
> exit, it may be more practical to disable BPF and rely on userspace event
> processing for affected hardware, even if FENCE.I is otherwise useful as a
> speculation barrier.

Thank you very much. For JH7110 I think it would then be best to avoid
adding anything unless there is any strong evidence showing this CPU is
vulnerable to Spectre v1. (A quick search yielded no result but maybe
someone else has more information on this.) Even if it is vulnerable,
people might want performant unprivileged eBPF simply for compatibility
reasons. As we can not know whether untrusted unprivileged users are
actually a concern, a dmesg warning might be best then. Or maybe there
is some other construct that achieves the desired effect on JH7110.

> I don't think it's possible to define a set of speculation barriers that apply
> to all possible existing and future hardware with the current specifications,
> because the ratified specifications cannot be changed and other than Zkt/Zvkt
> do not constrain uarch side channels.
>
> The TG is defining a new specification which includes semantically rich
> barriers that can have optimal overhead on new hardware. If we find a set of
> speculation barriers that work on some or (optimistically) all existing
> hardware, we would need to define a retroactive specification which documents
> that behavior, much like Zkt/Zvkt or many of the extensions defined in the
> profiles specification.

That would be very useful to eBPF.

Are you aware of any existing RISC-V CPU implementations where FENCE.I,
or any other instruction, does delay issueing/retirement by a few cycles
(e.g., until concurrent stores have completed)? (I am aware that
retirement is not sufficient formally, but it is better than nothing.)
Anything like this might be preferable over simply filling up the
reorder buffer with some NOP instruction. And even if a part of the CPU
state may still be speculative, any such instruction would already be
useful as a (partial) stopgap solution.

Or does FENCE.I do this on any concrete CPU other than JH7110?

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC
  2025-12-28 17:37 [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC Lukas Gerlach
  2026-01-05 23:28 ` Paul Walmsley
  2026-01-09  3:41 ` Bo Gan
@ 2026-01-12 18:33 ` Bo Gan
  2026-01-13  1:51   ` Paul Walmsley
  2 siblings, 1 reply; 14+ messages in thread
From: Bo Gan @ 2026-01-12 18:33 UTC (permalink / raw)
  To: Lukas Gerlach, bpf, linux-riscv, tech-speculation-barriers
  Cc: bjorn, ast, daniel, luke.r.nels, xi.wang, palmer, luis.gerhorst,
	daniel.weber, marton.bognar, jo.vanbulck, michael.schwarz

Hi Lukas,

Please also check out Ved's response from the Speculation Barrier TG:

https://lists.riscv.org/g/tech-speculation-barriers/message/21

I think the best way forward is to wait for the TG to clearly define
speculation barrier instructions, and use them for future cores. For
existing HW, emit a warning and do nothing. I don't want to see bpf
doing fence.i universally for all riscv. Neither do I like it guessing
this and that specific core implementation needing fence.i or not. We
simply don't know how each vendor design their cores. Let the vendor
tell us what's the best instruction to use for our existing HW. E.g.,
for JH7110, it's really U74 from Sifive, so we can ask them to fill-in
If we absolutely want fence.i as a best-effort kind of approach, then
I strongly suggest we make it opt-in. I'd imagine it'd be a very loud
noise if folks found the bpf perf on riscv suddenly regressed.

Bo

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC
  2026-01-12 18:33 ` Bo Gan
@ 2026-01-13  1:51   ` Paul Walmsley
  2026-01-15 13:13     ` Lukas Gerlach
  0 siblings, 1 reply; 14+ messages in thread
From: Paul Walmsley @ 2026-01-13  1:51 UTC (permalink / raw)
  To: Bo Gan
  Cc: Lukas Gerlach, bpf, linux-riscv, tech-speculation-barriers, bjorn,
	ast, daniel, luke.r.nels, xi.wang, palmer, luis.gerhorst,
	daniel.weber, marton.bognar, jo.vanbulck, michael.schwarz

Hi,

On Mon, 12 Jan 2026, Bo Gan wrote:

> Please also check out Ved's response from the Speculation Barrier TG:
> 
> https://lists.riscv.org/g/tech-speculation-barriers/message/21
> 
> I think the best way forward is to wait for the TG to clearly define
> speculation barrier instructions, and use them for future cores. 

Waiting for the speculation barriers TG to complete their work is 
unfortunately a non-starter.  It seems unlikely to do so for quite some 
time.  Even once the extension is ratified, it's likely to take years 
before these instructions enter silicon and are widely available.  
Meanwhile, there are already newer designs in silicon targeting use cases 
that will need mitigations.

> For existing HW, emit a warning and do nothing. 

Can we really assume that this use case is the same as everyone else's?  
So far the Linux approach to microarchitectural attacks is to implement 
mitigations, with the expensive ones switchable, and then to give users 
the choice as to whether to disable mitigations for their use case.  Is 
there a reason for arch/riscv to take a substantially different approach?

> I don't want to see bpf doing fence.i universally for all riscv.

I think there's already agreement here - 

  https://lore.kernel.org/linux-riscv/20260106084410.94496-1-lukas.gerlach@cispa.de/

> Neither do I like it guessing this and that specific core implementation 
> needing fence.i or not. We simply don't know how each vendor design 
> their cores. Let the vendor tell us what's the best instruction to use 
> for our existing HW.  E.g., for JH7110, it's really U74 from Sifive, so 
> we can ask them to fill-in

We should make sure that the sequence used can be determined per- 
microarchitecture.  But if there's no guidance from the vendor, then the 
community should implement something that seems to work.  This should also 
encourage vendors to engage with us to make sure that the most efficient 
workarounds or mitigations are implemented.  That hopefully should also 
encourage vendors to design hardware that don't have these known 
vulnerabilities.


- Paul

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC
  2026-01-13  1:51   ` Paul Walmsley
@ 2026-01-15 13:13     ` Lukas Gerlach
  0 siblings, 0 replies; 14+ messages in thread
From: Lukas Gerlach @ 2026-01-15 13:13 UTC (permalink / raw)
  To: pjw
  Cc: ast, bjorn, bpf, daniel.weber, daniel, ganboing, jo.vanbulck,
	linux-riscv, luis.gerhorst, lukas.gerlach, luke.r.nels,
	marton.bognar, michael.schwarz, palmer, tech-speculation-barriers,
	xi.wang

Thanks for the discussion.

I agree with Paul that waiting for the TG to complete is not practical
given the timeline. There are vulnerable cores in silicon now.

On fence.i's effectiveness: Stefan and Ved are correct that it only
architecturally guarantees a retirement barrier. However, we tested
fence.i on C910/C920 and P550 and found it does prevent Spectre-PHT
attacks on these cores because they drain the pipeline.

On performance: on the cores we tested, fence.i flushes the instruction
cache, so the overhead is significant. The barrier should be configurable
per-microarchitecture. In-order cores like U74 and C906 are not vulnerable
and don't need it.

More broadly, getting selectable per-microarchitecture mitigations in
place for RISC-V now seems valuable. Implementations vary significantly
and will likely need different mitigation strategies going forward.

Lukas

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-01-15 13:28 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-28 17:37 [PATCH] riscv, bpf: Emit fence.i for BPF_NOSPEC Lukas Gerlach
2026-01-05 23:28 ` Paul Walmsley
2026-01-06  8:44   ` [PATCH] riscv, bpf: add a speculation barrier " Lukas Gerlach
2026-01-07  8:26     ` Luis Gerhorst
2026-01-07  9:54       ` [PATCH] riscv, bpf: Emit fence.i " Lukas Gerlach
2026-01-07 17:52         ` Luis Gerhorst
2026-01-07 23:30           ` Samuel Holland
2026-01-08 10:05             ` Luis Gerhorst
2026-01-09  3:41 ` Bo Gan
2026-01-09  5:36   ` [tech-speculation-barriers] " Stefan O'Rear
2026-01-12 16:19     ` Luis Gerhorst
2026-01-12 18:33 ` Bo Gan
2026-01-13  1:51   ` Paul Walmsley
2026-01-15 13:13     ` Lukas Gerlach

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox