mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 15:41:52 +02:00
KVM: riscv: Fix Spectre-v1 in floating-point register access
User-controlled indices are used to index into floating-point registers. Sanitize them with array_index_nospec() to prevent speculative out-of-bounds access. 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-3-192caab8e0dc@cispa.de Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
parent
ec87a82ca8
commit
8f0c15c4b1
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user