aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorHaren Myneni <haren@linux.vnet.ibm.com>2012-12-06 16:51:04 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-01-10 01:01:13 -0500
commit44e9309f1f357794b7ae93d5f3e3e6f11d2b8a7f (patch)
tree3bfa0ffc5014355234fd8b7d45e49b0953b757f7 /arch/powerpc
parent13e7a8e846c2ea38a552b986ea49332f965bbb7a (diff)
powerpc: Implement PPR save/restore
[PATCH 6/6] powerpc: Implement PPR save/restore When the task enters in to kernel space, the user defined priority (PPR) will be saved in to PACA at the beginning of first level exception vector and then copy from PACA to thread_info in second level vector. PPR will be restored from thread_info before exits the kernel space. P7/P8 temporarily raises the thread priority to higher level during exception until the program executes HMT_* calls. But it will not modify PPR register. So we save PPR value whenever some register is available to use and then calls HMT_MEDIUM to increase the priority. This feature supports on P7 or later processors. We save/ restore PPR for all exception vectors except system call entry. GLIBC will be saving / restore for system calls. So the default PPR value (3) will be set for the system call exit when the task returned to the user space. Signed-off-by: Haren Myneni <haren@us.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/include/asm/exception-64s.h18
-rw-r--r--arch/powerpc/kernel/entry_64.S3
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S23
3 files changed, 26 insertions, 18 deletions
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 391e01387248..370298a0bca3 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -147,8 +147,9 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,943)
147 147
148#define __EXCEPTION_PROLOG_1(area, extra, vec) \ 148#define __EXCEPTION_PROLOG_1(area, extra, vec) \
149 GET_PACA(r13); \ 149 GET_PACA(r13); \
150 std r9,area+EX_R9(r13); /* save r9 - r12 */ \ 150 std r9,area+EX_R9(r13); /* save r9 */ \
151 std r10,area+EX_R10(r13); \ 151 HMT_MEDIUM_PPR_SAVE(area, r9); \
152 std r10,area+EX_R10(r13); /* save r10 - r12 */ \
152 BEGIN_FTR_SECTION_NESTED(66); \ 153 BEGIN_FTR_SECTION_NESTED(66); \
153 mfspr r10,SPRN_CFAR; \ 154 mfspr r10,SPRN_CFAR; \
154 std r10,area+EX_CFAR(r13); \ 155 std r10,area+EX_CFAR(r13); \
@@ -264,6 +265,7 @@ do_kvm_##n: \
264 std r10,GPR1(r1); /* save r1 in stackframe */ \ 265 std r10,GPR1(r1); /* save r1 in stackframe */ \
265 beq 4f; /* if from kernel mode */ \ 266 beq 4f; /* if from kernel mode */ \
266 ACCOUNT_CPU_USER_ENTRY(r9, r10); \ 267 ACCOUNT_CPU_USER_ENTRY(r9, r10); \
268 SAVE_PPR(area, r9, r10); \
2674: std r2,GPR2(r1); /* save r2 in stackframe */ \ 2694: std r2,GPR2(r1); /* save r2 in stackframe */ \
268 SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \ 270 SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
269 SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \ 271 SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
@@ -305,7 +307,7 @@ do_kvm_##n: \
305 . = loc; \ 307 . = loc; \
306 .globl label##_pSeries; \ 308 .globl label##_pSeries; \
307label##_pSeries: \ 309label##_pSeries: \
308 HMT_MEDIUM; \ 310 HMT_MEDIUM_PPR_DISCARD; \
309 SET_SCRATCH0(r13); /* save r13 */ \ 311 SET_SCRATCH0(r13); /* save r13 */ \
310 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ 312 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
311 EXC_STD, KVMTEST_PR, vec) 313 EXC_STD, KVMTEST_PR, vec)
@@ -314,7 +316,7 @@ label##_pSeries: \
314 . = loc; \ 316 . = loc; \
315 .globl label##_hv; \ 317 .globl label##_hv; \
316label##_hv: \ 318label##_hv: \
317 HMT_MEDIUM; \ 319 HMT_MEDIUM_PPR_DISCARD; \
318 SET_SCRATCH0(r13); /* save r13 */ \ 320 SET_SCRATCH0(r13); /* save r13 */ \
319 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ 321 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
320 EXC_HV, KVMTEST, vec) 322 EXC_HV, KVMTEST, vec)
@@ -323,7 +325,7 @@ label##_hv: \
323 . = loc; \ 325 . = loc; \
324 .globl label##_relon_pSeries; \ 326 .globl label##_relon_pSeries; \
325label##_relon_pSeries: \ 327label##_relon_pSeries: \
326 HMT_MEDIUM; \ 328 HMT_MEDIUM_PPR_DISCARD; \
327 /* No guest interrupts come through here */ \ 329 /* No guest interrupts come through here */ \
328 SET_SCRATCH0(r13); /* save r13 */ \ 330 SET_SCRATCH0(r13); /* save r13 */ \
329 EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ 331 EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
@@ -333,7 +335,7 @@ label##_relon_pSeries: \
333 . = loc; \ 335 . = loc; \
334 .globl label##_relon_hv; \ 336 .globl label##_relon_hv; \
335label##_relon_hv: \ 337label##_relon_hv: \
336 HMT_MEDIUM; \ 338 HMT_MEDIUM_PPR_DISCARD; \
337 /* No guest interrupts come through here */ \ 339 /* No guest interrupts come through here */ \
338 SET_SCRATCH0(r13); /* save r13 */ \ 340 SET_SCRATCH0(r13); /* save r13 */ \
339 EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \ 341 EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
@@ -371,7 +373,7 @@ label##_relon_hv: \
371#define SOFTEN_NOTEST_HV(vec) _SOFTEN_TEST(EXC_HV, vec) 373#define SOFTEN_NOTEST_HV(vec) _SOFTEN_TEST(EXC_HV, vec)
372 374
373#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \ 375#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra) \
374 HMT_MEDIUM; \ 376 HMT_MEDIUM_PPR_DISCARD; \
375 SET_SCRATCH0(r13); /* save r13 */ \ 377 SET_SCRATCH0(r13); /* save r13 */ \
376 __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \ 378 __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \
377 EXCEPTION_PROLOG_PSERIES_1(label##_common, h); 379 EXCEPTION_PROLOG_PSERIES_1(label##_common, h);
@@ -393,7 +395,7 @@ label##_hv: \
393 EXC_HV, SOFTEN_TEST_HV) 395 EXC_HV, SOFTEN_TEST_HV)
394 396
395#define __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \ 397#define __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra) \
396 HMT_MEDIUM; \ 398 HMT_MEDIUM_PPR_DISCARD; \
397 SET_SCRATCH0(r13); /* save r13 */ \ 399 SET_SCRATCH0(r13); /* save r13 */ \
398 __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \ 400 __EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec); \
399 EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, h); 401 EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, h);
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 7a70d0a6df3e..6faf51e165a5 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -227,6 +227,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
227 227
228 beq- 1f 228 beq- 1f
229 ACCOUNT_CPU_USER_EXIT(r11, r12) 229 ACCOUNT_CPU_USER_EXIT(r11, r12)
230 HMT_MEDIUM_LOW_HAS_PPR
230 ld r13,GPR13(r1) /* only restore r13 if returning to usermode */ 231 ld r13,GPR13(r1) /* only restore r13 if returning to usermode */
2311: ld r2,GPR2(r1) 2321: ld r2,GPR2(r1)
232 ld r1,GPR1(r1) 233 ld r1,GPR1(r1)
@@ -303,6 +304,7 @@ syscall_exit_work:
303 subi r12,r12,TI_FLAGS 304 subi r12,r12,TI_FLAGS
304 305
3054: /* Anything else left to do? */ 3064: /* Anything else left to do? */
307 SET_DEFAULT_THREAD_PPR(r3, r9) /* Set thread.ppr = 3 */
306 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) 308 andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP)
307 beq .ret_from_except_lite 309 beq .ret_from_except_lite
308 310
@@ -758,6 +760,7 @@ fast_exception_return:
758 andi. r0,r3,MSR_PR 760 andi. r0,r3,MSR_PR
759 beq 1f 761 beq 1f
760 ACCOUNT_CPU_USER_EXIT(r2, r4) 762 ACCOUNT_CPU_USER_EXIT(r2, r4)
763 RESTORE_PPR(r2, r4)
761 REST_GPR(13, r1) 764 REST_GPR(13, r1)
7621: 7651:
763 mtspr SPRN_SRR1,r3 766 mtspr SPRN_SRR1,r3
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 32fc04f78890..3425aba8da51 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -104,7 +104,7 @@ __start_interrupts:
104 104
105 .globl system_reset_pSeries; 105 .globl system_reset_pSeries;
106system_reset_pSeries: 106system_reset_pSeries:
107 HMT_MEDIUM; 107 HMT_MEDIUM_PPR_DISCARD
108 SET_SCRATCH0(r13) 108 SET_SCRATCH0(r13)
109#ifdef CONFIG_PPC_P7_NAP 109#ifdef CONFIG_PPC_P7_NAP
110BEGIN_FTR_SECTION 110BEGIN_FTR_SECTION
@@ -158,7 +158,7 @@ machine_check_pSeries_1:
158 . = 0x300 158 . = 0x300
159 .globl data_access_pSeries 159 .globl data_access_pSeries
160data_access_pSeries: 160data_access_pSeries:
161 HMT_MEDIUM 161 HMT_MEDIUM_PPR_DISCARD
162 SET_SCRATCH0(r13) 162 SET_SCRATCH0(r13)
163BEGIN_FTR_SECTION 163BEGIN_FTR_SECTION
164 b data_access_check_stab 164 b data_access_check_stab
@@ -170,7 +170,7 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
170 . = 0x380 170 . = 0x380
171 .globl data_access_slb_pSeries 171 .globl data_access_slb_pSeries
172data_access_slb_pSeries: 172data_access_slb_pSeries:
173 HMT_MEDIUM 173 HMT_MEDIUM_PPR_DISCARD
174 SET_SCRATCH0(r13) 174 SET_SCRATCH0(r13)
175 EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380) 175 EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380)
176 std r3,PACA_EXSLB+EX_R3(r13) 176 std r3,PACA_EXSLB+EX_R3(r13)
@@ -201,7 +201,7 @@ data_access_slb_pSeries:
201 . = 0x480 201 . = 0x480
202 .globl instruction_access_slb_pSeries 202 .globl instruction_access_slb_pSeries
203instruction_access_slb_pSeries: 203instruction_access_slb_pSeries:
204 HMT_MEDIUM 204 HMT_MEDIUM_PPR_DISCARD
205 SET_SCRATCH0(r13) 205 SET_SCRATCH0(r13)
206 EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480) 206 EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480)
207 std r3,PACA_EXSLB+EX_R3(r13) 207 std r3,PACA_EXSLB+EX_R3(r13)
@@ -324,10 +324,11 @@ vsx_unavailable_pSeries_1:
324 . = 0x1500 324 . = 0x1500
325 .global denorm_exception_hv 325 .global denorm_exception_hv
326denorm_exception_hv: 326denorm_exception_hv:
327 HMT_MEDIUM 327 HMT_MEDIUM_PPR_DISCARD
328 mtspr SPRN_SPRG_HSCRATCH0,r13 328 mtspr SPRN_SPRG_HSCRATCH0,r13
329 mfspr r13,SPRN_SPRG_HPACA 329 mfspr r13,SPRN_SPRG_HPACA
330 std r9,PACA_EXGEN+EX_R9(r13) 330 std r9,PACA_EXGEN+EX_R9(r13)
331 HMT_MEDIUM_PPR_SAVE(PACA_EXGEN, r9)
331 std r10,PACA_EXGEN+EX_R10(r13) 332 std r10,PACA_EXGEN+EX_R10(r13)
332 std r11,PACA_EXGEN+EX_R11(r13) 333 std r11,PACA_EXGEN+EX_R11(r13)
333 std r12,PACA_EXGEN+EX_R12(r13) 334 std r12,PACA_EXGEN+EX_R12(r13)
@@ -369,7 +370,7 @@ denorm_exception_hv:
369machine_check_pSeries: 370machine_check_pSeries:
370 .globl machine_check_fwnmi 371 .globl machine_check_fwnmi
371machine_check_fwnmi: 372machine_check_fwnmi:
372 HMT_MEDIUM 373 HMT_MEDIUM_PPR_DISCARD
373 SET_SCRATCH0(r13) /* save r13 */ 374 SET_SCRATCH0(r13) /* save r13 */
374 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, 375 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common,
375 EXC_STD, KVMTEST, 0x200) 376 EXC_STD, KVMTEST, 0x200)
@@ -498,6 +499,7 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
498 mtspr SPRN_HSRR0,r11 499 mtspr SPRN_HSRR0,r11
499 mtcrf 0x80,r9 500 mtcrf 0x80,r9
500 ld r9,PACA_EXGEN+EX_R9(r13) 501 ld r9,PACA_EXGEN+EX_R9(r13)
502 RESTORE_PPR_PACA(PACA_EXGEN, r10)
501 ld r10,PACA_EXGEN+EX_R10(r13) 503 ld r10,PACA_EXGEN+EX_R10(r13)
502 ld r11,PACA_EXGEN+EX_R11(r13) 504 ld r11,PACA_EXGEN+EX_R11(r13)
503 ld r12,PACA_EXGEN+EX_R12(r13) 505 ld r12,PACA_EXGEN+EX_R12(r13)
@@ -603,7 +605,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
603 .globl system_reset_fwnmi 605 .globl system_reset_fwnmi
604 .align 7 606 .align 7
605system_reset_fwnmi: 607system_reset_fwnmi:
606 HMT_MEDIUM 608 HMT_MEDIUM_PPR_DISCARD
607 SET_SCRATCH0(r13) /* save r13 */ 609 SET_SCRATCH0(r13) /* save r13 */
608 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD, 610 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
609 NOTEST, 0x100) 611 NOTEST, 0x100)
@@ -716,7 +718,7 @@ machine_check_common:
716 . = 0x4380 718 . = 0x4380
717 .globl data_access_slb_relon_pSeries 719 .globl data_access_slb_relon_pSeries
718data_access_slb_relon_pSeries: 720data_access_slb_relon_pSeries:
719 HMT_MEDIUM 721 HMT_MEDIUM_PPR_DISCARD
720 SET_SCRATCH0(r13) 722 SET_SCRATCH0(r13)
721 EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380) 723 EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380)
722 std r3,PACA_EXSLB+EX_R3(r13) 724 std r3,PACA_EXSLB+EX_R3(r13)
@@ -741,7 +743,7 @@ data_access_slb_relon_pSeries:
741 . = 0x4480 743 . = 0x4480
742 .globl instruction_access_slb_relon_pSeries 744 .globl instruction_access_slb_relon_pSeries
743instruction_access_slb_relon_pSeries: 745instruction_access_slb_relon_pSeries:
744 HMT_MEDIUM 746 HMT_MEDIUM_PPR_DISCARD
745 SET_SCRATCH0(r13) 747 SET_SCRATCH0(r13)
746 EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x480) 748 EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x480)
747 std r3,PACA_EXSLB+EX_R3(r13) 749 std r3,PACA_EXSLB+EX_R3(r13)
@@ -1062,6 +1064,7 @@ _GLOBAL(slb_miss_realmode)
1062 mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ 1064 mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
1063.machine pop 1065.machine pop
1064 1066
1067 RESTORE_PPR_PACA(PACA_EXSLB, r9)
1065 ld r9,PACA_EXSLB+EX_R9(r13) 1068 ld r9,PACA_EXSLB+EX_R9(r13)
1066 ld r10,PACA_EXSLB+EX_R10(r13) 1069 ld r10,PACA_EXSLB+EX_R10(r13)
1067 ld r11,PACA_EXSLB+EX_R11(r13) 1070 ld r11,PACA_EXSLB+EX_R11(r13)
@@ -1411,7 +1414,7 @@ initial_stab:
1411 1414
1412#ifdef CONFIG_PPC_POWERNV 1415#ifdef CONFIG_PPC_POWERNV
1413_GLOBAL(opal_mc_secondary_handler) 1416_GLOBAL(opal_mc_secondary_handler)
1414 HMT_MEDIUM 1417 HMT_MEDIUM_PPR_DISCARD
1415 SET_SCRATCH0(r13) 1418 SET_SCRATCH0(r13)
1416 GET_PACA(r13) 1419 GET_PACA(r13)
1417 clrldi r3,r3,2 1420 clrldi r3,r3,2