Although we emit a "SANITY CHECK" warning and taint the kernel if we
detect a CPU mismatch for AArch32 support at EL1, we still online the
CPU with disastrous consequences for any running 32-bit VMs.

Introduce a capability for AArch32 support at EL1 so that late onlining
of incompatible CPUs is forbidden.

Acked-by: Marc Zyngier <[email protected]>
Reviewed-by: Suzuki K Poulose <[email protected]>
Tested-by: Sai Prakash Ranjan <[email protected]>
Signed-off-by: Will Deacon <[email protected]>
---
 arch/arm64/include/asm/cpucaps.h |  3 ++-
 arch/arm64/include/asm/sysreg.h  |  1 +
 arch/arm64/kernel/cpufeature.c   | 12 ++++++++++++
 arch/arm64/kvm/reset.c           | 12 ++----------
 4 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 8eb5a088ae65..c54c674e6c21 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -61,7 +61,8 @@
 #define ARM64_HAS_AMU_EXTN                     51
 #define ARM64_HAS_ADDRESS_AUTH                 52
 #define ARM64_HAS_GENERIC_AUTH                 53
+#define ARM64_HAS_32BIT_EL1                    54
 
-#define ARM64_NCAPS                            54
+#define ARM64_NCAPS                            55
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index d7181972d28d..c4e896bf77f3 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -655,6 +655,7 @@
 #define ID_AA64PFR0_ASIMD_NI           0xf
 #define ID_AA64PFR0_ASIMD_SUPPORTED    0x0
 #define ID_AA64PFR0_EL1_64BIT_ONLY     0x1
+#define ID_AA64PFR0_EL1_32BIT_64BIT    0x2
 #define ID_AA64PFR0_EL0_64BIT_ONLY     0x1
 #define ID_AA64PFR0_EL0_32BIT_64BIT    0x2
 
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index b143f8bc6c52..838fe5cc8d7e 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1535,6 +1535,18 @@ static const struct arm64_cpu_capabilities 
arm64_features[] = {
                .field_pos = ID_AA64PFR0_EL0_SHIFT,
                .min_field_value = ID_AA64PFR0_EL0_32BIT_64BIT,
        },
+#ifdef CONFIG_KVM
+       {
+               .desc = "32-bit EL1 Support",
+               .capability = ARM64_HAS_32BIT_EL1,
+               .type = ARM64_CPUCAP_SYSTEM_FEATURE,
+               .matches = has_cpuid_feature,
+               .sys_reg = SYS_ID_AA64PFR0_EL1,
+               .sign = FTR_UNSIGNED,
+               .field_pos = ID_AA64PFR0_EL1_SHIFT,
+               .min_field_value = ID_AA64PFR0_EL1_32BIT_64BIT,
+       },
+#endif
        {
                .desc = "Kernel page table isolation (KPTI)",
                .capability = ARM64_UNMAP_KERNEL_AT_EL0,
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 30b7ea680f66..102e5c4e01a0 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -46,14 +46,6 @@ static const struct kvm_regs default_regs_reset32 = {
                        PSR_AA32_I_BIT | PSR_AA32_F_BIT),
 };
 
-static bool cpu_has_32bit_el1(void)
-{
-       u64 pfr0;
-
-       pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
-       return !!(pfr0 & 0x20);
-}
-
 /**
  * kvm_arch_vm_ioctl_check_extension
  *
@@ -66,7 +58,7 @@ int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long 
ext)
 
        switch (ext) {
        case KVM_CAP_ARM_EL1_32BIT:
-               r = cpu_has_32bit_el1();
+               r = cpus_have_const_cap(ARM64_HAS_32BIT_EL1);
                break;
        case KVM_CAP_GUEST_DEBUG_HW_BPS:
                r = get_num_brps();
@@ -288,7 +280,7 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
        switch (vcpu->arch.target) {
        default:
                if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) {
-                       if (!cpu_has_32bit_el1())
+                       if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1))
                                goto out;
                        cpu_reset = &default_regs_reset32;
                } else {
-- 
2.26.1.301.g55bc3eb7cb9-goog

_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to