mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 10:29:37 +00:00
powerpc/book3s: Return from interrupt if coming from evil context.
We can get machine checks from any context. We need to make sure that we handle all of them correctly. If we are coming from hypervisor user-space, we can continue in host kernel in virtual mode to deliver the MC event. If we got woken up from power-saving mode then we may come in with one of the following state: a. No state loss b. Supervisor state loss c. Hypervisor state loss For (a) and (b), we go back to nap again. State (c) is fatal, keep spinning. For all other context which we not sure of queue up the MCE event and return from the interrupt. 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
1e9b4507ed
commit
1c51089f77
2 changed files with 83 additions and 0 deletions
|
@ -155,6 +155,24 @@ machine_check_pSeries_1:
|
|||
*/
|
||||
HMT_MEDIUM_PPR_DISCARD
|
||||
SET_SCRATCH0(r13) /* save r13 */
|
||||
#ifdef CONFIG_PPC_P7_NAP
|
||||
BEGIN_FTR_SECTION
|
||||
/* Running native on arch 2.06 or later, check if we are
|
||||
* waking up from nap. We only handle no state loss and
|
||||
* supervisor state loss. We do -not- handle hypervisor
|
||||
* state loss at this time.
|
||||
*/
|
||||
mfspr r13,SPRN_SRR1
|
||||
rlwinm. r13,r13,47-31,30,31
|
||||
beq 9f
|
||||
|
||||
/* waking up from powersave (nap) state */
|
||||
cmpwi cr1,r13,2
|
||||
/* Total loss of HV state is fatal. let's just stay stuck here */
|
||||
bgt cr1,.
|
||||
9:
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
|
||||
#endif /* CONFIG_PPC_P7_NAP */
|
||||
EXCEPTION_PROLOG_0(PACA_EXMC)
|
||||
BEGIN_FTR_SECTION
|
||||
b machine_check_pSeries_early
|
||||
|
@ -818,6 +836,70 @@ BEGIN_FTR_SECTION
|
|||
bl .save_nvgprs
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl .machine_check_early
|
||||
ld r12,_MSR(r1)
|
||||
#ifdef CONFIG_PPC_P7_NAP
|
||||
/*
|
||||
* Check if thread was in power saving mode. We come here when any
|
||||
* of the following is true:
|
||||
* a. thread wasn't in power saving mode
|
||||
* b. thread was in power saving mode with no state loss or
|
||||
* supervisor state loss
|
||||
*
|
||||
* Go back to nap again if (b) is true.
|
||||
*/
|
||||
rlwinm. r11,r12,47-31,30,31 /* Was it in power saving mode? */
|
||||
beq 4f /* No, it wasn;t */
|
||||
/* Thread was in power saving mode. Go back to nap again. */
|
||||
cmpwi r11,2
|
||||
bne 3f
|
||||
/* Supervisor state loss */
|
||||
li r0,1
|
||||
stb r0,PACA_NAPSTATELOST(r13)
|
||||
3: MACHINE_CHECK_HANDLER_WINDUP
|
||||
GET_PACA(r13)
|
||||
ld r1,PACAR1(r13)
|
||||
b .power7_enter_nap_mode
|
||||
4:
|
||||
#endif
|
||||
/*
|
||||
* Check if we are coming from hypervisor userspace. If yes then we
|
||||
* continue in host kernel in V mode to deliver the MC event.
|
||||
*/
|
||||
rldicl. r11,r12,4,63 /* See if MC hit while in HV mode. */
|
||||
beq 5f
|
||||
andi. r11,r12,MSR_PR /* See if coming from user. */
|
||||
bne 9f /* continue in V mode if we are. */
|
||||
|
||||
5:
|
||||
#ifdef CONFIG_KVM_BOOK3S_64_HV
|
||||
/*
|
||||
* We are coming from kernel context. Check if we are coming from
|
||||
* guest. if yes, then we can continue. We will fall through
|
||||
* do_kvm_200->kvmppc_interrupt to deliver the MC event to guest.
|
||||
*/
|
||||
lbz r11,HSTATE_IN_GUEST(r13)
|
||||
cmpwi r11,0 /* Check if coming from guest */
|
||||
bne 9f /* continue if we are. */
|
||||
#endif
|
||||
/*
|
||||
* At this point we are not sure about what context we come from.
|
||||
* Queue up the MCE event and return from the interrupt.
|
||||
* But before that, check if this is an un-recoverable exception.
|
||||
* If yes, then stay on emergency stack and panic.
|
||||
*/
|
||||
andi. r11,r12,MSR_RI
|
||||
bne 2f
|
||||
1: addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl .unrecoverable_exception
|
||||
b 1b
|
||||
2:
|
||||
/*
|
||||
* Return from MC interrupt.
|
||||
* TODO: Queue up the MCE event so that we can log it later.
|
||||
*/
|
||||
MACHINE_CHECK_HANDLER_WINDUP
|
||||
rfid
|
||||
9:
|
||||
/* Deliver the machine check to host kernel in V mode. */
|
||||
MACHINE_CHECK_HANDLER_WINDUP
|
||||
b machine_check_pSeries
|
||||
|
|
|
@ -84,6 +84,7 @@ _GLOBAL(power7_nap)
|
|||
std r9,_MSR(r1)
|
||||
std r1,PACAR1(r13)
|
||||
|
||||
_GLOBAL(power7_enter_nap_mode)
|
||||
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
|
||||
/* Tell KVM we're napping */
|
||||
li r4,KVM_HWTHREAD_IN_NAP
|
||||
|
|
Loading…
Reference in a new issue