mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 20:32:04 +09:00
KVM: arm64: AArch32: Fix spurious trapping of conditional instructions
commit c92e8b9eacebb4060634ebd9395bba1b29aadc68 upstream.
We recently upgraded the view of ESR_EL2 to 64bit, in keeping with
the requirements of the architecture.
However, the AArch32 emulation code was left unaudited, and the
(already dodgy) code that triages whether a trap is spurious or not
(because the condition code failed) broke in a subtle way:
If ESR_EL2.ISS2 is ever non-zero (unlikely, but hey, this is the ARM
architecture we're talking about), the hack that tests the top bits
of ESR_EL2.EC will break in an interesting way.
Instead, use kvm_vcpu_trap_get_class() to obtain the EC, and list
all the possible ECs that can fail a condition code check.
While we're at it, add SMC32 to the list, as it is explicitly listed
as being allowed to trap despite failing a condition code check (as
described in the HCR_EL2.TSC documentation).
Fixes: 0b12620fdd ("KVM: arm64: Treat ESR_EL2 as a 64-bit register")
Cc: stable@vger.kernel.org
Acked-by: Oliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20240524141956.1450304-4-maz@kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
5b12ce0b6f
commit
e0032f5c08
@@ -50,9 +50,23 @@ bool kvm_condition_valid32(const struct kvm_vcpu *vcpu)
|
|||||||
u32 cpsr_cond;
|
u32 cpsr_cond;
|
||||||
int cond;
|
int cond;
|
||||||
|
|
||||||
/* Top two bits non-zero? Unconditional. */
|
/*
|
||||||
if (kvm_vcpu_get_esr(vcpu) >> 30)
|
* These are the exception classes that could fire with a
|
||||||
|
* conditional instruction.
|
||||||
|
*/
|
||||||
|
switch (kvm_vcpu_trap_get_class(vcpu)) {
|
||||||
|
case ESR_ELx_EC_CP15_32:
|
||||||
|
case ESR_ELx_EC_CP15_64:
|
||||||
|
case ESR_ELx_EC_CP14_MR:
|
||||||
|
case ESR_ELx_EC_CP14_LS:
|
||||||
|
case ESR_ELx_EC_FP_ASIMD:
|
||||||
|
case ESR_ELx_EC_CP10_ID:
|
||||||
|
case ESR_ELx_EC_CP14_64:
|
||||||
|
case ESR_ELx_EC_SVC32:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Is condition field valid? */
|
/* Is condition field valid? */
|
||||||
cond = kvm_vcpu_get_condition(vcpu);
|
cond = kvm_vcpu_get_condition(vcpu);
|
||||||
|
|||||||
Reference in New Issue
Block a user