Skip to content

Commit ec87a82

Browse files
Lukas Gerlachavpatel
authored andcommitted
KVM: riscv: Fix Spectre-v1 in AIA CSR access
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 8c86405 ("KVM: x86: Protect ioapic_read_indirect() from Spectre-v1/L1TF attacks") and arm64 commit 41b8759 ("KVM: arm/arm64: vgic: fix possible spectre-v1 in vgic_get_irq()"). Reviewed-by: Radim Krčmář <radim.krcmar@oss.qualcomm.com> Signed-off-by: Lukas Gerlach <lukas.gerlach@cispa.de> Link: https://lore.kernel.org/r/20260303-kvm-riscv-spectre-v1-v2-2-192caab8e0dc@cispa.de Signed-off-by: Anup Patel <anup@brainfault.org>
1 parent f9e26fc commit ec87a82

1 file changed

Lines changed: 9 additions & 2 deletions

File tree

arch/riscv/kvm/aia.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/irqchip/riscv-imsic.h>
1414
#include <linux/irqdomain.h>
1515
#include <linux/kvm_host.h>
16+
#include <linux/nospec.h>
1617
#include <linux/percpu.h>
1718
#include <linux/spinlock.h>
1819
#include <asm/cpufeature.h>
@@ -182,10 +183,13 @@ int kvm_riscv_vcpu_aia_get_csr(struct kvm_vcpu *vcpu,
182183
unsigned long *out_val)
183184
{
184185
struct kvm_vcpu_aia_csr *csr = &vcpu->arch.aia_context.guest_csr;
186+
unsigned long regs_max = sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long);
185187

186-
if (reg_num >= sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long))
188+
if (reg_num >= regs_max)
187189
return -ENOENT;
188190

191+
reg_num = array_index_nospec(reg_num, regs_max);
192+
189193
*out_val = 0;
190194
if (kvm_riscv_aia_available())
191195
*out_val = ((unsigned long *)csr)[reg_num];
@@ -198,10 +202,13 @@ int kvm_riscv_vcpu_aia_set_csr(struct kvm_vcpu *vcpu,
198202
unsigned long val)
199203
{
200204
struct kvm_vcpu_aia_csr *csr = &vcpu->arch.aia_context.guest_csr;
205+
unsigned long regs_max = sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long);
201206

202-
if (reg_num >= sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long))
207+
if (reg_num >= regs_max)
203208
return -ENOENT;
204209

210+
reg_num = array_index_nospec(reg_num, regs_max);
211+
205212
if (kvm_riscv_aia_available()) {
206213
((unsigned long *)csr)[reg_num] = val;
207214

0 commit comments

Comments
 (0)