diff options
author | Oliver Upton <oliver.upton@linux.dev> | 2024-03-07 03:45:24 +0300 |
---|---|---|
committer | Oliver Upton <oliver.upton@linux.dev> | 2024-03-07 03:45:24 +0300 |
commit | 262cd16e769f0c75353bd2521da756e45837e051 (patch) | |
tree | c9420e445d9556751c81cb8f80fd085301dcec7e /arch/arm64/include | |
parent | 6613476e225e090cc9aad49be7fa504e290dd33d (diff) | |
parent | 9aa030cee1c45d6e962f6bf22ba63d4aff2b1644 (diff) | |
download | linux-262cd16e769f0c75353bd2521da756e45837e051.tar.xz |
Merge branch kvm-arm64/feat_e2h0 into kvmarm/next
* kvm-arm64/feat_e2h0:
: Support for FEAT_E2H0, courtesy of Marc Zyngier
:
: As described in the cover letter:
:
: Since ARMv8.1, the architecture has grown the VHE feature, which makes
: EL2 a superset of EL1. With ARMv9.5 (and retroactively allowed from
: ARMv8.1), the architecture allows implementations to have VHE as the
: *only* implemented behaviour, meaning that HCR_EL2.E2H can be
: implemented as RES1. As a follow-up, HCR_EL2.NV1 can also be
: implemented as RES0, making the VHE-ness of the architecture
: recursive.
:
: This series adds support for detecting the architectural feature of E2H
: being RES1, leveraging the existing infrastructure for handling
: out-of-spec CPUs that are VHE-only. Additionally, the (incomplete) NV
: infrastructure in KVM is updated to enforce E2H=1 for guest hypervisors
: on implementations that do not support NV1.
arm64: cpufeatures: Fix FEAT_NV check when checking for FEAT_NV1
arm64: cpufeatures: Only check for NV1 if NV is present
arm64: cpufeatures: Add missing ID_AA64MMFR4_EL1 to __read_sysreg_by_encoding()
KVM: arm64: Handle Apple M2 as not having HCR_EL2.NV1 implemented
KVM: arm64: Force guest's HCR_EL2.E2H RES1 when NV1 is not implemented
KVM: arm64: Expose ID_AA64MMFR4_EL1 to guests
arm64: Treat HCR_EL2.E2H as RES1 when ID_AA64MMFR4_EL1.E2H0 is negative
arm64: cpufeature: Detect HCR_EL2.NV1 being RES0
arm64: cpufeature: Add ID_AA64MMFR4_EL1 handling
arm64: sysreg: Add layout for ID_AA64MMFR4_EL1
arm64: cpufeature: Correctly display signed override values
arm64: cpufeatures: Correctly handle signed values
arm64: Add macro to compose a sysreg field value
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Diffstat (limited to 'arch/arm64/include')
-rw-r--r-- | arch/arm64/include/asm/cpu.h | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/cpufeature.h | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/kvm_emulate.h | 3 | ||||
-rw-r--r-- | arch/arm64/include/asm/sysreg.h | 5 |
4 files changed, 8 insertions, 2 deletions
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h index b1e43f56ee46..6c13fd47e170 100644 --- a/arch/arm64/include/asm/cpu.h +++ b/arch/arm64/include/asm/cpu.h @@ -56,6 +56,7 @@ struct cpuinfo_arm64 { u64 reg_id_aa64mmfr1; u64 reg_id_aa64mmfr2; u64 reg_id_aa64mmfr3; + u64 reg_id_aa64mmfr4; u64 reg_id_aa64pfr0; u64 reg_id_aa64pfr1; u64 reg_id_aa64zfr0; diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 21c824edf8ce..a98d95f3492b 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -363,6 +363,7 @@ struct arm64_cpu_capabilities { u8 field_pos; u8 field_width; u8 min_field_value; + u8 max_field_value; u8 hwcap_type; bool sign; unsigned long hwcap; diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index b804fe832184..debc3753d2ef 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -209,7 +209,8 @@ static inline bool vcpu_is_el2(const struct kvm_vcpu *vcpu) static inline bool __vcpu_el2_e2h_is_set(const struct kvm_cpu_context *ctxt) { - return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H; + return (!cpus_have_final_cap(ARM64_HAS_HCR_NV1) || + (ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H)); } static inline bool vcpu_el2_e2h_is_set(const struct kvm_vcpu *vcpu) diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index c3b19b376c86..9e8999592f3a 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -1181,6 +1181,8 @@ par; \ }) +#define SYS_FIELD_VALUE(reg, field, val) reg##_##field##_##val + #define SYS_FIELD_GET(reg, field, val) \ FIELD_GET(reg##_##field##_MASK, val) @@ -1188,7 +1190,8 @@ FIELD_PREP(reg##_##field##_MASK, val) #define SYS_FIELD_PREP_ENUM(reg, field, val) \ - FIELD_PREP(reg##_##field##_MASK, reg##_##field##_##val) + FIELD_PREP(reg##_##field##_MASK, \ + SYS_FIELD_VALUE(reg, field, val)) #endif |