diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/Kconfig | 2 | ||||
-rw-r--r-- | arch/powerpc/include/asm/processor.h | 4 | ||||
-rw-r--r-- | arch/powerpc/include/asm/reg.h | 31 | ||||
-rw-r--r-- | arch/powerpc/include/asm/switch_to.h | 9 | ||||
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/eeh.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/entry_64.S | 36 | ||||
-rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/process.c | 10 | ||||
-rw-r--r-- | arch/powerpc/kernel/tm.S | 20 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 58 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_pr.c | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/nvram.c | 80 |
14 files changed, 170 insertions, 99 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 7205989b9b59..174c6a12269a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -586,7 +586,7 @@ config SCHED_SMT | |||
586 | config PPC_DENORMALISATION | 586 | config PPC_DENORMALISATION |
587 | bool "PowerPC denormalisation exception handling" | 587 | bool "PowerPC denormalisation exception handling" |
588 | depends on PPC_BOOK3S_64 | 588 | depends on PPC_BOOK3S_64 |
589 | default "n" | 589 | default "y" if PPC_POWERNV |
590 | ---help--- | 590 | ---help--- |
591 | Add support for handling denormalisation of single precision | 591 | Add support for handling denormalisation of single precision |
592 | values. Useful for bare metal only. If unsure say Y here. | 592 | values. Useful for bare metal only. If unsure say Y here. |
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 47a35b08b963..e378cccfca55 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h | |||
@@ -247,6 +247,10 @@ struct thread_struct { | |||
247 | unsigned long tm_orig_msr; /* Thread's MSR on ctx switch */ | 247 | unsigned long tm_orig_msr; /* Thread's MSR on ctx switch */ |
248 | struct pt_regs ckpt_regs; /* Checkpointed registers */ | 248 | struct pt_regs ckpt_regs; /* Checkpointed registers */ |
249 | 249 | ||
250 | unsigned long tm_tar; | ||
251 | unsigned long tm_ppr; | ||
252 | unsigned long tm_dscr; | ||
253 | |||
250 | /* | 254 | /* |
251 | * Transactional FP and VSX 0-31 register set. | 255 | * Transactional FP and VSX 0-31 register set. |
252 | * NOTE: the sense of these is the opposite of the integer ckpt_regs! | 256 | * NOTE: the sense of these is the opposite of the integer ckpt_regs! |
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 64264bf601f5..dc10bf549635 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h | |||
@@ -254,19 +254,28 @@ | |||
254 | #define SPRN_HRMOR 0x139 /* Real mode offset register */ | 254 | #define SPRN_HRMOR 0x139 /* Real mode offset register */ |
255 | #define SPRN_HSRR0 0x13A /* Hypervisor Save/Restore 0 */ | 255 | #define SPRN_HSRR0 0x13A /* Hypervisor Save/Restore 0 */ |
256 | #define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */ | 256 | #define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */ |
257 | /* HFSCR and FSCR bit numbers are the same */ | ||
258 | #define FSCR_TAR_LG 8 /* Enable Target Address Register */ | ||
259 | #define FSCR_EBB_LG 7 /* Enable Event Based Branching */ | ||
260 | #define FSCR_TM_LG 5 /* Enable Transactional Memory */ | ||
261 | #define FSCR_PM_LG 4 /* Enable prob/priv access to PMU SPRs */ | ||
262 | #define FSCR_BHRB_LG 3 /* Enable Branch History Rolling Buffer*/ | ||
263 | #define FSCR_DSCR_LG 2 /* Enable Data Stream Control Register */ | ||
264 | #define FSCR_VECVSX_LG 1 /* Enable VMX/VSX */ | ||
265 | #define FSCR_FP_LG 0 /* Enable Floating Point */ | ||
257 | #define SPRN_FSCR 0x099 /* Facility Status & Control Register */ | 266 | #define SPRN_FSCR 0x099 /* Facility Status & Control Register */ |
258 | #define FSCR_TAR (1 << (63-55)) /* Enable Target Address Register */ | 267 | #define FSCR_TAR __MASK(FSCR_TAR_LG) |
259 | #define FSCR_EBB (1 << (63-56)) /* Enable Event Based Branching */ | 268 | #define FSCR_EBB __MASK(FSCR_EBB_LG) |
260 | #define FSCR_DSCR (1 << (63-61)) /* Enable Data Stream Control Register */ | 269 | #define FSCR_DSCR __MASK(FSCR_DSCR_LG) |
261 | #define SPRN_HFSCR 0xbe /* HV=1 Facility Status & Control Register */ | 270 | #define SPRN_HFSCR 0xbe /* HV=1 Facility Status & Control Register */ |
262 | #define HFSCR_TAR (1 << (63-55)) /* Enable Target Address Register */ | 271 | #define HFSCR_TAR __MASK(FSCR_TAR_LG) |
263 | #define HFSCR_EBB (1 << (63-56)) /* Enable Event Based Branching */ | 272 | #define HFSCR_EBB __MASK(FSCR_EBB_LG) |
264 | #define HFSCR_TM (1 << (63-58)) /* Enable Transactional Memory */ | 273 | #define HFSCR_TM __MASK(FSCR_TM_LG) |
265 | #define HFSCR_PM (1 << (63-60)) /* Enable prob/priv access to PMU SPRs */ | 274 | #define HFSCR_PM __MASK(FSCR_PM_LG) |
266 | #define HFSCR_BHRB (1 << (63-59)) /* Enable Branch History Rolling Buffer*/ | 275 | #define HFSCR_BHRB __MASK(FSCR_BHRB_LG) |
267 | #define HFSCR_DSCR (1 << (63-61)) /* Enable Data Stream Control Register */ | 276 | #define HFSCR_DSCR __MASK(FSCR_DSCR_LG) |
268 | #define HFSCR_VECVSX (1 << (63-62)) /* Enable VMX/VSX */ | 277 | #define HFSCR_VECVSX __MASK(FSCR_VECVSX_LG) |
269 | #define HFSCR_FP (1 << (63-63)) /* Enable Floating Point */ | 278 | #define HFSCR_FP __MASK(FSCR_FP_LG) |
270 | #define SPRN_TAR 0x32f /* Target Address Register */ | 279 | #define SPRN_TAR 0x32f /* Target Address Register */ |
271 | #define SPRN_LPCR 0x13E /* LPAR Control Register */ | 280 | #define SPRN_LPCR 0x13E /* LPAR Control Register */ |
272 | #define LPCR_VPM0 (1ul << (63-0)) | 281 | #define LPCR_VPM0 (1ul << (63-0)) |
diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 2c7edde8f1bb..2be5618cdec6 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h | |||
@@ -15,6 +15,15 @@ extern struct task_struct *__switch_to(struct task_struct *, | |||
15 | struct thread_struct; | 15 | struct thread_struct; |
16 | extern struct task_struct *_switch(struct thread_struct *prev, | 16 | extern struct task_struct *_switch(struct thread_struct *prev, |
17 | struct thread_struct *next); | 17 | struct thread_struct *next); |
18 | #ifdef CONFIG_PPC_BOOK3S_64 | ||
19 | static inline void save_tar(struct thread_struct *prev) | ||
20 | { | ||
21 | if (cpu_has_feature(CPU_FTR_ARCH_207S)) | ||
22 | prev->tar = mfspr(SPRN_TAR); | ||
23 | } | ||
24 | #else | ||
25 | static inline void save_tar(struct thread_struct *prev) {} | ||
26 | #endif | ||
18 | 27 | ||
19 | extern void load_up_fpu(void); | 28 | extern void load_up_fpu(void); |
20 | extern void enable_kernel_fp(void); | 29 | extern void enable_kernel_fp(void); |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index c7e8afc2ead0..8207459efe56 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -138,6 +138,9 @@ int main(void) | |||
138 | DEFINE(THREAD_TM_TFHAR, offsetof(struct thread_struct, tm_tfhar)); | 138 | DEFINE(THREAD_TM_TFHAR, offsetof(struct thread_struct, tm_tfhar)); |
139 | DEFINE(THREAD_TM_TEXASR, offsetof(struct thread_struct, tm_texasr)); | 139 | DEFINE(THREAD_TM_TEXASR, offsetof(struct thread_struct, tm_texasr)); |
140 | DEFINE(THREAD_TM_TFIAR, offsetof(struct thread_struct, tm_tfiar)); | 140 | DEFINE(THREAD_TM_TFIAR, offsetof(struct thread_struct, tm_tfiar)); |
141 | DEFINE(THREAD_TM_TAR, offsetof(struct thread_struct, tm_tar)); | ||
142 | DEFINE(THREAD_TM_PPR, offsetof(struct thread_struct, tm_ppr)); | ||
143 | DEFINE(THREAD_TM_DSCR, offsetof(struct thread_struct, tm_dscr)); | ||
141 | DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs)); | 144 | DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs)); |
142 | DEFINE(THREAD_TRANSACT_VR0, offsetof(struct thread_struct, | 145 | DEFINE(THREAD_TRANSACT_VR0, offsetof(struct thread_struct, |
143 | transact_vr[0])); | 146 | transact_vr[0])); |
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index ea9414c8088d..55593ee2d5aa 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c | |||
@@ -1061,7 +1061,7 @@ static const struct file_operations proc_eeh_operations = { | |||
1061 | 1061 | ||
1062 | static int __init eeh_init_proc(void) | 1062 | static int __init eeh_init_proc(void) |
1063 | { | 1063 | { |
1064 | if (machine_is(pseries)) | 1064 | if (machine_is(pseries) || machine_is(powernv)) |
1065 | proc_create("powerpc/eeh", 0, NULL, &proc_eeh_operations); | 1065 | proc_create("powerpc/eeh", 0, NULL, &proc_eeh_operations); |
1066 | return 0; | 1066 | return 0; |
1067 | } | 1067 | } |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 707fbfde1324..4524500f30d6 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -450,15 +450,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_DSCR) | |||
450 | 450 | ||
451 | #ifdef CONFIG_PPC_BOOK3S_64 | 451 | #ifdef CONFIG_PPC_BOOK3S_64 |
452 | BEGIN_FTR_SECTION | 452 | BEGIN_FTR_SECTION |
453 | /* | ||
454 | * Back up the TAR across context switches. Note that the TAR is not | ||
455 | * available for use in the kernel. (To provide this, the TAR should | ||
456 | * be backed up/restored on exception entry/exit instead, and be in | ||
457 | * pt_regs. FIXME, this should be in pt_regs anyway (for debug).) | ||
458 | */ | ||
459 | mfspr r0,SPRN_TAR | ||
460 | std r0,THREAD_TAR(r3) | ||
461 | |||
462 | /* Event based branch registers */ | 453 | /* Event based branch registers */ |
463 | mfspr r0, SPRN_BESCR | 454 | mfspr r0, SPRN_BESCR |
464 | std r0, THREAD_BESCR(r3) | 455 | std r0, THREAD_BESCR(r3) |
@@ -587,9 +578,34 @@ BEGIN_FTR_SECTION | |||
587 | ld r7,DSCR_DEFAULT@toc(2) | 578 | ld r7,DSCR_DEFAULT@toc(2) |
588 | ld r0,THREAD_DSCR(r4) | 579 | ld r0,THREAD_DSCR(r4) |
589 | cmpwi r6,0 | 580 | cmpwi r6,0 |
581 | li r8, FSCR_DSCR | ||
590 | bne 1f | 582 | bne 1f |
591 | ld r0,0(r7) | 583 | ld r0,0(r7) |
592 | 1: cmpd r0,r25 | 584 | b 3f |
585 | 1: | ||
586 | BEGIN_FTR_SECTION_NESTED(70) | ||
587 | mfspr r6, SPRN_FSCR | ||
588 | or r6, r6, r8 | ||
589 | mtspr SPRN_FSCR, r6 | ||
590 | BEGIN_FTR_SECTION_NESTED(69) | ||
591 | mfspr r6, SPRN_HFSCR | ||
592 | or r6, r6, r8 | ||
593 | mtspr SPRN_HFSCR, r6 | ||
594 | END_FTR_SECTION_NESTED(CPU_FTR_HVMODE, CPU_FTR_HVMODE, 69) | ||
595 | b 4f | ||
596 | END_FTR_SECTION_NESTED(CPU_FTR_ARCH_207S, CPU_FTR_ARCH_207S, 70) | ||
597 | 3: | ||
598 | BEGIN_FTR_SECTION_NESTED(70) | ||
599 | mfspr r6, SPRN_FSCR | ||
600 | andc r6, r6, r8 | ||
601 | mtspr SPRN_FSCR, r6 | ||
602 | BEGIN_FTR_SECTION_NESTED(69) | ||
603 | mfspr r6, SPRN_HFSCR | ||
604 | andc r6, r6, r8 | ||
605 | mtspr SPRN_HFSCR, r6 | ||
606 | END_FTR_SECTION_NESTED(CPU_FTR_HVMODE, CPU_FTR_HVMODE, 69) | ||
607 | END_FTR_SECTION_NESTED(CPU_FTR_ARCH_207S, CPU_FTR_ARCH_207S, 70) | ||
608 | 4: cmpd r0,r25 | ||
593 | beq 2f | 609 | beq 2f |
594 | mtspr SPRN_DSCR,r0 | 610 | mtspr SPRN_DSCR,r0 |
595 | 2: | 611 | 2: |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 17f761dccb7a..3a9ed6ac224b 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -855,7 +855,7 @@ facility_unavailable_relon_trampoline: | |||
855 | hv_facility_unavailable_relon_trampoline: | 855 | hv_facility_unavailable_relon_trampoline: |
856 | SET_SCRATCH0(r13) | 856 | SET_SCRATCH0(r13) |
857 | EXCEPTION_PROLOG_0(PACA_EXGEN) | 857 | EXCEPTION_PROLOG_0(PACA_EXGEN) |
858 | b facility_unavailable_relon_hv | 858 | b hv_facility_unavailable_relon_hv |
859 | 859 | ||
860 | STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint) | 860 | STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint) |
861 | #ifdef CONFIG_PPC_DENORMALISATION | 861 | #ifdef CONFIG_PPC_DENORMALISATION |
@@ -1182,6 +1182,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) | |||
1182 | b .ret_from_except | 1182 | b .ret_from_except |
1183 | 1183 | ||
1184 | STD_EXCEPTION_COMMON(0xf60, facility_unavailable, .facility_unavailable_exception) | 1184 | STD_EXCEPTION_COMMON(0xf60, facility_unavailable, .facility_unavailable_exception) |
1185 | STD_EXCEPTION_COMMON(0xf80, hv_facility_unavailable, .facility_unavailable_exception) | ||
1185 | 1186 | ||
1186 | .align 7 | 1187 | .align 7 |
1187 | .globl __end_handlers | 1188 | .globl __end_handlers |
@@ -1195,7 +1196,7 @@ __end_handlers: | |||
1195 | STD_RELON_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable) | 1196 | STD_RELON_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable) |
1196 | STD_RELON_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable) | 1197 | STD_RELON_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable) |
1197 | STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable) | 1198 | STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable) |
1198 | STD_RELON_EXCEPTION_HV_OOL(0xf80, facility_unavailable) | 1199 | STD_RELON_EXCEPTION_HV_OOL(0xf80, hv_facility_unavailable) |
1199 | 1200 | ||
1200 | #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) | 1201 | #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) |
1201 | /* | 1202 | /* |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 0ec255a81c66..6f428da53e20 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -602,6 +602,16 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
602 | struct ppc64_tlb_batch *batch; | 602 | struct ppc64_tlb_batch *batch; |
603 | #endif | 603 | #endif |
604 | 604 | ||
605 | /* Back up the TAR across context switches. | ||
606 | * Note that the TAR is not available for use in the kernel. (To | ||
607 | * provide this, the TAR should be backed up/restored on exception | ||
608 | * entry/exit instead, and be in pt_regs. FIXME, this should be in | ||
609 | * pt_regs anyway (for debug).) | ||
610 | * Save the TAR here before we do treclaim/trecheckpoint as these | ||
611 | * will change the TAR. | ||
612 | */ | ||
613 | save_tar(&prev->thread); | ||
614 | |||
605 | __switch_to_tm(prev); | 615 | __switch_to_tm(prev); |
606 | 616 | ||
607 | #ifdef CONFIG_SMP | 617 | #ifdef CONFIG_SMP |
diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S index e2145b222f83..7b60b9851469 100644 --- a/arch/powerpc/kernel/tm.S +++ b/arch/powerpc/kernel/tm.S | |||
@@ -233,6 +233,16 @@ dont_backup_fp: | |||
233 | std r5, _CCR(r7) | 233 | std r5, _CCR(r7) |
234 | std r6, _XER(r7) | 234 | std r6, _XER(r7) |
235 | 235 | ||
236 | |||
237 | /* ******************** TAR, PPR, DSCR ********** */ | ||
238 | mfspr r3, SPRN_TAR | ||
239 | mfspr r4, SPRN_PPR | ||
240 | mfspr r5, SPRN_DSCR | ||
241 | |||
242 | std r3, THREAD_TM_TAR(r12) | ||
243 | std r4, THREAD_TM_PPR(r12) | ||
244 | std r5, THREAD_TM_DSCR(r12) | ||
245 | |||
236 | /* MSR and flags: We don't change CRs, and we don't need to alter | 246 | /* MSR and flags: We don't change CRs, and we don't need to alter |
237 | * MSR. | 247 | * MSR. |
238 | */ | 248 | */ |
@@ -347,6 +357,16 @@ dont_restore_fp: | |||
347 | mtmsr r6 /* FP/Vec off again! */ | 357 | mtmsr r6 /* FP/Vec off again! */ |
348 | 358 | ||
349 | restore_gprs: | 359 | restore_gprs: |
360 | |||
361 | /* ******************** TAR, PPR, DSCR ********** */ | ||
362 | ld r4, THREAD_TM_TAR(r3) | ||
363 | ld r5, THREAD_TM_PPR(r3) | ||
364 | ld r6, THREAD_TM_DSCR(r3) | ||
365 | |||
366 | mtspr SPRN_TAR, r4 | ||
367 | mtspr SPRN_PPR, r5 | ||
368 | mtspr SPRN_DSCR, r6 | ||
369 | |||
350 | /* ******************** CR,LR,CCR,MSR ********** */ | 370 | /* ******************** CR,LR,CCR,MSR ********** */ |
351 | ld r3, _CTR(r7) | 371 | ld r3, _CTR(r7) |
352 | ld r4, _LINK(r7) | 372 | ld r4, _LINK(r7) |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 77a7581dcb1c..529a9329e8d9 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -44,9 +44,7 @@ | |||
44 | #include <asm/machdep.h> | 44 | #include <asm/machdep.h> |
45 | #include <asm/rtas.h> | 45 | #include <asm/rtas.h> |
46 | #include <asm/pmc.h> | 46 | #include <asm/pmc.h> |
47 | #ifdef CONFIG_PPC32 | ||
48 | #include <asm/reg.h> | 47 | #include <asm/reg.h> |
49 | #endif | ||
50 | #ifdef CONFIG_PMAC_BACKLIGHT | 48 | #ifdef CONFIG_PMAC_BACKLIGHT |
51 | #include <asm/backlight.h> | 49 | #include <asm/backlight.h> |
52 | #endif | 50 | #endif |
@@ -1316,43 +1314,54 @@ void vsx_unavailable_exception(struct pt_regs *regs) | |||
1316 | die("Unrecoverable VSX Unavailable Exception", regs, SIGABRT); | 1314 | die("Unrecoverable VSX Unavailable Exception", regs, SIGABRT); |
1317 | } | 1315 | } |
1318 | 1316 | ||
1317 | #ifdef CONFIG_PPC64 | ||
1319 | void facility_unavailable_exception(struct pt_regs *regs) | 1318 | void facility_unavailable_exception(struct pt_regs *regs) |
1320 | { | 1319 | { |
1321 | static char *facility_strings[] = { | 1320 | static char *facility_strings[] = { |
1322 | "FPU", | 1321 | [FSCR_FP_LG] = "FPU", |
1323 | "VMX/VSX", | 1322 | [FSCR_VECVSX_LG] = "VMX/VSX", |
1324 | "DSCR", | 1323 | [FSCR_DSCR_LG] = "DSCR", |
1325 | "PMU SPRs", | 1324 | [FSCR_PM_LG] = "PMU SPRs", |
1326 | "BHRB", | 1325 | [FSCR_BHRB_LG] = "BHRB", |
1327 | "TM", | 1326 | [FSCR_TM_LG] = "TM", |
1328 | "AT", | 1327 | [FSCR_EBB_LG] = "EBB", |
1329 | "EBB", | 1328 | [FSCR_TAR_LG] = "TAR", |
1330 | "TAR", | ||
1331 | }; | 1329 | }; |
1332 | char *facility, *prefix; | 1330 | char *facility = "unknown"; |
1333 | u64 value; | 1331 | u64 value; |
1332 | u8 status; | ||
1333 | bool hv; | ||
1334 | 1334 | ||
1335 | if (regs->trap == 0xf60) { | 1335 | hv = (regs->trap == 0xf80); |
1336 | value = mfspr(SPRN_FSCR); | 1336 | if (hv) |
1337 | prefix = ""; | ||
1338 | } else { | ||
1339 | value = mfspr(SPRN_HFSCR); | 1337 | value = mfspr(SPRN_HFSCR); |
1340 | prefix = "Hypervisor "; | 1338 | else |
1339 | value = mfspr(SPRN_FSCR); | ||
1340 | |||
1341 | status = value >> 56; | ||
1342 | if (status == FSCR_DSCR_LG) { | ||
1343 | /* User is acessing the DSCR. Set the inherit bit and allow | ||
1344 | * the user to set it directly in future by setting via the | ||
1345 | * H/FSCR DSCR bit. | ||
1346 | */ | ||
1347 | current->thread.dscr_inherit = 1; | ||
1348 | if (hv) | ||
1349 | mtspr(SPRN_HFSCR, value | HFSCR_DSCR); | ||
1350 | else | ||
1351 | mtspr(SPRN_FSCR, value | FSCR_DSCR); | ||
1352 | return; | ||
1341 | } | 1353 | } |
1342 | 1354 | ||
1343 | value = value >> 56; | 1355 | if ((status < ARRAY_SIZE(facility_strings)) && |
1356 | facility_strings[status]) | ||
1357 | facility = facility_strings[status]; | ||
1344 | 1358 | ||
1345 | /* We restore the interrupt state now */ | 1359 | /* We restore the interrupt state now */ |
1346 | if (!arch_irq_disabled_regs(regs)) | 1360 | if (!arch_irq_disabled_regs(regs)) |
1347 | local_irq_enable(); | 1361 | local_irq_enable(); |
1348 | 1362 | ||
1349 | if (value < ARRAY_SIZE(facility_strings)) | ||
1350 | facility = facility_strings[value]; | ||
1351 | else | ||
1352 | facility = "unknown"; | ||
1353 | |||
1354 | pr_err("%sFacility '%s' unavailable, exception at 0x%lx, MSR=%lx\n", | 1363 | pr_err("%sFacility '%s' unavailable, exception at 0x%lx, MSR=%lx\n", |
1355 | prefix, facility, regs->nip, regs->msr); | 1364 | hv ? "Hypervisor " : "", facility, regs->nip, regs->msr); |
1356 | 1365 | ||
1357 | if (user_mode(regs)) { | 1366 | if (user_mode(regs)) { |
1358 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); | 1367 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); |
@@ -1361,6 +1370,7 @@ void facility_unavailable_exception(struct pt_regs *regs) | |||
1361 | 1370 | ||
1362 | die("Unexpected facility unavailable exception", regs, SIGABRT); | 1371 | die("Unexpected facility unavailable exception", regs, SIGABRT); |
1363 | } | 1372 | } |
1373 | #endif | ||
1364 | 1374 | ||
1365 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1375 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
1366 | 1376 | ||
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index cf39bf4f3c7d..e8d51cb76752 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -1809,7 +1809,7 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) | |||
1809 | rma_size <<= PAGE_SHIFT; | 1809 | rma_size <<= PAGE_SHIFT; |
1810 | rmls = lpcr_rmls(rma_size); | 1810 | rmls = lpcr_rmls(rma_size); |
1811 | err = -EINVAL; | 1811 | err = -EINVAL; |
1812 | if (rmls < 0) { | 1812 | if ((long)rmls < 0) { |
1813 | pr_err("KVM: Can't use RMA of 0x%lx bytes\n", rma_size); | 1813 | pr_err("KVM: Can't use RMA of 0x%lx bytes\n", rma_size); |
1814 | goto out_srcu; | 1814 | goto out_srcu; |
1815 | } | 1815 | } |
@@ -1874,7 +1874,7 @@ int kvmppc_core_init_vm(struct kvm *kvm) | |||
1874 | /* Allocate the guest's logical partition ID */ | 1874 | /* Allocate the guest's logical partition ID */ |
1875 | 1875 | ||
1876 | lpid = kvmppc_alloc_lpid(); | 1876 | lpid = kvmppc_alloc_lpid(); |
1877 | if (lpid < 0) | 1877 | if ((long)lpid < 0) |
1878 | return -ENOMEM; | 1878 | return -ENOMEM; |
1879 | kvm->arch.lpid = lpid; | 1879 | kvm->arch.lpid = lpid; |
1880 | 1880 | ||
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 19498a567a81..c6e13d9a9e15 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c | |||
@@ -1047,11 +1047,12 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id) | |||
1047 | if (err) | 1047 | if (err) |
1048 | goto free_shadow_vcpu; | 1048 | goto free_shadow_vcpu; |
1049 | 1049 | ||
1050 | err = -ENOMEM; | ||
1050 | p = __get_free_page(GFP_KERNEL|__GFP_ZERO); | 1051 | p = __get_free_page(GFP_KERNEL|__GFP_ZERO); |
1051 | /* the real shared page fills the last 4k of our page */ | ||
1052 | vcpu->arch.shared = (void*)(p + PAGE_SIZE - 4096); | ||
1053 | if (!p) | 1052 | if (!p) |
1054 | goto uninit_vcpu; | 1053 | goto uninit_vcpu; |
1054 | /* the real shared page fills the last 4k of our page */ | ||
1055 | vcpu->arch.shared = (void *)(p + PAGE_SIZE - 4096); | ||
1055 | 1056 | ||
1056 | #ifdef CONFIG_PPC_BOOK3S_64 | 1057 | #ifdef CONFIG_PPC_BOOK3S_64 |
1057 | /* default to book3s_64 (970fx) */ | 1058 | /* default to book3s_64 (970fx) */ |
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 9f8671a44551..6a5f2b1f32ca 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c | |||
@@ -569,35 +569,6 @@ error: | |||
569 | return ret; | 569 | return ret; |
570 | } | 570 | } |
571 | 571 | ||
572 | static int unzip_oops(char *oops_buf, char *big_buf) | ||
573 | { | ||
574 | struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf; | ||
575 | u64 timestamp = oops_hdr->timestamp; | ||
576 | char *big_oops_data = NULL; | ||
577 | char *oops_data_buf = NULL; | ||
578 | size_t big_oops_data_sz; | ||
579 | int unzipped_len; | ||
580 | |||
581 | big_oops_data = big_buf + sizeof(struct oops_log_info); | ||
582 | big_oops_data_sz = big_oops_buf_sz - sizeof(struct oops_log_info); | ||
583 | oops_data_buf = oops_buf + sizeof(struct oops_log_info); | ||
584 | |||
585 | unzipped_len = nvram_decompress(oops_data_buf, big_oops_data, | ||
586 | oops_hdr->report_length, | ||
587 | big_oops_data_sz); | ||
588 | |||
589 | if (unzipped_len < 0) { | ||
590 | pr_err("nvram: decompression failed; returned %d\n", | ||
591 | unzipped_len); | ||
592 | return -1; | ||
593 | } | ||
594 | oops_hdr = (struct oops_log_info *)big_buf; | ||
595 | oops_hdr->version = OOPS_HDR_VERSION; | ||
596 | oops_hdr->report_length = (u16) unzipped_len; | ||
597 | oops_hdr->timestamp = timestamp; | ||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | static int nvram_pstore_open(struct pstore_info *psi) | 572 | static int nvram_pstore_open(struct pstore_info *psi) |
602 | { | 573 | { |
603 | /* Reset the iterator to start reading partitions again */ | 574 | /* Reset the iterator to start reading partitions again */ |
@@ -685,10 +656,9 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type, | |||
685 | unsigned int err_type, id_no, size = 0; | 656 | unsigned int err_type, id_no, size = 0; |
686 | struct nvram_os_partition *part = NULL; | 657 | struct nvram_os_partition *part = NULL; |
687 | char *buff = NULL, *big_buff = NULL; | 658 | char *buff = NULL, *big_buff = NULL; |
688 | int rc, sig = 0; | 659 | int sig = 0; |
689 | loff_t p; | 660 | loff_t p; |
690 | 661 | ||
691 | read_partition: | ||
692 | read_type++; | 662 | read_type++; |
693 | 663 | ||
694 | switch (nvram_type_ids[read_type]) { | 664 | switch (nvram_type_ids[read_type]) { |
@@ -749,30 +719,46 @@ read_partition: | |||
749 | *id = id_no; | 719 | *id = id_no; |
750 | 720 | ||
751 | if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) { | 721 | if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) { |
722 | int length, unzipped_len; | ||
723 | size_t hdr_size; | ||
724 | |||
752 | oops_hdr = (struct oops_log_info *)buff; | 725 | oops_hdr = (struct oops_log_info *)buff; |
753 | *buf = buff + sizeof(*oops_hdr); | 726 | if (oops_hdr->version < OOPS_HDR_VERSION) { |
727 | /* Old format oops header had 2-byte record size */ | ||
728 | hdr_size = sizeof(u16); | ||
729 | length = oops_hdr->version; | ||
730 | time->tv_sec = 0; | ||
731 | time->tv_nsec = 0; | ||
732 | } else { | ||
733 | hdr_size = sizeof(*oops_hdr); | ||
734 | length = oops_hdr->report_length; | ||
735 | time->tv_sec = oops_hdr->timestamp; | ||
736 | time->tv_nsec = 0; | ||
737 | } | ||
738 | *buf = kmalloc(length, GFP_KERNEL); | ||
739 | if (*buf == NULL) | ||
740 | return -ENOMEM; | ||
741 | memcpy(*buf, buff + hdr_size, length); | ||
742 | kfree(buff); | ||
754 | 743 | ||
755 | if (err_type == ERR_TYPE_KERNEL_PANIC_GZ) { | 744 | if (err_type == ERR_TYPE_KERNEL_PANIC_GZ) { |
756 | big_buff = kmalloc(big_oops_buf_sz, GFP_KERNEL); | 745 | big_buff = kmalloc(big_oops_buf_sz, GFP_KERNEL); |
757 | if (!big_buff) | 746 | if (!big_buff) |
758 | return -ENOMEM; | 747 | return -ENOMEM; |
759 | 748 | ||
760 | rc = unzip_oops(buff, big_buff); | 749 | unzipped_len = nvram_decompress(*buf, big_buff, |
750 | length, big_oops_buf_sz); | ||
761 | 751 | ||
762 | if (rc != 0) { | 752 | if (unzipped_len < 0) { |
763 | kfree(buff); | 753 | pr_err("nvram: decompression failed, returned " |
754 | "rc %d\n", unzipped_len); | ||
764 | kfree(big_buff); | 755 | kfree(big_buff); |
765 | goto read_partition; | 756 | } else { |
757 | *buf = big_buff; | ||
758 | length = unzipped_len; | ||
766 | } | 759 | } |
767 | |||
768 | oops_hdr = (struct oops_log_info *)big_buff; | ||
769 | *buf = big_buff + sizeof(*oops_hdr); | ||
770 | kfree(buff); | ||
771 | } | 760 | } |
772 | 761 | return length; | |
773 | time->tv_sec = oops_hdr->timestamp; | ||
774 | time->tv_nsec = 0; | ||
775 | return oops_hdr->report_length; | ||
776 | } | 762 | } |
777 | 763 | ||
778 | *buf = buff; | 764 | *buf = buff; |
@@ -816,6 +802,7 @@ static int nvram_pstore_init(void) | |||
816 | static void __init nvram_init_oops_partition(int rtas_partition_exists) | 802 | static void __init nvram_init_oops_partition(int rtas_partition_exists) |
817 | { | 803 | { |
818 | int rc; | 804 | int rc; |
805 | size_t size; | ||
819 | 806 | ||
820 | rc = pseries_nvram_init_os_partition(&oops_log_partition); | 807 | rc = pseries_nvram_init_os_partition(&oops_log_partition); |
821 | if (rc != 0) { | 808 | if (rc != 0) { |
@@ -844,8 +831,9 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists) | |||
844 | big_oops_buf_sz = (oops_data_sz * 100) / 45; | 831 | big_oops_buf_sz = (oops_data_sz * 100) / 45; |
845 | big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL); | 832 | big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL); |
846 | if (big_oops_buf) { | 833 | if (big_oops_buf) { |
847 | stream.workspace = kmalloc(zlib_deflate_workspacesize( | 834 | size = max(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL), |
848 | WINDOW_BITS, MEM_LEVEL), GFP_KERNEL); | 835 | zlib_inflate_workspacesize()); |
836 | stream.workspace = kmalloc(size, GFP_KERNEL); | ||
849 | if (!stream.workspace) { | 837 | if (!stream.workspace) { |
850 | pr_err("nvram: No memory for compression workspace; " | 838 | pr_err("nvram: No memory for compression workspace; " |
851 | "skipping compression of %s partition data\n", | 839 | "skipping compression of %s partition data\n", |