* [PATCH 0/4] KVM: riscv: Fix Spectre-v1 vulnerabilities in register access
@ 2026-02-26 14:18 Lukas Gerlach
2026-02-26 14:18 ` [PATCH 1/4] KVM: riscv: Fix Spectre-v1 in ONE_REG " Lukas Gerlach
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Lukas Gerlach @ 2026-02-26 14:18 UTC (permalink / raw)
To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Andrew Jones
Cc: kvm, kvm-riscv, linux-riscv, linux-kernel, Daniel Weber,
Michael Schwarz, Marton Bognar, Jo Van Bulck, Lukas Gerlach
This series adds array_index_nospec() to RISC-V KVM to prevent
speculative out-of-bounds access to kernel memory.
Similar fixes exist for x86 (ioapic, lapic, PMU) and arm64 (vgic).
Signed-off-by: Lukas Gerlach <lukas.gerlach@cispa.de>
---
Lukas Gerlach (4):
KVM: riscv: Fix Spectre-v1 in ONE_REG register access
KVM: riscv: Fix Spectre-v1 in AIA CSR access
KVM: riscv: Fix Spectre-v1 in floating-point register access
KVM: riscv: Fix Spectre-v1 in PMU counter access
arch/riscv/kvm/aia.c | 11 +++++++++--
arch/riscv/kvm/vcpu_fp.c | 17 +++++++++++++----
arch/riscv/kvm/vcpu_onereg.c | 36 ++++++++++++++++++++++++++++--------
arch/riscv/kvm/vcpu_pmu.c | 4 ++++
4 files changed, 54 insertions(+), 14 deletions(-)
---
base-commit: f4d0ec0aa20d49f09dc01d82894ce80d72de0560
change-id: 20260226-kvm-riscv-spectre-v1-4d04dc68c226
Best regards,
--
Lukas Gerlach <lukas.gerlach@cispa.de>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/4] KVM: riscv: Fix Spectre-v1 in ONE_REG register access
2026-02-26 14:18 [PATCH 0/4] KVM: riscv: Fix Spectre-v1 vulnerabilities in register access Lukas Gerlach
@ 2026-02-26 14:18 ` Lukas Gerlach
2026-02-26 14:18 ` [PATCH 2/4] KVM: riscv: Fix Spectre-v1 in AIA CSR access Lukas Gerlach
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Lukas Gerlach @ 2026-02-26 14:18 UTC (permalink / raw)
To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Andrew Jones
Cc: kvm, kvm-riscv, linux-riscv, linux-kernel, Daniel Weber,
Michael Schwarz, Marton Bognar, Jo Van Bulck, Lukas Gerlach
User-controlled register indices from the ONE_REG ioctl are used to
index into arrays of register values. Sanitize them with
array_index_nospec() to prevent speculative out-of-bounds access.
Signed-off-by: Lukas Gerlach <lukas.gerlach@cispa.de>
---
arch/riscv/kvm/vcpu_onereg.c | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index e7ab6cb00646..a4c8703a96a9 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -10,6 +10,7 @@
#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/err.h>
+#include <linux/nospec.h>
#include <linux/uaccess.h>
#include <linux/kvm_host.h>
#include <asm/cacheflush.h>
@@ -127,6 +128,7 @@ static int kvm_riscv_vcpu_isa_check_host(unsigned long kvm_ext, unsigned long *g
kvm_ext >= ARRAY_SIZE(kvm_isa_ext_arr))
return -ENOENT;
+ kvm_ext = array_index_nospec(kvm_ext, ARRAY_SIZE(kvm_isa_ext_arr));
*guest_ext = kvm_isa_ext_arr[kvm_ext];
switch (*guest_ext) {
case RISCV_ISA_EXT_SMNPM:
@@ -443,13 +445,16 @@ static int kvm_riscv_vcpu_get_reg_core(struct kvm_vcpu *vcpu,
unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
KVM_REG_SIZE_MASK |
KVM_REG_RISCV_CORE);
+ unsigned long regs_max = sizeof(struct kvm_riscv_core) / sizeof(unsigned long);
unsigned long reg_val;
if (KVM_REG_SIZE(reg->id) != sizeof(unsigned long))
return -EINVAL;
- if (reg_num >= sizeof(struct kvm_riscv_core) / sizeof(unsigned long))
+ if (reg_num >= regs_max)
return -ENOENT;
+ reg_num = array_index_nospec(reg_num, regs_max);
+
if (reg_num == KVM_REG_RISCV_CORE_REG(regs.pc))
reg_val = cntx->sepc;
else if (KVM_REG_RISCV_CORE_REG(regs.pc) < reg_num &&
@@ -476,13 +481,16 @@ static int kvm_riscv_vcpu_set_reg_core(struct kvm_vcpu *vcpu,
unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK |
KVM_REG_SIZE_MASK |
KVM_REG_RISCV_CORE);
+ unsigned long regs_max = sizeof(struct kvm_riscv_core) / sizeof(unsigned long);
unsigned long reg_val;
if (KVM_REG_SIZE(reg->id) != sizeof(unsigned long))
return -EINVAL;
- if (reg_num >= sizeof(struct kvm_riscv_core) / sizeof(unsigned long))
+ if (reg_num >= regs_max)
return -ENOENT;
+ reg_num = array_index_nospec(reg_num, regs_max);
+
if (copy_from_user(®_val, uaddr, KVM_REG_SIZE(reg->id)))
return -EFAULT;
@@ -507,10 +515,13 @@ static int kvm_riscv_vcpu_general_get_csr(struct kvm_vcpu *vcpu,
unsigned long *out_val)
{
struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr;
+ unsigned long regs_max = sizeof(struct kvm_riscv_csr) / sizeof(unsigned long);
- if (reg_num >= sizeof(struct kvm_riscv_csr) / sizeof(unsigned long))
+ if (reg_num >= regs_max)
return -ENOENT;
+ reg_num = array_index_nospec(reg_num, regs_max);
+
if (reg_num == KVM_REG_RISCV_CSR_REG(sip)) {
kvm_riscv_vcpu_flush_interrupts(vcpu);
*out_val = (csr->hvip >> VSIP_TO_HVIP_SHIFT) & VSIP_VALID_MASK;
@@ -526,10 +537,13 @@ static int kvm_riscv_vcpu_general_set_csr(struct kvm_vcpu *vcpu,
unsigned long reg_val)
{
struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr;
+ unsigned long regs_max = sizeof(struct kvm_riscv_csr) / sizeof(unsigned long);
- if (reg_num >= sizeof(struct kvm_riscv_csr) / sizeof(unsigned long))
+ if (reg_num >= regs_max)
return -ENOENT;
+ reg_num = array_index_nospec(reg_num, regs_max);
+
if (reg_num == KVM_REG_RISCV_CSR_REG(sip)) {
reg_val &= VSIP_VALID_MASK;
reg_val <<= VSIP_TO_HVIP_SHIFT;
@@ -548,11 +562,14 @@ static inline int kvm_riscv_vcpu_smstateen_set_csr(struct kvm_vcpu *vcpu,
unsigned long reg_val)
{
struct kvm_vcpu_smstateen_csr *csr = &vcpu->arch.smstateen_csr;
+ unsigned long regs_max = sizeof(struct kvm_riscv_smstateen_csr) /
+ sizeof(unsigned long);
- if (reg_num >= sizeof(struct kvm_riscv_smstateen_csr) /
- sizeof(unsigned long))
+ if (reg_num >= regs_max)
return -EINVAL;
+ reg_num = array_index_nospec(reg_num, regs_max);
+
((unsigned long *)csr)[reg_num] = reg_val;
return 0;
}
@@ -562,11 +579,14 @@ static int kvm_riscv_vcpu_smstateen_get_csr(struct kvm_vcpu *vcpu,
unsigned long *out_val)
{
struct kvm_vcpu_smstateen_csr *csr = &vcpu->arch.smstateen_csr;
+ unsigned long regs_max = sizeof(struct kvm_riscv_smstateen_csr) /
+ sizeof(unsigned long);
- if (reg_num >= sizeof(struct kvm_riscv_smstateen_csr) /
- sizeof(unsigned long))
+ if (reg_num >= regs_max)
return -EINVAL;
+ reg_num = array_index_nospec(reg_num, regs_max);
+
*out_val = ((unsigned long *)csr)[reg_num];
return 0;
}
--
2.51.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/4] KVM: riscv: Fix Spectre-v1 in AIA CSR access
2026-02-26 14:18 [PATCH 0/4] KVM: riscv: Fix Spectre-v1 vulnerabilities in register access Lukas Gerlach
2026-02-26 14:18 ` [PATCH 1/4] KVM: riscv: Fix Spectre-v1 in ONE_REG " Lukas Gerlach
@ 2026-02-26 14:18 ` Lukas Gerlach
2026-02-26 14:19 ` [PATCH 3/4] KVM: riscv: Fix Spectre-v1 in floating-point register access Lukas Gerlach
2026-02-26 14:19 ` [PATCH 4/4] KVM: riscv: Fix Spectre-v1 in PMU counter access Lukas Gerlach
3 siblings, 0 replies; 7+ messages in thread
From: Lukas Gerlach @ 2026-02-26 14:18 UTC (permalink / raw)
To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Andrew Jones
Cc: kvm, kvm-riscv, linux-riscv, linux-kernel, Daniel Weber,
Michael Schwarz, Marton Bognar, Jo Van Bulck, Lukas Gerlach
User-controlled indices are used to access AIA CSR registers.
Sanitize them with array_index_nospec() to prevent speculative
out-of-bounds access.
Similar to x86 commit 8c86405f606c ("KVM: x86: Protect
ioapic_read_indirect() from Spectre-v1/L1TF attacks") and arm64
commit 41b87599c743 ("KVM: arm/arm64: vgic: fix possible spectre-v1
in vgic_get_irq()").
Signed-off-by: Lukas Gerlach <lukas.gerlach@cispa.de>
---
arch/riscv/kvm/aia.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c
index cac3c2b51d72..38de97d2f5b8 100644
--- a/arch/riscv/kvm/aia.c
+++ b/arch/riscv/kvm/aia.c
@@ -13,6 +13,7 @@
#include <linux/irqchip/riscv-imsic.h>
#include <linux/irqdomain.h>
#include <linux/kvm_host.h>
+#include <linux/nospec.h>
#include <linux/percpu.h>
#include <linux/spinlock.h>
#include <asm/cpufeature.h>
@@ -182,10 +183,13 @@ int kvm_riscv_vcpu_aia_get_csr(struct kvm_vcpu *vcpu,
unsigned long *out_val)
{
struct kvm_vcpu_aia_csr *csr = &vcpu->arch.aia_context.guest_csr;
+ unsigned long regs_max = sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long);
- if (reg_num >= sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long))
+ if (reg_num >= regs_max)
return -ENOENT;
+ reg_num = array_index_nospec(reg_num, regs_max);
+
*out_val = 0;
if (kvm_riscv_aia_available())
*out_val = ((unsigned long *)csr)[reg_num];
@@ -198,10 +202,13 @@ int kvm_riscv_vcpu_aia_set_csr(struct kvm_vcpu *vcpu,
unsigned long val)
{
struct kvm_vcpu_aia_csr *csr = &vcpu->arch.aia_context.guest_csr;
+ unsigned long regs_max = sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long);
- if (reg_num >= sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long))
+ if (reg_num >= regs_max)
return -ENOENT;
+ reg_num = array_index_nospec(reg_num, regs_max);
+
if (kvm_riscv_aia_available()) {
((unsigned long *)csr)[reg_num] = val;
--
2.51.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 3/4] KVM: riscv: Fix Spectre-v1 in floating-point register access
2026-02-26 14:18 [PATCH 0/4] KVM: riscv: Fix Spectre-v1 vulnerabilities in register access Lukas Gerlach
2026-02-26 14:18 ` [PATCH 1/4] KVM: riscv: Fix Spectre-v1 in ONE_REG " Lukas Gerlach
2026-02-26 14:18 ` [PATCH 2/4] KVM: riscv: Fix Spectre-v1 in AIA CSR access Lukas Gerlach
@ 2026-02-26 14:19 ` Lukas Gerlach
2026-02-26 14:19 ` [PATCH 4/4] KVM: riscv: Fix Spectre-v1 in PMU counter access Lukas Gerlach
3 siblings, 0 replies; 7+ messages in thread
From: Lukas Gerlach @ 2026-02-26 14:19 UTC (permalink / raw)
To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Andrew Jones
Cc: kvm, kvm-riscv, linux-riscv, linux-kernel, Daniel Weber,
Michael Schwarz, Marton Bognar, Jo Van Bulck, Lukas Gerlach
User-controlled indices are used to index into floating-point registers.
Sanitize them with array_index_nospec() to prevent speculative
out-of-bounds access.
Signed-off-by: Lukas Gerlach <lukas.gerlach@cispa.de>
---
arch/riscv/kvm/vcpu_fp.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/arch/riscv/kvm/vcpu_fp.c b/arch/riscv/kvm/vcpu_fp.c
index 030904d82b58..bd5a9e7e7165 100644
--- a/arch/riscv/kvm/vcpu_fp.c
+++ b/arch/riscv/kvm/vcpu_fp.c
@@ -10,6 +10,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/kvm_host.h>
+#include <linux/nospec.h>
#include <linux/uaccess.h>
#include <asm/cpufeature.h>
@@ -93,9 +94,11 @@ int kvm_riscv_vcpu_get_reg_fp(struct kvm_vcpu *vcpu,
if (reg_num == KVM_REG_RISCV_FP_F_REG(fcsr))
reg_val = &cntx->fp.f.fcsr;
else if ((KVM_REG_RISCV_FP_F_REG(f[0]) <= reg_num) &&
- reg_num <= KVM_REG_RISCV_FP_F_REG(f[31]))
+ reg_num <= KVM_REG_RISCV_FP_F_REG(f[31])) {
+ reg_num = array_index_nospec(reg_num,
+ ARRAY_SIZE(cntx->fp.f.f));
reg_val = &cntx->fp.f.f[reg_num];
- else
+ } else
return -ENOENT;
} else if ((rtype == KVM_REG_RISCV_FP_D) &&
riscv_isa_extension_available(vcpu->arch.isa, d)) {
@@ -107,6 +110,8 @@ int kvm_riscv_vcpu_get_reg_fp(struct kvm_vcpu *vcpu,
reg_num <= KVM_REG_RISCV_FP_D_REG(f[31])) {
if (KVM_REG_SIZE(reg->id) != sizeof(u64))
return -EINVAL;
+ reg_num = array_index_nospec(reg_num,
+ ARRAY_SIZE(cntx->fp.d.f));
reg_val = &cntx->fp.d.f[reg_num];
} else
return -ENOENT;
@@ -138,9 +143,11 @@ int kvm_riscv_vcpu_set_reg_fp(struct kvm_vcpu *vcpu,
if (reg_num == KVM_REG_RISCV_FP_F_REG(fcsr))
reg_val = &cntx->fp.f.fcsr;
else if ((KVM_REG_RISCV_FP_F_REG(f[0]) <= reg_num) &&
- reg_num <= KVM_REG_RISCV_FP_F_REG(f[31]))
+ reg_num <= KVM_REG_RISCV_FP_F_REG(f[31])) {
+ reg_num = array_index_nospec(reg_num,
+ ARRAY_SIZE(cntx->fp.f.f));
reg_val = &cntx->fp.f.f[reg_num];
- else
+ } else
return -ENOENT;
} else if ((rtype == KVM_REG_RISCV_FP_D) &&
riscv_isa_extension_available(vcpu->arch.isa, d)) {
@@ -152,6 +159,8 @@ int kvm_riscv_vcpu_set_reg_fp(struct kvm_vcpu *vcpu,
reg_num <= KVM_REG_RISCV_FP_D_REG(f[31])) {
if (KVM_REG_SIZE(reg->id) != sizeof(u64))
return -EINVAL;
+ reg_num = array_index_nospec(reg_num,
+ ARRAY_SIZE(cntx->fp.d.f));
reg_val = &cntx->fp.d.f[reg_num];
} else
return -ENOENT;
--
2.51.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 4/4] KVM: riscv: Fix Spectre-v1 in PMU counter access
2026-02-26 14:18 [PATCH 0/4] KVM: riscv: Fix Spectre-v1 vulnerabilities in register access Lukas Gerlach
` (2 preceding siblings ...)
2026-02-26 14:19 ` [PATCH 3/4] KVM: riscv: Fix Spectre-v1 in floating-point register access Lukas Gerlach
@ 2026-02-26 14:19 ` Lukas Gerlach
2026-02-27 13:28 ` Radim Krčmář
3 siblings, 1 reply; 7+ messages in thread
From: Lukas Gerlach @ 2026-02-26 14:19 UTC (permalink / raw)
To: Anup Patel, Atish Patra, Paul Walmsley, Palmer Dabbelt,
Albert Ou, Alexandre Ghiti, Andrew Jones
Cc: kvm, kvm-riscv, linux-riscv, linux-kernel, Daniel Weber,
Michael Schwarz, Marton Bognar, Jo Van Bulck, Lukas Gerlach
Guest-controlled counter indices received via SBI ecalls are used to
index into the PMC array. Sanitize them with array_index_nospec()
to prevent speculative out-of-bounds access.
Similar to x86 commit 13c5183a4e64 ("KVM: x86: Protect MSR-based
index computations in pmu.h from Spectre-v1/L1TF attacks").
Fixes: 8f0153ecd3bf ("RISC-V: KVM: Add skeleton support for perf")
Signed-off-by: Lukas Gerlach <lukas.gerlach@cispa.de>
---
arch/riscv/kvm/vcpu_pmu.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index 4d8d5e9aa53d..fd891750c31f 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -10,6 +10,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/kvm_host.h>
+#include <linux/nospec.h>
#include <linux/perf/riscv_pmu.h>
#include <asm/csr.h>
#include <asm/kvm_vcpu_sbi.h>
@@ -218,6 +219,7 @@ static int pmu_fw_ctr_read_hi(struct kvm_vcpu *vcpu, unsigned long cidx,
return -EINVAL;
}
+ cidx = array_index_nospec(cidx, RISCV_KVM_MAX_COUNTERS);
pmc = &kvpmu->pmc[cidx];
if (pmc->cinfo.type != SBI_PMU_CTR_TYPE_FW)
@@ -244,6 +246,7 @@ static int pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
return -EINVAL;
}
+ cidx = array_index_nospec(cidx, RISCV_KVM_MAX_COUNTERS);
pmc = &kvpmu->pmc[cidx];
if (pmc->cinfo.type == SBI_PMU_CTR_TYPE_FW) {
@@ -525,6 +528,7 @@ int kvm_riscv_vcpu_pmu_ctr_info(struct kvm_vcpu *vcpu, unsigned long cidx,
return 0;
}
+ cidx = array_index_nospec(cidx, RISCV_KVM_MAX_COUNTERS);
retdata->out_val = kvpmu->pmc[cidx].cinfo.value;
return 0;
--
2.51.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 4/4] KVM: riscv: Fix Spectre-v1 in PMU counter access
2026-02-26 14:19 ` [PATCH 4/4] KVM: riscv: Fix Spectre-v1 in PMU counter access Lukas Gerlach
@ 2026-02-27 13:28 ` Radim Krčmář
2026-02-27 15:12 ` Lukas Gerlach
0 siblings, 1 reply; 7+ messages in thread
From: Radim Krčmář @ 2026-02-27 13:28 UTC (permalink / raw)
To: Lukas Gerlach, Anup Patel, Atish Patra, Paul Walmsley,
Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Andrew Jones
Cc: kvm, kvm-riscv, linux-riscv, linux-kernel, Daniel Weber,
Michael Schwarz, Marton Bognar, Jo Van Bulck
2026-02-26T15:19:01+01:00, Lukas Gerlach <lukas.gerlach@cispa.de>:
> Guest-controlled counter indices received via SBI ecalls are used to
> index into the PMC array. Sanitize them with array_index_nospec()
> to prevent speculative out-of-bounds access.
>
> Similar to x86 commit 13c5183a4e64 ("KVM: x86: Protect MSR-based
> index computations in pmu.h from Spectre-v1/L1TF attacks").
>
> Fixes: 8f0153ecd3bf ("RISC-V: KVM: Add skeleton support for perf")
> Signed-off-by: Lukas Gerlach <lukas.gerlach@cispa.de>
> ---
> diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
> @@ -525,6 +528,7 @@ int kvm_riscv_vcpu_pmu_ctr_info(struct kvm_vcpu *vcpu, unsigned long cidx,
> return 0;
> }
>
> + cidx = array_index_nospec(cidx, RISCV_KVM_MAX_COUNTERS);
This one also covers a non-speculation bug, since the previous condition
used cidx > RISCV_KVM_MAX_COUNTER. :) I'll send a patch for that.
I noticed a few other places where mis-speculation is possible,
see below; can you explain why they don't need protection?
Anyway, the series looks good,
Reviewed-by: Radim Krčmář <radim.krcmar@oss.qualcomm.com>
Thanks.
---
diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index 4d8d5e9aa53d..08301b6033f0 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -87,7 +87,7 @@ static void kvm_pmu_release_perf_event(struct kvm_pmc *pmc)
static u64 kvm_pmu_get_perf_event_hw_config(u32 sbi_event_code)
{
- return hw_event_perf_map[sbi_event_code];
+ return hw_event_perf_map[array_index_nospec(sbi_event_code, SBI_PMU_HW_GENERAL_MAX)];
}
static u64 kvm_pmu_get_perf_event_cache_config(u32 sbi_event_code)
@@ -559,7 +559,7 @@ int kvm_riscv_vcpu_pmu_ctr_start(struct kvm_vcpu *vcpu, unsigned long ctr_base,
}
/* Start the counters that have been configured and requested by the guest */
for_each_set_bit(i, &ctr_mask, RISCV_MAX_COUNTERS) {
- pmc_index = i + ctr_base;
+ pmc_index = array_index_nospec(i + ctr_base, RISCV_KVM_MAX_COUNTERS);
if (!test_bit(pmc_index, kvpmu->pmc_in_use))
continue;
/* The guest started the counter again. Reset the overflow status */
@@ -630,7 +630,7 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
/* Stop the counters that have been configured and requested by the guest */
for_each_set_bit(i, &ctr_mask, RISCV_MAX_COUNTERS) {
- pmc_index = i + ctr_base;
+ pmc_index = array_index_nospec(i + ctr_base, RISCV_KVM_MAX_COUNTERS);
if (!test_bit(pmc_index, kvpmu->pmc_in_use))
continue;
pmc = &kvpmu->pmc[pmc_index];
@@ -761,6 +761,7 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *vcpu, unsigned long ctr_ba
}
}
+ ctr_idx = array_index_nospec(ctr_idx, RISCV_KVM_MAX_COUNTERS);
pmc = &kvpmu->pmc[ctr_idx];
pmc->idx = ctr_idx;
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 4/4] KVM: riscv: Fix Spectre-v1 in PMU counter access
2026-02-27 13:28 ` Radim Krčmář
@ 2026-02-27 15:12 ` Lukas Gerlach
0 siblings, 0 replies; 7+ messages in thread
From: Lukas Gerlach @ 2026-02-27 15:12 UTC (permalink / raw)
To: radim.krcmar
Cc: ajones, alex, anup, aou, atish.patra, daniel.weber, jo.vanbulck,
kvm-riscv, kvm, linux-kernel, linux-riscv, lukas.gerlach,
marton.bognar, michael.schwarz, palmer, pjw
Thanks for the review!
> This one also covers a non-speculation bug, since the previous condition
> used cidx > RISCV_KVM_MAX_COUNTER. :) I'll send a patch for that.
Nice catch, thanks for sending the fix.
> I noticed a few other places where mis-speculation is possible,
> see below; can you explain why they don't need protection?
They do, I missed those. Will send a v2 incorporating all four sites.
Thanks,
Lukas
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-02-27 15:13 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-26 14:18 [PATCH 0/4] KVM: riscv: Fix Spectre-v1 vulnerabilities in register access Lukas Gerlach
2026-02-26 14:18 ` [PATCH 1/4] KVM: riscv: Fix Spectre-v1 in ONE_REG " Lukas Gerlach
2026-02-26 14:18 ` [PATCH 2/4] KVM: riscv: Fix Spectre-v1 in AIA CSR access Lukas Gerlach
2026-02-26 14:19 ` [PATCH 3/4] KVM: riscv: Fix Spectre-v1 in floating-point register access Lukas Gerlach
2026-02-26 14:19 ` [PATCH 4/4] KVM: riscv: Fix Spectre-v1 in PMU counter access Lukas Gerlach
2026-02-27 13:28 ` Radim Krčmář
2026-02-27 15:12 ` Lukas Gerlach
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®