Commit 77f63b4da4b69f65c17c45e797ddb3013b889df9

Authored by Linus Torvalds

Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc

Pull powerpc fixes from Ben Herrenschmidt:
 "This includes small series from Michael Neuling to fix a couple of
  nasty remaining problems with the new Power8 support, also targeted at
  stable 3.10, without which some new userspace accessible registers
  aren't properly context switched, and in some case, can be clobbered
  by the user of transactional memory.

  Along with that, a few slightly more minor things, such as a missing
  Kconfig option to enable handling of denorm exceptions when not
  running under a hypervisor (or userspace will randomly crash when
  hitting denorms with the vector unit), some nasty bugs in the new
  pstore oops code, and other simple bug fixes worth having in now.

  Note: I picked up the two powerpc KVM fixes as Alex Graf asked me to
  handle KVM bits while he is on vacation.  However I'll let him decide
  whether they should go to -stable or not when he is back"

* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc:
  powerpc/tm: Fix context switching TAR, PPR and DSCR SPRs
  powerpc: Save the TAR register earlier
  powerpc: Fix context switch DSCR on POWER8
  powerpc: Rework setting up H/FSCR bit definitions
  powerpc: Fix hypervisor facility unavaliable vector number
  powerpc/kvm/book3s_pr: Return appropriate error when allocation fails
  powerpc/kvm: Add signed type cast for comparation
  powerpc/eeh: Add missing procfs entry for PowerNV
  powerpc/pseries: Add backward compatibilty to read old kernel oops-log
  powerpc/pseries: Fix buffer overflow when reading from pstore
  powerpc: On POWERNV enable PPC_DENORMALISATION by default

Showing 14 changed files Side-by-side Diff

arch/powerpc/Kconfig
... ... @@ -566,7 +566,7 @@
566 566 config PPC_DENORMALISATION
567 567 bool "PowerPC denormalisation exception handling"
568 568 depends on PPC_BOOK3S_64
569   - default "n"
  569 + default "y" if PPC_POWERNV
570 570 ---help---
571 571 Add support for handling denormalisation of single precision
572 572 values. Useful for bare metal only. If unsure say Y here.
arch/powerpc/include/asm/processor.h
... ... @@ -247,6 +247,10 @@
247 247 unsigned long tm_orig_msr; /* Thread's MSR on ctx switch */
248 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 255 * Transactional FP and VSX 0-31 register set.
252 256 * NOTE: the sense of these is the opposite of the integer ckpt_regs!
arch/powerpc/include/asm/reg.h
... ... @@ -254,19 +254,28 @@
254 254 #define SPRN_HRMOR 0x139 /* Real mode offset register */
255 255 #define SPRN_HSRR0 0x13A /* Hypervisor Save/Restore 0 */
256 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 266 #define SPRN_FSCR 0x099 /* Facility Status & Control Register */
258   -#define FSCR_TAR (1 << (63-55)) /* Enable Target Address Register */
259   -#define FSCR_EBB (1 << (63-56)) /* Enable Event Based Branching */
260   -#define FSCR_DSCR (1 << (63-61)) /* Enable Data Stream Control Register */
  267 +#define FSCR_TAR __MASK(FSCR_TAR_LG)
  268 +#define FSCR_EBB __MASK(FSCR_EBB_LG)
  269 +#define FSCR_DSCR __MASK(FSCR_DSCR_LG)
261 270 #define SPRN_HFSCR 0xbe /* HV=1 Facility Status & Control Register */
262   -#define HFSCR_TAR (1 << (63-55)) /* Enable Target Address Register */
263   -#define HFSCR_EBB (1 << (63-56)) /* Enable Event Based Branching */
264   -#define HFSCR_TM (1 << (63-58)) /* Enable Transactional Memory */
265   -#define HFSCR_PM (1 << (63-60)) /* Enable prob/priv access to PMU SPRs */
266   -#define HFSCR_BHRB (1 << (63-59)) /* Enable Branch History Rolling Buffer*/
267   -#define HFSCR_DSCR (1 << (63-61)) /* Enable Data Stream Control Register */
268   -#define HFSCR_VECVSX (1 << (63-62)) /* Enable VMX/VSX */
269   -#define HFSCR_FP (1 << (63-63)) /* Enable Floating Point */
  271 +#define HFSCR_TAR __MASK(FSCR_TAR_LG)
  272 +#define HFSCR_EBB __MASK(FSCR_EBB_LG)
  273 +#define HFSCR_TM __MASK(FSCR_TM_LG)
  274 +#define HFSCR_PM __MASK(FSCR_PM_LG)
  275 +#define HFSCR_BHRB __MASK(FSCR_BHRB_LG)
  276 +#define HFSCR_DSCR __MASK(FSCR_DSCR_LG)
  277 +#define HFSCR_VECVSX __MASK(FSCR_VECVSX_LG)
  278 +#define HFSCR_FP __MASK(FSCR_FP_LG)
270 279 #define SPRN_TAR 0x32f /* Target Address Register */
271 280 #define SPRN_LPCR 0x13E /* LPAR Control Register */
272 281 #define LPCR_VPM0 (1ul << (63-0))
arch/powerpc/include/asm/switch_to.h
... ... @@ -15,6 +15,15 @@
15 15 struct thread_struct;
16 16 extern struct task_struct *_switch(struct thread_struct *prev,
17 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 28 extern void giveup_fpu(struct task_struct *);
20 29 extern void load_up_fpu(void);
arch/powerpc/kernel/asm-offsets.c
... ... @@ -138,6 +138,9 @@
138 138 DEFINE(THREAD_TM_TFHAR, offsetof(struct thread_struct, tm_tfhar));
139 139 DEFINE(THREAD_TM_TEXASR, offsetof(struct thread_struct, tm_texasr));
140 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 144 DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs));
142 145 DEFINE(THREAD_TRANSACT_VR0, offsetof(struct thread_struct,
143 146 transact_vr[0]));
arch/powerpc/kernel/eeh.c
... ... @@ -1061,7 +1061,7 @@
1061 1061  
1062 1062 static int __init eeh_init_proc(void)
1063 1063 {
1064   - if (machine_is(pseries))
  1064 + if (machine_is(pseries) || machine_is(powernv))
1065 1065 proc_create("powerpc/eeh", 0, NULL, &proc_eeh_operations);
1066 1066 return 0;
1067 1067 }
arch/powerpc/kernel/entry_64.S
... ... @@ -449,15 +449,6 @@
449 449  
450 450 #ifdef CONFIG_PPC_BOOK3S_64
451 451 BEGIN_FTR_SECTION
452   - /*
453   - * Back up the TAR across context switches. Note that the TAR is not
454   - * available for use in the kernel. (To provide this, the TAR should
455   - * be backed up/restored on exception entry/exit instead, and be in
456   - * pt_regs. FIXME, this should be in pt_regs anyway (for debug).)
457   - */
458   - mfspr r0,SPRN_TAR
459   - std r0,THREAD_TAR(r3)
460   -
461 452 /* Event based branch registers */
462 453 mfspr r0, SPRN_BESCR
463 454 std r0, THREAD_BESCR(r3)
464 455  
... ... @@ -584,9 +575,34 @@
584 575 ld r7,DSCR_DEFAULT@toc(2)
585 576 ld r0,THREAD_DSCR(r4)
586 577 cmpwi r6,0
  578 + li r8, FSCR_DSCR
587 579 bne 1f
588 580 ld r0,0(r7)
589   -1: cmpd r0,r25
  581 + b 3f
  582 +1:
  583 + BEGIN_FTR_SECTION_NESTED(70)
  584 + mfspr r6, SPRN_FSCR
  585 + or r6, r6, r8
  586 + mtspr SPRN_FSCR, r6
  587 + BEGIN_FTR_SECTION_NESTED(69)
  588 + mfspr r6, SPRN_HFSCR
  589 + or r6, r6, r8
  590 + mtspr SPRN_HFSCR, r6
  591 + END_FTR_SECTION_NESTED(CPU_FTR_HVMODE, CPU_FTR_HVMODE, 69)
  592 + b 4f
  593 + END_FTR_SECTION_NESTED(CPU_FTR_ARCH_207S, CPU_FTR_ARCH_207S, 70)
  594 +3:
  595 + BEGIN_FTR_SECTION_NESTED(70)
  596 + mfspr r6, SPRN_FSCR
  597 + andc r6, r6, r8
  598 + mtspr SPRN_FSCR, r6
  599 + BEGIN_FTR_SECTION_NESTED(69)
  600 + mfspr r6, SPRN_HFSCR
  601 + andc r6, r6, r8
  602 + mtspr SPRN_HFSCR, r6
  603 + END_FTR_SECTION_NESTED(CPU_FTR_HVMODE, CPU_FTR_HVMODE, 69)
  604 + END_FTR_SECTION_NESTED(CPU_FTR_ARCH_207S, CPU_FTR_ARCH_207S, 70)
  605 +4: cmpd r0,r25
590 606 beq 2f
591 607 mtspr SPRN_DSCR,r0
592 608 2:
arch/powerpc/kernel/exceptions-64s.S
... ... @@ -848,7 +848,7 @@
848 848 . = 0x4f80
849 849 SET_SCRATCH0(r13)
850 850 EXCEPTION_PROLOG_0(PACA_EXGEN)
851   - b facility_unavailable_relon_hv
  851 + b hv_facility_unavailable_relon_hv
852 852  
853 853 STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint)
854 854 #ifdef CONFIG_PPC_DENORMALISATION
... ... @@ -1175,6 +1175,7 @@
1175 1175 b .ret_from_except
1176 1176  
1177 1177 STD_EXCEPTION_COMMON(0xf60, facility_unavailable, .facility_unavailable_exception)
  1178 + STD_EXCEPTION_COMMON(0xf80, hv_facility_unavailable, .facility_unavailable_exception)
1178 1179  
1179 1180 .align 7
1180 1181 .globl __end_handlers
... ... @@ -1188,7 +1189,7 @@
1188 1189 STD_RELON_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable)
1189 1190 STD_RELON_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable)
1190 1191 STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable)
1191   - STD_RELON_EXCEPTION_HV_OOL(0xf80, facility_unavailable)
  1192 + STD_RELON_EXCEPTION_HV_OOL(0xf80, hv_facility_unavailable)
1192 1193  
1193 1194 #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
1194 1195 /*
arch/powerpc/kernel/process.c
... ... @@ -600,6 +600,16 @@
600 600 struct ppc64_tlb_batch *batch;
601 601 #endif
602 602  
  603 + /* Back up the TAR across context switches.
  604 + * Note that the TAR is not available for use in the kernel. (To
  605 + * provide this, the TAR should be backed up/restored on exception
  606 + * entry/exit instead, and be in pt_regs. FIXME, this should be in
  607 + * pt_regs anyway (for debug).)
  608 + * Save the TAR here before we do treclaim/trecheckpoint as these
  609 + * will change the TAR.
  610 + */
  611 + save_tar(&prev->thread);
  612 +
603 613 __switch_to_tm(prev);
604 614  
605 615 #ifdef CONFIG_SMP
arch/powerpc/kernel/tm.S
... ... @@ -233,6 +233,16 @@
233 233 std r5, _CCR(r7)
234 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 246 /* MSR and flags: We don't change CRs, and we don't need to alter
237 247 * MSR.
238 248 */
... ... @@ -347,6 +357,16 @@
347 357 mtmsr r6 /* FP/Vec off again! */
348 358  
349 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 370 /* ******************** CR,LR,CCR,MSR ********** */
351 371 ld r3, _CTR(r7)
352 372 ld r4, _LINK(r7)
arch/powerpc/kernel/traps.c
... ... @@ -44,9 +44,7 @@
44 44 #include <asm/machdep.h>
45 45 #include <asm/rtas.h>
46 46 #include <asm/pmc.h>
47   -#ifdef CONFIG_PPC32
48 47 #include <asm/reg.h>
49   -#endif
50 48 #ifdef CONFIG_PMAC_BACKLIGHT
51 49 #include <asm/backlight.h>
52 50 #endif
53 51  
54 52  
55 53  
56 54  
57 55  
58 56  
59 57  
60 58  
... ... @@ -1296,43 +1294,54 @@
1296 1294 die("Unrecoverable VSX Unavailable Exception", regs, SIGABRT);
1297 1295 }
1298 1296  
  1297 +#ifdef CONFIG_PPC64
1299 1298 void facility_unavailable_exception(struct pt_regs *regs)
1300 1299 {
1301 1300 static char *facility_strings[] = {
1302   - "FPU",
1303   - "VMX/VSX",
1304   - "DSCR",
1305   - "PMU SPRs",
1306   - "BHRB",
1307   - "TM",
1308   - "AT",
1309   - "EBB",
1310   - "TAR",
  1301 + [FSCR_FP_LG] = "FPU",
  1302 + [FSCR_VECVSX_LG] = "VMX/VSX",
  1303 + [FSCR_DSCR_LG] = "DSCR",
  1304 + [FSCR_PM_LG] = "PMU SPRs",
  1305 + [FSCR_BHRB_LG] = "BHRB",
  1306 + [FSCR_TM_LG] = "TM",
  1307 + [FSCR_EBB_LG] = "EBB",
  1308 + [FSCR_TAR_LG] = "TAR",
1311 1309 };
1312   - char *facility, *prefix;
  1310 + char *facility = "unknown";
1313 1311 u64 value;
  1312 + u8 status;
  1313 + bool hv;
1314 1314  
1315   - if (regs->trap == 0xf60) {
1316   - value = mfspr(SPRN_FSCR);
1317   - prefix = "";
1318   - } else {
  1315 + hv = (regs->trap == 0xf80);
  1316 + if (hv)
1319 1317 value = mfspr(SPRN_HFSCR);
1320   - prefix = "Hypervisor ";
  1318 + else
  1319 + value = mfspr(SPRN_FSCR);
  1320 +
  1321 + status = value >> 56;
  1322 + if (status == FSCR_DSCR_LG) {
  1323 + /* User is acessing the DSCR. Set the inherit bit and allow
  1324 + * the user to set it directly in future by setting via the
  1325 + * H/FSCR DSCR bit.
  1326 + */
  1327 + current->thread.dscr_inherit = 1;
  1328 + if (hv)
  1329 + mtspr(SPRN_HFSCR, value | HFSCR_DSCR);
  1330 + else
  1331 + mtspr(SPRN_FSCR, value | FSCR_DSCR);
  1332 + return;
1321 1333 }
1322 1334  
1323   - value = value >> 56;
  1335 + if ((status < ARRAY_SIZE(facility_strings)) &&
  1336 + facility_strings[status])
  1337 + facility = facility_strings[status];
1324 1338  
1325 1339 /* We restore the interrupt state now */
1326 1340 if (!arch_irq_disabled_regs(regs))
1327 1341 local_irq_enable();
1328 1342  
1329   - if (value < ARRAY_SIZE(facility_strings))
1330   - facility = facility_strings[value];
1331   - else
1332   - facility = "unknown";
1333   -
1334 1343 pr_err("%sFacility '%s' unavailable, exception at 0x%lx, MSR=%lx\n",
1335   - prefix, facility, regs->nip, regs->msr);
  1344 + hv ? "Hypervisor " : "", facility, regs->nip, regs->msr);
1336 1345  
1337 1346 if (user_mode(regs)) {
1338 1347 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
... ... @@ -1341,6 +1350,7 @@
1341 1350  
1342 1351 die("Unexpected facility unavailable exception", regs, SIGABRT);
1343 1352 }
  1353 +#endif
1344 1354  
1345 1355 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1346 1356  
arch/powerpc/kvm/book3s_hv.c
... ... @@ -1809,7 +1809,7 @@
1809 1809 rma_size <<= PAGE_SHIFT;
1810 1810 rmls = lpcr_rmls(rma_size);
1811 1811 err = -EINVAL;
1812   - if (rmls < 0) {
  1812 + if ((long)rmls < 0) {
1813 1813 pr_err("KVM: Can't use RMA of 0x%lx bytes\n", rma_size);
1814 1814 goto out_srcu;
1815 1815 }
... ... @@ -1874,7 +1874,7 @@
1874 1874 /* Allocate the guest's logical partition ID */
1875 1875  
1876 1876 lpid = kvmppc_alloc_lpid();
1877   - if (lpid < 0)
  1877 + if ((long)lpid < 0)
1878 1878 return -ENOMEM;
1879 1879 kvm->arch.lpid = lpid;
1880 1880  
arch/powerpc/kvm/book3s_pr.c
... ... @@ -1047,11 +1047,12 @@
1047 1047 if (err)
1048 1048 goto free_shadow_vcpu;
1049 1049  
  1050 + err = -ENOMEM;
1050 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 1052 if (!p)
1054 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 1057 #ifdef CONFIG_PPC_BOOK3S_64
1057 1058 /* default to book3s_64 (970fx) */
arch/powerpc/platforms/pseries/nvram.c
... ... @@ -569,35 +569,6 @@
569 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 572 static int nvram_pstore_open(struct pstore_info *psi)
602 573 {
603 574 /* Reset the iterator to start reading partitions again */
604 575  
... ... @@ -685,10 +656,9 @@
685 656 unsigned int err_type, id_no, size = 0;
686 657 struct nvram_os_partition *part = NULL;
687 658 char *buff = NULL, *big_buff = NULL;
688   - int rc, sig = 0;
  659 + int sig = 0;
689 660 loff_t p;
690 661  
691   -read_partition:
692 662 read_type++;
693 663  
694 664 switch (nvram_type_ids[read_type]) {
695 665  
696 666  
697 667  
698 668  
699 669  
700 670  
... ... @@ -749,30 +719,46 @@
749 719 *id = id_no;
750 720  
751 721 if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
  722 + int length, unzipped_len;
  723 + size_t hdr_size;
  724 +
752 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 744 if (err_type == ERR_TYPE_KERNEL_PANIC_GZ) {
756 745 big_buff = kmalloc(big_oops_buf_sz, GFP_KERNEL);
757 746 if (!big_buff)
758 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) {
763   - kfree(buff);
  752 + if (unzipped_len < 0) {
  753 + pr_err("nvram: decompression failed, returned "
  754 + "rc %d\n", unzipped_len);
764 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   -
773   - time->tv_sec = oops_hdr->timestamp;
774   - time->tv_nsec = 0;
775   - return oops_hdr->report_length;
  761 + return length;
776 762 }
777 763  
778 764 *buf = buff;
... ... @@ -816,6 +802,7 @@
816 802 static void __init nvram_init_oops_partition(int rtas_partition_exists)
817 803 {
818 804 int rc;
  805 + size_t size;
819 806  
820 807 rc = pseries_nvram_init_os_partition(&oops_log_partition);
821 808 if (rc != 0) {
... ... @@ -844,8 +831,9 @@
844 831 big_oops_buf_sz = (oops_data_sz * 100) / 45;
845 832 big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL);
846 833 if (big_oops_buf) {
847   - stream.workspace = kmalloc(zlib_deflate_workspacesize(
848   - WINDOW_BITS, MEM_LEVEL), GFP_KERNEL);
  834 + size = max(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
  835 + zlib_inflate_workspacesize());
  836 + stream.workspace = kmalloc(size, GFP_KERNEL);
849 837 if (!stream.workspace) {
850 838 pr_err("nvram: No memory for compression workspace; "
851 839 "skipping compression of %s partition data\n",