]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: arm64: Hide ID_AA64MMFR2_EL1.NV from guest and userspace
authorMarc Zyngier <maz@kernel.org>
Thu, 20 Feb 2025 13:48:55 +0000 (13:48 +0000)
committerOliver Upton <oliver.upton@linux.dev>
Mon, 24 Feb 2025 19:06:55 +0000 (11:06 -0800)
Since our take on FEAT_NV is to only support FEAT_NV2, we should
never expose ID_AA64MMFR2_EL1.NV to a guest nor userspace.

Make sure we mask this field for good.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Joey Gouly <joey.gouly@arm.com>
Link: https://lore.kernel.org/r/20250220134907.554085-3-maz@kernel.org
[oliver: squash diff for NV field]
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
arch/arm64/kvm/sys_regs.c

index 82430c1e1dd02b1ac24fd2ddcd05a91272997fdb..4f675f4ae536e3ab2ecafb3d27ca0beae269e0b2 100644 (file)
@@ -1627,6 +1627,7 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
                break;
        case SYS_ID_AA64MMFR2_EL1:
                val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK;
+               val &= ~ID_AA64MMFR2_EL1_NV;
                break;
        case SYS_ID_AA64MMFR3_EL1:
                val &= ID_AA64MMFR3_EL1_TCRX | ID_AA64MMFR3_EL1_S1POE |
@@ -1945,6 +1946,22 @@ static int set_id_aa64pfr1_el1(struct kvm_vcpu *vcpu,
        return set_id_reg(vcpu, rd, user_val);
 }
 
+static int set_id_aa64mmfr2_el1(struct kvm_vcpu *vcpu,
+                               const struct sys_reg_desc *rd, u64 user_val)
+{
+       u64 hw_val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1);
+       u64 nv_mask = ID_AA64MMFR2_EL1_NV_MASK;
+
+       /*
+        * We made the mistake to expose the now deprecated NV field,
+        * so allow userspace to write it, but silently ignore it.
+        */
+       if ((hw_val & nv_mask) == (user_val & nv_mask))
+               user_val &= ~nv_mask;
+
+       return set_id_reg(vcpu, rd, user_val);
+}
+
 static int set_ctr_el0(struct kvm_vcpu *vcpu,
                       const struct sys_reg_desc *rd, u64 user_val)
 {
@@ -2671,7 +2688,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
                                        ID_AA64MMFR1_EL1_XNX |
                                        ID_AA64MMFR1_EL1_VH |
                                        ID_AA64MMFR1_EL1_VMIDBits)),
-       ID_WRITABLE(ID_AA64MMFR2_EL1, ~(ID_AA64MMFR2_EL1_RES0 |
+       ID_FILTERED(ID_AA64MMFR2_EL1,
+                   id_aa64mmfr2_el1, ~(ID_AA64MMFR2_EL1_RES0 |
                                        ID_AA64MMFR2_EL1_EVT |
                                        ID_AA64MMFR2_EL1_FWB |
                                        ID_AA64MMFR2_EL1_IDS |