@@ -1330,6 +1330,7 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
13301330 val &= ~ARM64_FEATURE_MASK (ID_AA64PFR1_EL1_MTE );
13311331
13321332 val &= ~ARM64_FEATURE_MASK (ID_AA64PFR1_EL1_SME );
1333+ val &= ~ARM64_FEATURE_MASK (ID_AA64PFR1_EL1_MPAM_frac );
13331334 break ;
13341335 case SYS_ID_AA64ISAR1_EL1 :
13351336 if (!vcpu_has_ptrauth (vcpu ))
@@ -1472,6 +1473,13 @@ static u64 read_sanitised_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
14721473
14731474 val &= ~ID_AA64PFR0_EL1_AMU_MASK ;
14741475
1476+ /*
1477+ * MPAM is disabled by default as KVM also needs a set of PARTID to
1478+ * program the MPAMVPMx_EL2 PARTID remapping registers with. But some
1479+ * older kernels let the guest see the ID bit.
1480+ */
1481+ val &= ~ID_AA64PFR0_EL1_MPAM_MASK ;
1482+
14751483 return val ;
14761484}
14771485
@@ -1560,6 +1568,42 @@ static int set_id_dfr0_el1(struct kvm_vcpu *vcpu,
15601568 return set_id_reg (vcpu , rd , val );
15611569}
15621570
1571+ static int set_id_aa64pfr0_el1 (struct kvm_vcpu * vcpu ,
1572+ const struct sys_reg_desc * rd , u64 user_val )
1573+ {
1574+ u64 hw_val = read_sanitised_ftr_reg (SYS_ID_AA64PFR0_EL1 );
1575+ u64 mpam_mask = ID_AA64PFR0_EL1_MPAM_MASK ;
1576+
1577+ /*
1578+ * Commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits
1579+ * in ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to
1580+ * guests, but didn't add trap handling. KVM doesn't support MPAM and
1581+ * always returns an UNDEF for these registers. The guest must see 0
1582+ * for this field.
1583+ *
1584+ * But KVM must also accept values from user-space that were provided
1585+ * by KVM. On CPUs that support MPAM, permit user-space to write
1586+ * the sanitizied value to ID_AA64PFR0_EL1.MPAM, but ignore this field.
1587+ */
1588+ if ((hw_val & mpam_mask ) == (user_val & mpam_mask ))
1589+ user_val &= ~ID_AA64PFR0_EL1_MPAM_MASK ;
1590+
1591+ return set_id_reg (vcpu , rd , user_val );
1592+ }
1593+
1594+ static int set_id_aa64pfr1_el1 (struct kvm_vcpu * vcpu ,
1595+ const struct sys_reg_desc * rd , u64 user_val )
1596+ {
1597+ u64 hw_val = read_sanitised_ftr_reg (SYS_ID_AA64PFR1_EL1 );
1598+ u64 mpam_mask = ID_AA64PFR1_EL1_MPAM_frac_MASK ;
1599+
1600+ /* See set_id_aa64pfr0_el1 for comment about MPAM */
1601+ if ((hw_val & mpam_mask ) == (user_val & mpam_mask ))
1602+ user_val &= ~ID_AA64PFR1_EL1_MPAM_frac_MASK ;
1603+
1604+ return set_id_reg (vcpu , rd , user_val );
1605+ }
1606+
15631607/*
15641608 * cpufeature ID register user accessors
15651609 *
@@ -2018,10 +2062,14 @@ static const struct sys_reg_desc sys_reg_descs[] = {
20182062 { SYS_DESC (SYS_ID_AA64PFR0_EL1 ),
20192063 .access = access_id_reg ,
20202064 .get_user = get_id_reg ,
2021- .set_user = set_id_reg ,
2065+ .set_user = set_id_aa64pfr0_el1 ,
20222066 .reset = read_sanitised_id_aa64pfr0_el1 ,
20232067 .val = ID_AA64PFR0_EL1_CSV2_MASK | ID_AA64PFR0_EL1_CSV3_MASK , },
2024- ID_SANITISED (ID_AA64PFR1_EL1 ),
2068+ { SYS_DESC (SYS_ID_AA64PFR1_EL1 ),
2069+ .access = access_id_reg ,
2070+ .get_user = get_id_reg ,
2071+ .set_user = set_id_aa64pfr1_el1 ,
2072+ .reset = kvm_read_sanitised_id_reg , },
20252073 ID_UNALLOCATED (4 ,2 ),
20262074 ID_UNALLOCATED (4 ,3 ),
20272075 ID_SANITISED (ID_AA64ZFR0_EL1 ),
0 commit comments