[RFC PATCH v3 03/16] KVM: arm64: Hide SPE from guests
From: Alexandru Elisei <hidden>
Date: 2020-10-27 17:27:11
Also in:
kvmarm
Subsystem:
arm64 port (aarch64 architecture), kernel virtual machine for arm64 (kvm/arm64), the rest · Maintainers:
Catalin Marinas, Will Deacon, Marc Zyngier, Oliver Upton, Linus Torvalds
When SPE is not implemented, accesses to the SPE registers cause an undefined exception. KVM advertises the presence of SPE in the ID_AA64DFR0_EL1 register, but configures MDCR_EL2 to trap accesses to the registers and injects an undefined exception when that happens. The architecture doesn't allow trapping access to the PMBIDR_EL1 register, which means the guest will be able to read it even if SPE is not advertised in the ID register. However, since it's usually better for a read to unexpectedly succeed than to cause an exception, let's stop advertising the presence of SPE to guests to better match how KVM emulates the architecture. Signed-off-by: Alexandru Elisei <redacted> --- arch/arm64/kvm/sys_regs.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index d9117bc56237..aa776c006a2a 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c@@ -244,6 +244,12 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu, return true; } +static unsigned int spe_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *r) +{ + return REG_HIDDEN_GUEST | REG_HIDDEN_USER; +} + static bool access_actlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r)
@@ -1143,6 +1149,8 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, val = cpuid_feature_cap_perfmon_field(val, ID_AA64DFR0_PMUVER_SHIFT, ID_AA64DFR0_PMUVER_8_1); + /* Don't advertise SPE to guests */ + val &= ~(0xfUL << ID_AA64DFR0_PMSVER_SHIFT); } else if (id == SYS_ID_DFR0_EL1) { /* Limit guests to PMUv3 for ARMv8.1 */ val = cpuid_feature_cap_perfmon_field(val,
@@ -1590,6 +1598,17 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 }, { SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 }, + { SYS_DESC(SYS_PMSCR_EL1), .visibility = spe_visibility }, + { SYS_DESC(SYS_PMSICR_EL1), .visibility = spe_visibility }, + { SYS_DESC(SYS_PMSIRR_EL1), .visibility = spe_visibility }, + { SYS_DESC(SYS_PMSFCR_EL1), .visibility = spe_visibility }, + { SYS_DESC(SYS_PMSEVFR_EL1), .visibility = spe_visibility }, + { SYS_DESC(SYS_PMSLATFR_EL1), .visibility = spe_visibility }, + { SYS_DESC(SYS_PMSIDR_EL1), .visibility = spe_visibility }, + { SYS_DESC(SYS_PMBLIMITR_EL1), .visibility = spe_visibility }, + { SYS_DESC(SYS_PMBPTR_EL1), .visibility = spe_visibility }, + { SYS_DESC(SYS_PMBSR_EL1), .visibility = spe_visibility }, + { SYS_DESC(SYS_PMINTENSET_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 }, { SYS_DESC(SYS_PMINTENCLR_EL1), access_pminten, reset_unknown, PMINTENSET_EL1 },
--
2.29.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel