forked from Minki/linux
powerpc/book3s: Fix guest MC delivery mechanism to avoid soft lockups in guest.
Currently we forward MCEs to guest which have been recovered by guest. And for unhandled errors we do not deliver the MCE to guest. It looks like with no support of FWNMI in qemu, guest just panics whenever we deliver the recovered MCEs to guest. Also, the existig code used to return to host for unhandled errors which was casuing guest to hang with soft lockups inside guest and makes it difficult to recover guest instance. This patch now forwards all fatal MCEs to guest causing guest to crash/panic. And, for recovered errors we just go back to normal functioning of guest instead of returning to host. This fixes soft lockup issues in guest. This patch also fixes an issue where guest MCE events were not logged to host console. Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
parent
e6654d5b42
commit
74845bc2fa
@ -113,10 +113,8 @@ static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu)
|
||||
* We assume that if the condition is recovered then linux host
|
||||
* will have generated an error log event that we will pick
|
||||
* up and log later.
|
||||
* Don't release mce event now. In case if condition is not
|
||||
* recovered we do guest exit and go back to linux host machine
|
||||
* check handler. Hence we need make sure that current mce event
|
||||
* is available for linux host to consume.
|
||||
* Don't release mce event now. We will queue up the event so that
|
||||
* we can log the MCE event info on host console.
|
||||
*/
|
||||
if (!get_mce_event(&mce_evt, MCE_EVENT_DONTRELEASE))
|
||||
goto out;
|
||||
@ -128,11 +126,12 @@ static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu)
|
||||
|
||||
out:
|
||||
/*
|
||||
* If we have handled the error, then release the mce event because
|
||||
* we will be delivering machine check to guest.
|
||||
* We are now going enter guest either through machine check
|
||||
* interrupt (for unhandled errors) or will continue from
|
||||
* current HSRR0 (for handled errors) in guest. Hence
|
||||
* queue up the event so that we can log it from host console later.
|
||||
*/
|
||||
if (handled)
|
||||
release_mce_event();
|
||||
machine_check_queue_event();
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
@ -2257,15 +2257,28 @@ machine_check_realmode:
|
||||
mr r3, r9 /* get vcpu pointer */
|
||||
bl kvmppc_realmode_machine_check
|
||||
nop
|
||||
cmpdi r3, 0 /* continue exiting from guest? */
|
||||
cmpdi r3, 0 /* Did we handle MCE ? */
|
||||
ld r9, HSTATE_KVM_VCPU(r13)
|
||||
li r12, BOOK3S_INTERRUPT_MACHINE_CHECK
|
||||
beq mc_cont
|
||||
/*
|
||||
* Deliver unhandled/fatal (e.g. UE) MCE errors to guest through
|
||||
* machine check interrupt (set HSRR0 to 0x200). And for handled
|
||||
* errors (no-fatal), just go back to guest execution with current
|
||||
* HSRR0 instead of exiting guest. This new approach will inject
|
||||
* machine check to guest for fatal error causing guest to crash.
|
||||
*
|
||||
* The old code used to return to host for unhandled errors which
|
||||
* was causing guest to hang with soft lockups inside guest and
|
||||
* makes it difficult to recover guest instance.
|
||||
*/
|
||||
ld r10, VCPU_PC(r9)
|
||||
ld r11, VCPU_MSR(r9)
|
||||
bne 2f /* Continue guest execution. */
|
||||
/* If not, deliver a machine check. SRR0/1 are already set */
|
||||
li r10, BOOK3S_INTERRUPT_MACHINE_CHECK
|
||||
ld r11, VCPU_MSR(r9)
|
||||
bl kvmppc_msr_interrupt
|
||||
b fast_interrupt_c_return
|
||||
2: b fast_interrupt_c_return
|
||||
|
||||
/*
|
||||
* Check the reason we woke from nap, and take appropriate action.
|
||||
|
Loading…
Reference in New Issue
Block a user