arm64: hyp/kvm: Make hyp-stub reject kvm_call_hyp()
A later patch implements kvm_arch_hardware_disable(), to remove kvm from el2, and re-instate the hyp-stub. This can happen while guests are running, particularly when kvm_reboot() calls kvm_arch_hardware_disable() on each cpu. This can interrupt a guest, remove kvm, then allow the guest to be scheduled again. This causes kvm_call_hyp() to be run against the hyp-stub. Change the hyp-stub to return a new exception type when this happens, and add code to kvm's handle_exit() to tell userspace we failed to enter the guest. Signed-off-by: James Morse <james.morse@arm.com> Acked-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:
parent
ad72e59ff2
commit
c94b0cf282
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#define ARM_EXCEPTION_IRQ 0
|
#define ARM_EXCEPTION_IRQ 0
|
||||||
#define ARM_EXCEPTION_TRAP 1
|
#define ARM_EXCEPTION_TRAP 1
|
||||||
|
/* The hyp-stub will return this for any kvm_call_hyp() call */
|
||||||
|
#define ARM_EXCEPTION_HYP_GONE 2
|
||||||
|
|
||||||
#define KVM_ARM64_DEBUG_DIRTY_SHIFT 0
|
#define KVM_ARM64_DEBUG_DIRTY_SHIFT 0
|
||||||
#define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT)
|
#define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT)
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <asm/assembler.h>
|
#include <asm/assembler.h>
|
||||||
#include <asm/kvm_arm.h>
|
#include <asm/kvm_arm.h>
|
||||||
|
#include <asm/kvm_asm.h>
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
#include <asm/virt.h>
|
#include <asm/virt.h>
|
||||||
|
|
||||||
@ -70,8 +71,8 @@ el1_sync:
|
|||||||
msr vbar_el2, x1
|
msr vbar_el2, x1
|
||||||
b 9f
|
b 9f
|
||||||
|
|
||||||
/* Unrecognised call type */
|
/* Someone called kvm_call_hyp() against the hyp-stub... */
|
||||||
2: mov x0, xzr
|
2: mov x0, #ARM_EXCEPTION_HYP_GONE
|
||||||
|
|
||||||
9: eret
|
9: eret
|
||||||
ENDPROC(el1_sync)
|
ENDPROC(el1_sync)
|
||||||
|
@ -186,6 +186,13 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
|
|||||||
exit_handler = kvm_get_exit_handler(vcpu);
|
exit_handler = kvm_get_exit_handler(vcpu);
|
||||||
|
|
||||||
return exit_handler(vcpu, run);
|
return exit_handler(vcpu, run);
|
||||||
|
case ARM_EXCEPTION_HYP_GONE:
|
||||||
|
/*
|
||||||
|
* EL2 has been reset to the hyp-stub. This happens when a guest
|
||||||
|
* is pre-empted by kvm_reboot()'s shutdown call.
|
||||||
|
*/
|
||||||
|
run->exit_reason = KVM_EXIT_FAIL_ENTRY;
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
kvm_pr_unimpl("Unsupported exception type: %d",
|
kvm_pr_unimpl("Unsupported exception type: %d",
|
||||||
exception_index);
|
exception_index);
|
||||||
|
Loading…
Reference in New Issue
Block a user