aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/include/asm/kvm_arm.h8
-rw-r--r--arch/arm64/kvm/Kconfig1
-rw-r--r--arch/arm64/kvm/handle_exit.c18
3 files changed, 20 insertions, 7 deletions
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index a5f28e2720c7..c98ef4771c73 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -63,6 +63,7 @@
63 * TAC: Trap ACTLR 63 * TAC: Trap ACTLR
64 * TSC: Trap SMC 64 * TSC: Trap SMC
65 * TSW: Trap cache operations by set/way 65 * TSW: Trap cache operations by set/way
66 * TWE: Trap WFE
66 * TWI: Trap WFI 67 * TWI: Trap WFI
67 * TIDCP: Trap L2CTLR/L2ECTLR 68 * TIDCP: Trap L2CTLR/L2ECTLR
68 * BSU_IS: Upgrade barriers to the inner shareable domain 69 * BSU_IS: Upgrade barriers to the inner shareable domain
@@ -72,8 +73,9 @@
72 * FMO: Override CPSR.F and enable signaling with VF 73 * FMO: Override CPSR.F and enable signaling with VF
73 * SWIO: Turn set/way invalidates into set/way clean+invalidate 74 * SWIO: Turn set/way invalidates into set/way clean+invalidate
74 */ 75 */
75#define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWI | HCR_VM | HCR_BSU_IS | \ 76#define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \
76 HCR_FB | HCR_TAC | HCR_AMO | HCR_IMO | HCR_FMO | \ 77 HCR_BSU_IS | HCR_FB | HCR_TAC | \
78 HCR_AMO | HCR_IMO | HCR_FMO | \
77 HCR_SWIO | HCR_TIDCP | HCR_RW) 79 HCR_SWIO | HCR_TIDCP | HCR_RW)
78#define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF) 80#define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF)
79 81
@@ -242,4 +244,6 @@
242 244
243#define ESR_EL2_EC_xABT_xFSR_EXTABT 0x10 245#define ESR_EL2_EC_xABT_xFSR_EXTABT 0x10
244 246
247#define ESR_EL2_EC_WFI_ISS_WFE (1 << 0)
248
245#endif /* __ARM64_KVM_ARM_H__ */ 249#endif /* __ARM64_KVM_ARM_H__ */
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 21e90820bd23..4480ab339a00 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -21,6 +21,7 @@ config KVM
21 select MMU_NOTIFIER 21 select MMU_NOTIFIER
22 select PREEMPT_NOTIFIERS 22 select PREEMPT_NOTIFIERS
23 select ANON_INODES 23 select ANON_INODES
24 select HAVE_KVM_CPU_RELAX_INTERCEPT
24 select KVM_MMIO 25 select KVM_MMIO
25 select KVM_ARM_HOST 26 select KVM_ARM_HOST
26 select KVM_ARM_VGIC 27 select KVM_ARM_VGIC
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,