aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kvm/handle_exit.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/kvm/handle_exit.c')
-rw-r--r--arch/arm64/kvm/handle_exit.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 9beaca033437..8da56067c304 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -47,21 +47,29 @@ static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
47} 47}
48 48
49/** 49/**
50 * kvm_handle_wfi - handle a wait-for-interrupts instruction executed by a guest 50 * kvm_handle_wfx - handle a wait-for-interrupts or wait-for-event
51 * instruction executed by a guest
52 *
51 * @vcpu: the vcpu pointer 53 * @vcpu: the vcpu pointer
52 * 54 *
53 * Simply call kvm_vcpu_block(), which will halt execution of 55 * WFE: Yield the CPU and come back to this vcpu when the scheduler
56 * decides to.
57 * WFI: Simply call kvm_vcpu_block(), which will halt execution of
54 * world-switches and schedule other host processes until there is an 58 * world-switches and schedule other host processes until there is an
55 * incoming IRQ or FIQ to the VM. 59 * incoming IRQ or FIQ to the VM.
56 */ 60 */
57static int kvm_handle_wfi(struct kvm_vcpu *vcpu, struct kvm_run *run) 61static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run)
58{ 62{
59 kvm_vcpu_block(vcpu); 63 if (kvm_vcpu_get_hsr(vcpu) & ESR_EL2_EC_WFI_ISS_WFE)
64 kvm_vcpu_on_spin(vcpu);
65 else
66 kvm_vcpu_block(vcpu);
67
60 return 1; 68 return 1;
61} 69}
62 70
63static exit_handle_fn arm_exit_handlers[] = { 71static exit_handle_fn arm_exit_handlers[] = {
64 [ESR_EL2_EC_WFI] = kvm_handle_wfi, 72 [ESR_EL2_EC_WFI] = kvm_handle_wfx,
65 [ESR_EL2_EC_CP15_32] = kvm_handle_cp15_32, 73 [ESR_EL2_EC_CP15_32] = kvm_handle_cp15_32,
66 [ESR_EL2_EC_CP15_64] = kvm_handle_cp15_64, 74 [ESR_EL2_EC_CP15_64] = kvm_handle_cp15_64,
67 [ESR_EL2_EC_CP14_MR] = kvm_handle_cp14_access, 75 [ESR_EL2_EC_CP14_MR] = kvm_handle_cp14_access,