UPSTREAM: KVM: arm64: Stop handle_exit() from handling HVC twice when an SError occurs

Prior to commit defe21f49b ("KVM: arm64: Move PC rollback on SError to
HYP"), when an SError is synchronised due to another exception, KVM
handles the SError first. If the guest survives, the instruction that
triggered the original exception is re-exectued to handle the first
exception. HVC is treated as a special case as the instruction wouldn't
normally be re-exectued, as its not a trap.

Commit defe21f49b didn't preserve the behaviour of the 'return 1'
that skips the rest of handle_exit().

Since commit defe21f49b, KVM will try to handle the SError and the
original exception at the same time. When the exception was an HVC,
fixup_guest_exit() has already rolled back ELR_EL2, meaning if the
guest has virtual SError masked, it will execute and handle the HVC
twice.

Restore the original behaviour.

Bug: 254441685
Fixes: defe21f49b ("KVM: arm64: Move PC rollback on SError to HYP")
Cc: stable@vger.kernel.org
Signed-off-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20220127122052.1584324-4-james.morse@arm.com
(cherry picked from commit 1229630af8)
Signed-off-by: Lee Jones <joneslee@google.com>
Change-Id: Ie3ba170f6aa453c8e1ae2941d1baf8e9340b300b
This commit is contained in:
James Morse
2022-01-27 12:20:51 +00:00
committed by Lee Jones
parent 62e7b5a95c
commit 8318510708

View File

@@ -240,6 +240,14 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index)
{
struct kvm_run *run = vcpu->run;
if (ARM_SERROR_PENDING(exception_index)) {
/*
* The SError is handled by handle_exit_early(). If the guest
* survives it will re-execute the original instruction.
*/
return 1;
}
exception_index = ARM_EXCEPTION_CODE(exception_index);
switch (exception_index) {