aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>2013-10-30 10:34:31 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-12-05 00:04:36 -0500
commit1c51089f777bf357487668be9621292cfed752bd (patch)
tree6509fd5b46f95cbd78a74ee197a7f56c3587b120 /arch/powerpc/kernel
parent1e9b4507ed98457edb8a892934282b8f63e17246 (diff)
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>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S82
-rw-r--r--arch/powerpc/kernel/idle_power7.S1
2 files changed, 83 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 4034dfb2a530..1aec3025eeee 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -155,6 +155,24 @@ machine_check_pSeries_1:
155 */ 155 */
156 HMT_MEDIUM_PPR_DISCARD 156 HMT_MEDIUM_PPR_DISCARD
157 SET_SCRATCH0(r13) /* save r13 */ 157 SET_SCRATCH0(r13) /* save r13 */
158#ifdef CONFIG_PPC_P7_NAP
159BEGIN_FTR_SECTION
160 /* Running native on arch 2.06 or later, check if we are
161 * waking up from nap. We only handle no state loss and
162 * supervisor state loss. We do -not- handle hypervisor
163 * state loss at this time.
164 */
165 mfspr r13,SPRN_SRR1
166 rlwinm. r13,r13,47-31,30,31
167 beq 9f
168
169 /* waking up from powersave (nap) state */
170 cmpwi cr1,r13,2
171 /* Total loss of HV state is fatal. let's just stay stuck here */
172 bgt cr1,.
1739:
174END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
175#endif /* CONFIG_PPC_P7_NAP */
158 EXCEPTION_PROLOG_0(PACA_EXMC) 176 EXCEPTION_PROLOG_0(PACA_EXMC)
159BEGIN_FTR_SECTION 177BEGIN_FTR_SECTION
160 b machine_check_pSeries_early 178 b machine_check_pSeries_early
@@ -818,6 +836,70 @@ BEGIN_FTR_SECTION
818 bl .save_nvgprs 836 bl .save_nvgprs
819 addi r3,r1,STACK_FRAME_OVERHEAD 837 addi r3,r1,STACK_FRAME_OVERHEAD
820 bl .machine_check_early 838 bl .machine_check_early
839 ld r12,_MSR(r1)
840#ifdef CONFIG_PPC_P7_NAP
841 /*
842 * Check if thread was in power saving mode. We come here when any
843 * of the following is true:
844 * a. thread wasn't in power saving mode
845 * b. thread was in power saving mode with no state loss or
846 * supervisor state loss
847 *
848 * Go back to nap again if (b) is true.
849 */
850 rlwinm. r11,r12,47-31,30,31 /* Was it in power saving mode? */
851 beq 4f /* No, it wasn;t */
852 /* Thread was in power saving mode. Go back to nap again. */
853 cmpwi r11,2
854 bne 3f
855 /* Supervisor state loss */
856 li r0,1
857 stb r0,PACA_NAPSTATELOST(r13)
8583: MACHINE_CHECK_HANDLER_WINDUP
859 GET_PACA(r13)
860 ld r1,PACAR1(r13)
861 b .power7_enter_nap_mode
8624:
863#endif
864 /*
865 * Check if we are coming from hypervisor userspace. If yes then we
866 * continue in host kernel in V mode to deliver the MC event.
867 */
868 rldicl. r11,r12,4,63 /* See if MC hit while in HV mode. */
869 beq 5f
870 andi. r11,r12,MSR_PR /* See if coming from user. */
871 bne 9f /* continue in V mode if we are. */
872
8735:
874#ifdef CONFIG_KVM_BOOK3S_64_HV
875 /*
876 * We are coming from kernel context. Check if we are coming from
877 * guest. if yes, then we can continue. We will fall through
878 * do_kvm_200->kvmppc_interrupt to deliver the MC event to guest.
879 */
880 lbz r11,HSTATE_IN_GUEST(r13)
881 cmpwi r11,0 /* Check if coming from guest */
882 bne 9f /* continue if we are. */
883#endif
884 /*
885 * At this point we are not sure about what context we come from.
886 * Queue up the MCE event and return from the interrupt.
887 * But before that, check if this is an un-recoverable exception.
888 * If yes, then stay on emergency stack and panic.
889 */
890 andi. r11,r12,MSR_RI
891 bne 2f
8921: addi r3,r1,STACK_FRAME_OVERHEAD
893 bl .unrecoverable_exception
894 b 1b
8952:
896 /*
897 * Return from MC interrupt.
898 * TODO: Queue up the MCE event so that we can log it later.
899 */
900 MACHINE_CHECK_HANDLER_WINDUP
901 rfid
9029:
821 /* Deliver the machine check to host kernel in V mode. */ 903 /* Deliver the machine check to host kernel in V mode. */
822 MACHINE_CHECK_HANDLER_WINDUP 904 MACHINE_CHECK_HANDLER_WINDUP
823 b machine_check_pSeries 905 b machine_check_pSeries
diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S
index 847e40e62fce..3fdef0f0c67f 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -84,6 +84,7 @@ _GLOBAL(power7_nap)
84 std r9,_MSR(r1) 84 std r9,_MSR(r1)
85 std r1,PACAR1(r13) 85 std r1,PACAR1(r13)
86 86
87_GLOBAL(power7_enter_nap_mode)
87#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE 88#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
88 /* Tell KVM we're napping */ 89 /* Tell KVM we're napping */
89 li r4,KVM_HWTHREAD_IN_NAP 90 li r4,KVM_HWTHREAD_IN_NAP