Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64/sve: KVM: Hide SVE from CPU features exposed to guests

KVM guests cannot currently use SVE, because SVE is always
configured to trap to EL2.

However, a guest that sees SVE reported as present in
ID_AA64PFR0_EL1 may legitimately expect that SVE works and try to
use it. Instead of working, the guest will receive an injected
undef exception, which may cause the guest to oops or go into a
spin.

To avoid misleading the guest into believing that SVE will work,
this patch masks out the SVE field from ID_AA64PFR0_EL1 when a
guest attempts to read this register. No support is explicitly
added for ID_AA64ZFR0_EL1 either, so that is still emulated as
reading as zero, which is consistent with SVE not being
implemented.

This is a temporary measure, and will be removed in a later series
when full KVM support for SVE is implemented.

Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>

authored by

Dave Martin and committed by
Will Deacon
07d79fe7 aac45ffd

+11 -1
+11 -1
arch/arm64/kvm/sys_regs.c
··· 23 23 #include <linux/bsearch.h> 24 24 #include <linux/kvm_host.h> 25 25 #include <linux/mm.h> 26 + #include <linux/printk.h> 26 27 #include <linux/uaccess.h> 27 28 28 29 #include <asm/cacheflush.h> ··· 898 897 { 899 898 u32 id = sys_reg((u32)r->Op0, (u32)r->Op1, 900 899 (u32)r->CRn, (u32)r->CRm, (u32)r->Op2); 900 + u64 val = raz ? 0 : read_sanitised_ftr_reg(id); 901 901 902 - return raz ? 0 : read_sanitised_ftr_reg(id); 902 + if (id == SYS_ID_AA64PFR0_EL1) { 903 + if (val & (0xfUL << ID_AA64PFR0_SVE_SHIFT)) 904 + pr_err_once("kvm [%i]: SVE unsupported for guests, suppressing\n", 905 + task_pid_nr(current)); 906 + 907 + val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT); 908 + } 909 + 910 + return val; 903 911 } 904 912 905 913 /* cpufeature ID register access trap handlers */