arm64: cpufeature: Add CPU capability for AArch32 EL1 support
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. Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Acked-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20200421142922.18950-4-will@kernel.org Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
0113340e6e
commit
540f76d12c
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue