@@ -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 },
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 <alexandru.elisei@arm.com> --- arch/arm64/kvm/sys_regs.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)