Message ID | 20220811170221.3771048-2-oliver.upton@linux.dev (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: arm64: Uphold 64bit-only behavior on asymmetric systems | expand |
On Thu, Aug 11, 2022 at 05:02:20PM +0000, Oliver Upton wrote: > KVM does not support AArch32 on asymmetric systems. To that end, enforce > AArch64-only behavior on PMCR_EL1.LC when on an asymmetric system. > > Fixes: 2122a833316f ("arm64: Allow mismatched 32-bit EL0 support") > Signed-off-by: Oliver Upton <oliver.upton@linux.dev> > --- > arch/arm64/include/asm/kvm_host.h | 4 ++++ > arch/arm64/kvm/arm.c | 3 +-- > arch/arm64/kvm/sys_regs.c | 4 ++-- > 3 files changed, 7 insertions(+), 4 deletions(-) > > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h > index f38ef299f13b..e9c9388ccc02 100644 > --- a/arch/arm64/include/asm/kvm_host.h > +++ b/arch/arm64/include/asm/kvm_host.h > @@ -929,6 +929,10 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu); > (system_supports_mte() && \ > test_bit(KVM_ARCH_FLAG_MTE_ENABLED, &(kvm)->arch.flags)) > > +#define kvm_supports_32bit_el0() \ > + (system_supports_32bit_el0() && \ > + !static_branch_unlikely(&arm64_mismatched_32bit_el0)) > + > int kvm_trng_call(struct kvm_vcpu *vcpu); > #ifdef CONFIG_KVM > extern phys_addr_t hyp_mem_base; > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c > index 986cee6fbc7f..bef3849c564f 100644 > --- a/arch/arm64/kvm/arm.c > +++ b/arch/arm64/kvm/arm.c > @@ -757,8 +757,7 @@ static bool vcpu_mode_is_bad_32bit(struct kvm_vcpu *vcpu) > if (likely(!vcpu_mode_is_32bit(vcpu))) > return false; > > - return !system_supports_32bit_el0() || > - static_branch_unlikely(&arm64_mismatched_32bit_el0); > + return kvm_supports_32bit_el0(); Lol, promised this was lightly tested :) Read the patch once more, this will need to be: return !kvm_supports_32bit_el0(); I'll fix it in v2 but will wait a bit for folks to review. -- Thanks, Oliver > } > > /** > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c > index c059b259aea6..3234f50b8c4b 100644 > --- a/arch/arm64/kvm/sys_regs.c > +++ b/arch/arm64/kvm/sys_regs.c > @@ -652,7 +652,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_supports_32bit_el0()) > val |= ARMV8_PMU_PMCR_LC; > __vcpu_sys_reg(vcpu, r->reg) = val; > } > @@ -701,7 +701,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_supports_32bit_el0()) > val |= ARMV8_PMU_PMCR_LC; > __vcpu_sys_reg(vcpu, PMCR_EL0) = val; > kvm_pmu_handle_pmcr(vcpu, val); > -- > 2.37.1.559.g78731f0fdb-goog >
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index f38ef299f13b..e9c9388ccc02 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -929,6 +929,10 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu); (system_supports_mte() && \ test_bit(KVM_ARCH_FLAG_MTE_ENABLED, &(kvm)->arch.flags)) +#define kvm_supports_32bit_el0() \ + (system_supports_32bit_el0() && \ + !static_branch_unlikely(&arm64_mismatched_32bit_el0)) + int kvm_trng_call(struct kvm_vcpu *vcpu); #ifdef CONFIG_KVM extern phys_addr_t hyp_mem_base; diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 986cee6fbc7f..bef3849c564f 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -757,8 +757,7 @@ static bool vcpu_mode_is_bad_32bit(struct kvm_vcpu *vcpu) if (likely(!vcpu_mode_is_32bit(vcpu))) return false; - return !system_supports_32bit_el0() || - static_branch_unlikely(&arm64_mismatched_32bit_el0); + return kvm_supports_32bit_el0(); } /** diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index c059b259aea6..3234f50b8c4b 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -652,7 +652,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_supports_32bit_el0()) val |= ARMV8_PMU_PMCR_LC; __vcpu_sys_reg(vcpu, r->reg) = val; } @@ -701,7 +701,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_supports_32bit_el0()) val |= ARMV8_PMU_PMCR_LC; __vcpu_sys_reg(vcpu, PMCR_EL0) = val; kvm_pmu_handle_pmcr(vcpu, val);
KVM does not support AArch32 on asymmetric systems. To that end, enforce AArch64-only behavior on PMCR_EL1.LC when on an asymmetric system. Fixes: 2122a833316f ("arm64: Allow mismatched 32-bit EL0 support") Signed-off-by: Oliver Upton <oliver.upton@linux.dev> --- arch/arm64/include/asm/kvm_host.h | 4 ++++ arch/arm64/kvm/arm.c | 3 +-- arch/arm64/kvm/sys_regs.c | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-)