aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGautham R. Shenoy <ego@linux.vnet.ibm.com>2015-10-15 01:59:58 -0400
committerPaul Mackerras <paulus@samba.org>2015-10-21 01:31:52 -0400
commit70aa3961a196ac32baf54032b2051bac9a941118 (patch)
treec014c098d5c8b98906a4d2a0e80a47a08375a020
parentbfec5c2cc0adad3b343281eb4f9b94222c5f594f (diff)
KVM: PPC: Book3S HV: Handle H_DOORBELL on the guest exit path
Currently a CPU running a guest can receive a H_DOORBELL in the following two cases: 1) When the CPU is napping due to CEDE or there not being a guest vcpu. 2) The CPU is running the guest vcpu. Case 1), the doorbell message is not cleared since we were waking up from nap. Hence when the EE bit gets set on transition from guest to host, the H_DOORBELL interrupt is delivered to the host and the corresponding handler is invoked. However in Case 2), the message gets cleared by the action of taking the H_DOORBELL interrupt. Since the CPU was running a guest, instead of invoking the doorbell handler, the code invokes the second-level interrupt handler to switch the context from the guest to the host. At this point the setting of the EE bit doesn't result in the CPU getting the doorbell interrupt since it has already been delivered once. So, the handler for this doorbell is never invoked! This causes softlockups if the missed DOORBELL was an IPI sent from a sibling subcore on the same CPU. This patch fixes it by explitly invoking the doorbell handler on the exit path if the exit reason is H_DOORBELL similar to the way an EXTERNAL interrupt is handled. Since this will also handle Case 1), we can unconditionally clear the doorbell message in kvmppc_check_wake_reason. Signed-off-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S17
1 files changed, 14 insertions, 3 deletions
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index fb8d29650612..b1dab8d1d885 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -150,6 +150,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
150 cmpwi cr1, r12, BOOK3S_INTERRUPT_MACHINE_CHECK 150 cmpwi cr1, r12, BOOK3S_INTERRUPT_MACHINE_CHECK
151 cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL 151 cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
152 beq 11f 152 beq 11f
153 cmpwi r12, BOOK3S_INTERRUPT_H_DOORBELL
154 beq 15f /* Invoke the H_DOORBELL handler */
153 cmpwi cr2, r12, BOOK3S_INTERRUPT_HMI 155 cmpwi cr2, r12, BOOK3S_INTERRUPT_HMI
154 beq cr2, 14f /* HMI check */ 156 beq cr2, 14f /* HMI check */
155 157
@@ -174,6 +176,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
174 mtspr SPRN_HSRR1, r7 176 mtspr SPRN_HSRR1, r7
175 b hmi_exception_after_realmode 177 b hmi_exception_after_realmode
176 178
17915: mtspr SPRN_HSRR0, r8
180 mtspr SPRN_HSRR1, r7
181 ba 0xe80
182
177kvmppc_primary_no_guest: 183kvmppc_primary_no_guest:
178 /* We handle this much like a ceded vcpu */ 184 /* We handle this much like a ceded vcpu */
179 /* put the HDEC into the DEC, since HDEC interrupts don't wake us */ 185 /* put the HDEC into the DEC, since HDEC interrupts don't wake us */
@@ -2440,14 +2446,19 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
2440 2446
2441 /* hypervisor doorbell */ 2447 /* hypervisor doorbell */
24423: li r12, BOOK3S_INTERRUPT_H_DOORBELL 24483: li r12, BOOK3S_INTERRUPT_H_DOORBELL
2449
2450 /*
2451 * Clear the doorbell as we will invoke the handler
2452 * explicitly in the guest exit path.
2453 */
2454 lis r6, (PPC_DBELL_SERVER << (63-36))@h
2455 PPC_MSGCLR(6)
2443 /* see if it's a host IPI */ 2456 /* see if it's a host IPI */
2444 li r3, 1 2457 li r3, 1
2445 lbz r0, HSTATE_HOST_IPI(r13) 2458 lbz r0, HSTATE_HOST_IPI(r13)
2446 cmpwi r0, 0 2459 cmpwi r0, 0
2447 bnelr 2460 bnelr
2448 /* if not, clear it and return -1 */ 2461 /* if not, return -1 */
2449 lis r6, (PPC_DBELL_SERVER << (63-36))@h
2450 PPC_MSGCLR(6)
2451 li r3, -1 2462 li r3, -1
2452 blr 2463 blr
2453 2464