Full patch below.
M.
diff --git a/arch/arm64/kvm/config.c b/arch/arm64/kvm/config.c
index d4e1218b004dd..666070d4ccd7f 100644
--- a/arch/arm64/kvm/config.c
+++ b/arch/arm64/kvm/config.c
@@ -295,34 +295,34 @@ static const struct reg_bits_to_feat_map hfgrtr_feat_map[] = {
HFGRTR_EL2_APDBKey |
HFGRTR_EL2_APDAKey,
feat_pauth),
- NEEDS_FEAT(HFGRTR_EL2_VBAR_EL1 |
- HFGRTR_EL2_TTBR1_EL1 |
- HFGRTR_EL2_TTBR0_EL1 |
- HFGRTR_EL2_TPIDR_EL0 |
- HFGRTR_EL2_TPIDRRO_EL0 |
- HFGRTR_EL2_TPIDR_EL1 |
- HFGRTR_EL2_TCR_EL1 |
- HFGRTR_EL2_SCTLR_EL1 |
- HFGRTR_EL2_REVIDR_EL1 |
- HFGRTR_EL2_PAR_EL1 |
- HFGRTR_EL2_MPIDR_EL1 |
- HFGRTR_EL2_MIDR_EL1 |
- HFGRTR_EL2_MAIR_EL1 |
- HFGRTR_EL2_ISR_EL1 |
- HFGRTR_EL2_FAR_EL1 |
- HFGRTR_EL2_ESR_EL1 |
- HFGRTR_EL2_DCZID_EL0 |
- HFGRTR_EL2_CTR_EL0 |
- HFGRTR_EL2_CSSELR_EL1 |
- HFGRTR_EL2_CPACR_EL1 |
- HFGRTR_EL2_CONTEXTIDR_EL1 |
- HFGRTR_EL2_CLIDR_EL1 |
- HFGRTR_EL2_CCSIDR_EL1 |
- HFGRTR_EL2_AMAIR_EL1 |
- HFGRTR_EL2_AIDR_EL1 |
- HFGRTR_EL2_AFSR1_EL1 |
- HFGRTR_EL2_AFSR0_EL1,
- FEAT_AA64EL1),
+ NEEDS_FEAT_FLAG(HFGRTR_EL2_VBAR_EL1 |
+ HFGRTR_EL2_TTBR1_EL1 |
+ HFGRTR_EL2_TTBR0_EL1 |
+ HFGRTR_EL2_TPIDR_EL0 |
+ HFGRTR_EL2_TPIDRRO_EL0 |
+ HFGRTR_EL2_TPIDR_EL1 |
+ HFGRTR_EL2_TCR_EL1 |
+ HFGRTR_EL2_SCTLR_EL1 |
+ HFGRTR_EL2_REVIDR_EL1 |
+ HFGRTR_EL2_PAR_EL1 |
+ HFGRTR_EL2_MPIDR_EL1 |
+ HFGRTR_EL2_MIDR_EL1 |
+ HFGRTR_EL2_MAIR_EL1 |
+ HFGRTR_EL2_ISR_EL1 |
+ HFGRTR_EL2_FAR_EL1 |
+ HFGRTR_EL2_ESR_EL1 |
+ HFGRTR_EL2_DCZID_EL0 |
+ HFGRTR_EL2_CTR_EL0 |
+ HFGRTR_EL2_CSSELR_EL1 |
+ HFGRTR_EL2_CPACR_EL1 |
+ HFGRTR_EL2_CONTEXTIDR_EL1|
+ HFGRTR_EL2_CLIDR_EL1 |
+ HFGRTR_EL2_CCSIDR_EL1 |
+ HFGRTR_EL2_AMAIR_EL1 |
+ HFGRTR_EL2_AIDR_EL1 |
+ HFGRTR_EL2_AFSR1_EL1 |
+ HFGRTR_EL2_AFSR0_EL1,
+ NEVER_FGU, FEAT_AA64EL1),
};
static const struct reg_bits_to_feat_map hfgwtr_feat_map[] = {
@@ -368,25 +368,25 @@ static const struct reg_bits_to_feat_map hfgwtr_feat_map[] = {
HFGWTR_EL2_APDBKey |
HFGWTR_EL2_APDAKey,
feat_pauth),
- NEEDS_FEAT(HFGWTR_EL2_VBAR_EL1 |
- HFGWTR_EL2_TTBR1_EL1 |
- HFGWTR_EL2_TTBR0_EL1 |
- HFGWTR_EL2_TPIDR_EL0 |
- HFGWTR_EL2_TPIDRRO_EL0 |
- HFGWTR_EL2_TPIDR_EL1 |
- HFGWTR_EL2_TCR_EL1 |
- HFGWTR_EL2_SCTLR_EL1 |
- HFGWTR_EL2_PAR_EL1 |
- HFGWTR_EL2_MAIR_EL1 |
- HFGWTR_EL2_FAR_EL1 |
- HFGWTR_EL2_ESR_EL1 |
- HFGWTR_EL2_CSSELR_EL1 |
- HFGWTR_EL2_CPACR_EL1 |
- HFGWTR_EL2_CONTEXTIDR_EL1 |
- HFGWTR_EL2_AMAIR_EL1 |
- HFGWTR_EL2_AFSR1_EL1 |
- HFGWTR_EL2_AFSR0_EL1,
- FEAT_AA64EL1),
+ NEEDS_FEAT_FLAG(HFGWTR_EL2_VBAR_EL1 |
+ HFGWTR_EL2_TTBR1_EL1 |
+ HFGWTR_EL2_TTBR0_EL1 |
+ HFGWTR_EL2_TPIDR_EL0 |
+ HFGWTR_EL2_TPIDRRO_EL0 |
+ HFGWTR_EL2_TPIDR_EL1 |
+ HFGWTR_EL2_TCR_EL1 |
+ HFGWTR_EL2_SCTLR_EL1 |
+ HFGWTR_EL2_PAR_EL1 |
+ HFGWTR_EL2_MAIR_EL1 |
+ HFGWTR_EL2_FAR_EL1 |
+ HFGWTR_EL2_ESR_EL1 |
+ HFGWTR_EL2_CSSELR_EL1 |
+ HFGWTR_EL2_CPACR_EL1 |
+ HFGWTR_EL2_CONTEXTIDR_EL1|
+ HFGWTR_EL2_AMAIR_EL1 |
+ HFGWTR_EL2_AFSR1_EL1 |
+ HFGWTR_EL2_AFSR0_EL1,
+ NEVER_FGU, FEAT_AA64EL1),
};
static const struct reg_bits_to_feat_map hdfgrtr_feat_map[] = {
@@ -443,17 +443,17 @@ static const struct reg_bits_to_feat_map hdfgrtr_feat_map[] = {
FEAT_TRBE),
NEEDS_FEAT_FLAG(HDFGRTR_EL2_OSDLR_EL1, NEVER_FGU,
FEAT_DoubleLock),
- NEEDS_FEAT(HDFGRTR_EL2_OSECCR_EL1 |
- HDFGRTR_EL2_OSLSR_EL1 |
- HDFGRTR_EL2_DBGPRCR_EL1 |
- HDFGRTR_EL2_DBGAUTHSTATUS_EL1|
- HDFGRTR_EL2_DBGCLAIM |
- HDFGRTR_EL2_MDSCR_EL1 |
- HDFGRTR_EL2_DBGWVRn_EL1 |
- HDFGRTR_EL2_DBGWCRn_EL1 |
- HDFGRTR_EL2_DBGBVRn_EL1 |
- HDFGRTR_EL2_DBGBCRn_EL1,
- FEAT_AA64EL1)
+ NEEDS_FEAT_FLAG(HDFGRTR_EL2_OSECCR_EL1 |
+ HDFGRTR_EL2_OSLSR_EL1 |
+ HDFGRTR_EL2_DBGPRCR_EL1 |
+ HDFGRTR_EL2_DBGAUTHSTATUS_EL1|
+ HDFGRTR_EL2_DBGCLAIM |
+ HDFGRTR_EL2_MDSCR_EL1 |
+ HDFGRTR_EL2_DBGWVRn_EL1 |
+ HDFGRTR_EL2_DBGWCRn_EL1 |
+ HDFGRTR_EL2_DBGBVRn_EL1 |
+ HDFGRTR_EL2_DBGBCRn_EL1,
+ NEVER_FGU, FEAT_AA64EL1)
};
static const struct reg_bits_to_feat_map hdfgwtr_feat_map[] = {
@@ -503,16 +503,16 @@ static const struct reg_bits_to_feat_map hdfgwtr_feat_map[] = {
FEAT_TRBE),
NEEDS_FEAT_FLAG(HDFGWTR_EL2_OSDLR_EL1,
NEVER_FGU, FEAT_DoubleLock),
- NEEDS_FEAT(HDFGWTR_EL2_OSECCR_EL1 |
- HDFGWTR_EL2_OSLAR_EL1 |
- HDFGWTR_EL2_DBGPRCR_EL1 |
- HDFGWTR_EL2_DBGCLAIM |
- HDFGWTR_EL2_MDSCR_EL1 |
- HDFGWTR_EL2_DBGWVRn_EL1 |
- HDFGWTR_EL2_DBGWCRn_EL1 |
- HDFGWTR_EL2_DBGBVRn_EL1 |
- HDFGWTR_EL2_DBGBCRn_EL1,
- FEAT_AA64EL1),
+ NEEDS_FEAT_FLAG(HDFGWTR_EL2_OSECCR_EL1 |
+ HDFGWTR_EL2_OSLAR_EL1 |
+ HDFGWTR_EL2_DBGPRCR_EL1 |
+ HDFGWTR_EL2_DBGCLAIM |
+ HDFGWTR_EL2_MDSCR_EL1 |
+ HDFGWTR_EL2_DBGWVRn_EL1 |
+ HDFGWTR_EL2_DBGWCRn_EL1 |
+ HDFGWTR_EL2_DBGBVRn_EL1 |
+ HDFGWTR_EL2_DBGBCRn_EL1,
+ NEVER_FGU, FEAT_AA64EL1),
NEEDS_FEAT(HDFGWTR_EL2_TRFCR_EL1, FEAT_TRF),
};
@@ -556,38 +556,38 @@ static const struct reg_bits_to_feat_map hfgitr_feat_map[] = {
HFGITR_EL2_ATS1E1RP,
FEAT_PAN2),
NEEDS_FEAT(HFGITR_EL2_DCCVADP, FEAT_DPB2),
- NEEDS_FEAT(HFGITR_EL2_DCCVAC |
- HFGITR_EL2_SVC_EL1 |
- HFGITR_EL2_SVC_EL0 |
- HFGITR_EL2_ERET |
- HFGITR_EL2_TLBIVAALE1 |
- HFGITR_EL2_TLBIVALE1 |
- HFGITR_EL2_TLBIVAAE1 |
- HFGITR_EL2_TLBIASIDE1 |
- HFGITR_EL2_TLBIVAE1 |
- HFGITR_EL2_TLBIVMALLE1 |
- HFGITR_EL2_TLBIVAALE1IS |
- HFGITR_EL2_TLBIVALE1IS |
- HFGITR_EL2_TLBIVAAE1IS |
- HFGITR_EL2_TLBIASIDE1IS |
- HFGITR_EL2_TLBIVAE1IS |
- HFGITR_EL2_TLBIVMALLE1IS |
- HFGITR_EL2_ATS1E0W |
- HFGITR_EL2_ATS1E0R |
- HFGITR_EL2_ATS1E1W |
- HFGITR_EL2_ATS1E1R |
- HFGITR_EL2_DCZVA |
- HFGITR_EL2_DCCIVAC |
- HFGITR_EL2_DCCVAP |
- HFGITR_EL2_DCCVAU |
- HFGITR_EL2_DCCISW |
- HFGITR_EL2_DCCSW |
- HFGITR_EL2_DCISW |
- HFGITR_EL2_DCIVAC |
- HFGITR_EL2_ICIVAU |
- HFGITR_EL2_ICIALLU |
- HFGITR_EL2_ICIALLUIS,
- FEAT_AA64EL1),
+ NEEDS_FEAT_FLAG(HFGITR_EL2_DCCVAC |
+ HFGITR_EL2_SVC_EL1 |
+ HFGITR_EL2_SVC_EL0 |
+ HFGITR_EL2_ERET |
+ HFGITR_EL2_TLBIVAALE1 |
+ HFGITR_EL2_TLBIVALE1 |
+ HFGITR_EL2_TLBIVAAE1 |
+ HFGITR_EL2_TLBIASIDE1 |
+ HFGITR_EL2_TLBIVAE1 |
+ HFGITR_EL2_TLBIVMALLE1 |
+ HFGITR_EL2_TLBIVAALE1IS |
+ HFGITR_EL2_TLBIVALE1IS |
+ HFGITR_EL2_TLBIVAAE1IS |
+ HFGITR_EL2_TLBIASIDE1IS |
+ HFGITR_EL2_TLBIVAE1IS |
+ HFGITR_EL2_TLBIVMALLE1IS|
+ HFGITR_EL2_ATS1E0W |
+ HFGITR_EL2_ATS1E0R |
+ HFGITR_EL2_ATS1E1W |
+ HFGITR_EL2_ATS1E1R |
+ HFGITR_EL2_DCZVA |
+ HFGITR_EL2_DCCIVAC |
+ HFGITR_EL2_DCCVAP |
+ HFGITR_EL2_DCCVAU |
+ HFGITR_EL2_DCCISW |
+ HFGITR_EL2_DCCSW |
+ HFGITR_EL2_DCISW |
+ HFGITR_EL2_DCIVAC |
+ HFGITR_EL2_ICIVAU |
+ HFGITR_EL2_ICIALLU |
+ HFGITR_EL2_ICIALLUIS,
+ NEVER_FGU, FEAT_AA64EL1),
};
static const struct reg_bits_to_feat_map hafgrtr_feat_map[] = {
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 157de0ace6e7e..28dc778d0d9bb 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1946,6 +1946,12 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
if ((hw_val & mpam_mask) == (user_val & mpam_mask))
user_val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
+ /* Fail the guest's request to disable the AA64 ISA at EL{0,1,2} */
+ if (!FIELD_GET(ID_AA64PFR0_EL1_EL0, user_val) ||
+ !FIELD_GET(ID_AA64PFR0_EL1_EL1, user_val) ||
+ (vcpu_has_nv(vcpu) && !FIELD_GET(ID_AA64PFR0_EL1_EL2, user_val)))
+ return -EINVAL;
+
return set_id_reg(vcpu, rd, user_val);
}
diff --git a/tools/testing/selftests/kvm/arm64/set_id_regs.c b/tools/testing/selftests/kvm/arm64/set_id_regs.c
index 322b9d3b01255..57708de2075df 100644
--- a/tools/testing/selftests/kvm/arm64/set_id_regs.c
+++ b/tools/testing/selftests/kvm/arm64/set_id_regs.c
@@ -129,10 +129,10 @@ static const struct reg_ftr_bits ftr_id_aa64pfr0_el1[] = {
REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR0_EL1, DIT, 0),
REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR0_EL1, SEL2, 0),
REG_FTR_BITS(FTR_EXACT, ID_AA64PFR0_EL1, GIC, 0),
- REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR0_EL1, EL3, 0),
- REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR0_EL1, EL2, 0),
- REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR0_EL1, EL1, 0),
- REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR0_EL1, EL0, 0),
+ REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR0_EL1, EL3, 1),
+ REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR0_EL1, EL2, 1),
+ REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR0_EL1, EL1, 1),
+ REG_FTR_BITS(FTR_LOWER_SAFE, ID_AA64PFR0_EL1, EL0, 1),
REG_FTR_END,
};