aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/powerpc/include/asm/processor.h4
-rw-r--r--arch/powerpc/include/asm/reg.h31
-rw-r--r--arch/powerpc/include/asm/switch_to.h9
-rw-r--r--arch/powerpc/kernel/asm-offsets.c3
-rw-r--r--arch/powerpc/kernel/eeh.c2
-rw-r--r--arch/powerpc/kernel/entry_64.S36
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S5
-rw-r--r--arch/powerpc/kernel/process.c10
-rw-r--r--arch/powerpc/kernel/tm.S20
-rw-r--r--arch/powerpc/kernel/traps.c58
-rw-r--r--arch/powerpc/kvm/book3s_hv.c4
-rw-r--r--arch/powerpc/kvm/book3s_pr.c5
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c80
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
586config PPC_DENORMALISATION 586config 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 *,
15struct thread_struct; 15struct thread_struct;
16extern struct task_struct *_switch(struct thread_struct *prev, 16extern struct task_struct *_switch(struct thread_struct *prev,
17 struct thread_struct *next); 17 struct thread_struct *next);
18#ifdef CONFIG_PPC_BOOK3S_64
19static 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
25static inline void save_tar(struct thread_struct *prev) {}
26#endif
18 27
19extern void load_up_fpu(void); 28extern void load_up_fpu(void);
20extern void enable_kernel_fp(void); 29extern 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
1062static int __init eeh_init_proc(void) 1062static 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
452BEGIN_FTR_SECTION 452BEGIN_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)
5921: cmpd r0,r25 584 b 3f
5851:
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)
5973:
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)
6084: cmpd r0,r25
593 beq 2f 609 beq 2f
594 mtspr SPRN_DSCR,r0 610 mtspr SPRN_DSCR,r0
5952: 6112:
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:
855hv_facility_unavailable_relon_trampoline: 855hv_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
349restore_gprs: 359restore_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
1319void facility_unavailable_exception(struct pt_regs *regs) 1318void 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
572static 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
601static int nvram_pstore_open(struct pstore_info *psi) 572static 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
691read_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)
816static void __init nvram_init_oops_partition(int rtas_partition_exists) 802static 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",