mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
ANDROID: arm64: kvm: Hide asym aarch32 systems from KVM
KVM is not allowed when CONFIG_ASYMMETRIC_AARCH32 is enabled. But there's a desire to allow the 2 configs to coexist for Android GKI so that Protected KVM and this feature can both be enabled. The approach taken here is to simply make sure KVM doesn't see the asymmetry and hope for the best. It's not a bulletproof solution since ERET can still cause a return to aarch32. There's very little we can do anyway and we assume upper layer have to cooperate to guarantee correctness. Tested on FVP by booting the same kernel via qemu and attempting to run a 32bit statically linked binary. The host can run the app fine but the guest wasn't able to recognize the binary and run it. Which is the expected behavior. Bug: 168847043 Reason: Needed for bringup. Revert when upstream patch is available Signed-off-by: Qais Yousef <qais.yousef@arm.com> Change-Id: I2fc639815632567d0a4697b184ded03392dd572d
This commit is contained in:
@@ -590,6 +590,15 @@ static inline bool system_supports_32bit_el0(void)
|
||||
return cpus_have_const_cap(ARM64_HAS_32BIT_EL0);
|
||||
}
|
||||
|
||||
static inline bool kvm_system_supports_32bit_el0(void)
|
||||
{
|
||||
#ifndef CONFIG_ASYMMETRIC_AARCH32
|
||||
return system_supports_32bit_el0();
|
||||
#else
|
||||
return cpumask_equal(&aarch32_el0_mask, cpu_possible_mask);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool system_supports_4kb_granule(void)
|
||||
{
|
||||
u64 mmfr0;
|
||||
|
||||
@@ -226,7 +226,7 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
|
||||
u64 mode = (*(u64 *)valp) & PSR_AA32_MODE_MASK;
|
||||
switch (mode) {
|
||||
case PSR_AA32_MODE_USR:
|
||||
if (!system_supports_32bit_el0())
|
||||
if (!kvm_system_supports_32bit_el0())
|
||||
return -EINVAL;
|
||||
break;
|
||||
case PSR_AA32_MODE_FIQ:
|
||||
|
||||
@@ -670,7 +670,7 @@ static void reset_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
|
||||
*/
|
||||
val = ((pmcr & ~ARMV8_PMU_PMCR_MASK)
|
||||
| (ARMV8_PMU_PMCR_MASK & 0xdecafbad)) & (~ARMV8_PMU_PMCR_E);
|
||||
if (!system_supports_32bit_el0())
|
||||
if (!kvm_system_supports_32bit_el0())
|
||||
val |= ARMV8_PMU_PMCR_LC;
|
||||
__vcpu_sys_reg(vcpu, r->reg) = val;
|
||||
}
|
||||
@@ -722,7 +722,7 @@ static bool access_pmcr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
|
||||
val = __vcpu_sys_reg(vcpu, PMCR_EL0);
|
||||
val &= ~ARMV8_PMU_PMCR_MASK;
|
||||
val |= p->regval & ARMV8_PMU_PMCR_MASK;
|
||||
if (!system_supports_32bit_el0())
|
||||
if (!kvm_system_supports_32bit_el0())
|
||||
val |= ARMV8_PMU_PMCR_LC;
|
||||
__vcpu_sys_reg(vcpu, PMCR_EL0) = val;
|
||||
kvm_pmu_handle_pmcr(vcpu, val);
|
||||
@@ -1131,6 +1131,15 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
|
||||
if (!(val & (0xfUL << ID_AA64PFR0_CSV2_SHIFT)) &&
|
||||
arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED)
|
||||
val |= (1UL << ID_AA64PFR0_CSV2_SHIFT);
|
||||
|
||||
if (!kvm_system_supports_32bit_el0()) {
|
||||
/*
|
||||
* We could be running on asym aarch32 system.
|
||||
* Override to present a aarch64 only system.
|
||||
*/
|
||||
val &= ~(0xfUL << ID_AA64PFR0_EL0_SHIFT);
|
||||
val |= (ID_AA64PFR0_EL0_64BIT_ONLY << ID_AA64PFR0_EL0_SHIFT);
|
||||
}
|
||||
} else if (id == SYS_ID_AA64PFR1_EL1) {
|
||||
val &= ~(0xfUL << ID_AA64PFR1_MTE_SHIFT);
|
||||
} else if (id == SYS_ID_AA64ISAR1_EL1 && !vcpu_has_ptrauth(vcpu)) {
|
||||
|
||||
Reference in New Issue
Block a user