mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-04 17:05:12 -04:00
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 commit8c86405f60("KVM: x86: Protect ioapic_read_indirect() from Spectre-v1/L1TF attacks") and arm64 commit41b87599c7("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>
This commit is contained in:
committed by
Anup Patel
parent
f9e26fc325
commit
ec87a82ca8
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user