Skip to content

Commit fb479e4

Browse files
npigginmpe
authored andcommitted
powerpc/64s: relocation, register save fixes for system reset interrupt
This patch does a couple of things. First of all, powernv immediately explodes when running a relocated kernel, because the system reset exception for handling sleeps does not do correct relocated branches. Secondly, the sleep handling code trashes the condition and cfar registers, which we would like to preserve for debugging purposes (for non-sleep case exception). This patch changes the exception to use the standard format that saves registers before any tests or branches are made. It adds the test for idle-wakeup as an "extra" to break out of the normal exception path. Then it branches to a relocated idle handler that calls the various idle handling functions. After this patch, POWER8 CPU simulator now boots powernv kernel that is running at non-zero. Fixes: 948cf67 ("powerpc: Add NAP mode support on Power7 in HV mode") Cc: [email protected] # v3.0+ Signed-off-by: Nicholas Piggin <[email protected]> Acked-by: Gautham R. Shenoy <[email protected]> Acked-by: Balbir Singh <[email protected]> Signed-off-by: Michael Ellerman <[email protected]>
1 parent bd77c44 commit fb479e4

File tree

2 files changed

+45
-21
lines changed

2 files changed

+45
-21
lines changed

arch/powerpc/include/asm/exception-64s.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@
9393
ld reg,PACAKBASE(r13); /* get high part of &label */ \
9494
ori reg,reg,(FIXED_SYMBOL_ABS_ADDR(label))@l;
9595

96+
#define __LOAD_HANDLER(reg, label) \
97+
ld reg,PACAKBASE(r13); \
98+
ori reg,reg,(ABS_ADDR(label))@l;
99+
96100
/* Exception register prefixes */
97101
#define EXC_HV H
98102
#define EXC_STD
@@ -208,6 +212,18 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
208212
#define kvmppc_interrupt kvmppc_interrupt_pr
209213
#endif
210214

215+
#ifdef CONFIG_RELOCATABLE
216+
#define BRANCH_TO_COMMON(reg, label) \
217+
__LOAD_HANDLER(reg, label); \
218+
mtctr reg; \
219+
bctr
220+
221+
#else
222+
#define BRANCH_TO_COMMON(reg, label) \
223+
b label
224+
225+
#endif
226+
211227
#define __KVM_HANDLER_PROLOG(area, n) \
212228
BEGIN_FTR_SECTION_NESTED(947) \
213229
ld r10,area+EX_CFAR(r13); \

arch/powerpc/kernel/exceptions-64s.S

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -95,19 +95,35 @@ __start_interrupts:
9595
/* No virt vectors corresponding with 0x0..0x100 */
9696
EXC_VIRT_NONE(0x4000, 0x4100)
9797

98-
EXC_REAL_BEGIN(system_reset, 0x100, 0x200)
99-
SET_SCRATCH0(r13)
98+
10099
#ifdef CONFIG_PPC_P7_NAP
101-
BEGIN_FTR_SECTION
102-
/* Running native on arch 2.06 or later, check if we are
103-
* waking up from nap/sleep/winkle.
100+
/*
101+
* If running native on arch 2.06 or later, check if we are waking up
102+
* from nap/sleep/winkle, and branch to idle handler.
104103
*/
105-
mfspr r13,SPRN_SRR1
106-
rlwinm. r13,r13,47-31,30,31
107-
beq 9f
104+
#define IDLETEST(n) \
105+
BEGIN_FTR_SECTION ; \
106+
mfspr r10,SPRN_SRR1 ; \
107+
rlwinm. r10,r10,47-31,30,31 ; \
108+
beq- 1f ; \
109+
cmpwi cr3,r10,2 ; \
110+
BRANCH_TO_COMMON(r10, system_reset_idle_common) ; \
111+
1: \
112+
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
113+
#else
114+
#define IDLETEST NOTEST
115+
#endif
108116

109-
cmpwi cr3,r13,2
110-
GET_PACA(r13)
117+
EXC_REAL_BEGIN(system_reset, 0x100, 0x200)
118+
SET_SCRATCH0(r13)
119+
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
120+
IDLETEST, 0x100)
121+
122+
EXC_REAL_END(system_reset, 0x100, 0x200)
123+
EXC_VIRT_NONE(0x4100, 0x4200)
124+
125+
#ifdef CONFIG_PPC_P7_NAP
126+
EXC_COMMON_BEGIN(system_reset_idle_common)
111127
bl pnv_restore_hyp_resource
112128

113129
li r0,PNV_THREAD_RUNNING
@@ -130,14 +146,8 @@ BEGIN_FTR_SECTION
130146
blt cr3,2f
131147
b pnv_wakeup_loss
132148
2: b pnv_wakeup_noloss
149+
#endif
133150

134-
9:
135-
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
136-
#endif /* CONFIG_PPC_P7_NAP */
137-
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
138-
NOTEST, 0x100)
139-
EXC_REAL_END(system_reset, 0x100, 0x200)
140-
EXC_VIRT_NONE(0x4100, 0x4200)
141151
EXC_COMMON(system_reset_common, 0x100, system_reset_exception)
142152

143153
#ifdef CONFIG_PPC_PSERIES
@@ -817,10 +827,8 @@ EXC_VIRT(trap_0b, 0x4b00, 0x4c00, 0xb00)
817827
TRAMP_KVM(PACA_EXGEN, 0xb00)
818828
EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
819829

820-
821-
#define LOAD_SYSCALL_HANDLER(reg) \
822-
ld reg,PACAKBASE(r13); \
823-
ori reg,reg,(ABS_ADDR(system_call_common))@l;
830+
#define LOAD_SYSCALL_HANDLER(reg) \
831+
__LOAD_HANDLER(reg, system_call_common)
824832

825833
/* Syscall routine is used twice, in reloc-off and reloc-on paths */
826834
#define SYSCALL_PSERIES_1 \

0 commit comments

Comments
 (0)