diff options
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/align.c | 52 | ||||
-rw-r--r-- | arch/powerpc/kernel/cpu_setup_power.S | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 8 | ||||
-rw-r--r-- | arch/powerpc/kernel/paca.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/process.c | 34 | ||||
-rw-r--r-- | arch/powerpc/kernel/prom.c | 58 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtas.c | 15 | ||||
-rw-r--r-- | arch/powerpc/kernel/rtasd.c | 24 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup-common.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_32.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 29 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_32.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_64.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/tm.S | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 1 |
15 files changed, 163 insertions, 74 deletions
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index de91f3ae631e..94908af308d8 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c | |||
@@ -73,7 +73,7 @@ static struct aligninfo aligninfo[128] = { | |||
73 | { 8, LD+F }, /* 00 0 1001: lfd */ | 73 | { 8, LD+F }, /* 00 0 1001: lfd */ |
74 | { 4, ST+F+S }, /* 00 0 1010: stfs */ | 74 | { 4, ST+F+S }, /* 00 0 1010: stfs */ |
75 | { 8, ST+F }, /* 00 0 1011: stfd */ | 75 | { 8, ST+F }, /* 00 0 1011: stfd */ |
76 | INVALID, /* 00 0 1100 */ | 76 | { 16, LD }, /* 00 0 1100: lq */ |
77 | { 8, LD }, /* 00 0 1101: ld/ldu/lwa */ | 77 | { 8, LD }, /* 00 0 1101: ld/ldu/lwa */ |
78 | INVALID, /* 00 0 1110 */ | 78 | INVALID, /* 00 0 1110 */ |
79 | { 8, ST }, /* 00 0 1111: std/stdu */ | 79 | { 8, ST }, /* 00 0 1111: std/stdu */ |
@@ -140,7 +140,7 @@ static struct aligninfo aligninfo[128] = { | |||
140 | { 2, LD+SW }, /* 10 0 1100: lhbrx */ | 140 | { 2, LD+SW }, /* 10 0 1100: lhbrx */ |
141 | { 4, LD+SE }, /* 10 0 1101 lwa */ | 141 | { 4, LD+SE }, /* 10 0 1101 lwa */ |
142 | { 2, ST+SW }, /* 10 0 1110: sthbrx */ | 142 | { 2, ST+SW }, /* 10 0 1110: sthbrx */ |
143 | INVALID, /* 10 0 1111 */ | 143 | { 16, ST }, /* 10 0 1111: stq */ |
144 | INVALID, /* 10 1 0000 */ | 144 | INVALID, /* 10 1 0000 */ |
145 | INVALID, /* 10 1 0001 */ | 145 | INVALID, /* 10 1 0001 */ |
146 | INVALID, /* 10 1 0010 */ | 146 | INVALID, /* 10 1 0010 */ |
@@ -385,8 +385,6 @@ static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg, | |||
385 | char *ptr1 = (char *) ¤t->thread.TS_FPR(reg+1); | 385 | char *ptr1 = (char *) ¤t->thread.TS_FPR(reg+1); |
386 | int i, ret, sw = 0; | 386 | int i, ret, sw = 0; |
387 | 387 | ||
388 | if (!(flags & F)) | ||
389 | return 0; | ||
390 | if (reg & 1) | 388 | if (reg & 1) |
391 | return 0; /* invalid form: FRS/FRT must be even */ | 389 | return 0; /* invalid form: FRS/FRT must be even */ |
392 | if (flags & SW) | 390 | if (flags & SW) |
@@ -406,6 +404,34 @@ static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg, | |||
406 | return 1; /* exception handled and fixed up */ | 404 | return 1; /* exception handled and fixed up */ |
407 | } | 405 | } |
408 | 406 | ||
407 | #ifdef CONFIG_PPC64 | ||
408 | static int emulate_lq_stq(struct pt_regs *regs, unsigned char __user *addr, | ||
409 | unsigned int reg, unsigned int flags) | ||
410 | { | ||
411 | char *ptr0 = (char *)®s->gpr[reg]; | ||
412 | char *ptr1 = (char *)®s->gpr[reg+1]; | ||
413 | int i, ret, sw = 0; | ||
414 | |||
415 | if (reg & 1) | ||
416 | return 0; /* invalid form: GPR must be even */ | ||
417 | if (flags & SW) | ||
418 | sw = 7; | ||
419 | ret = 0; | ||
420 | for (i = 0; i < 8; ++i) { | ||
421 | if (!(flags & ST)) { | ||
422 | ret |= __get_user(ptr0[i^sw], addr + i); | ||
423 | ret |= __get_user(ptr1[i^sw], addr + i + 8); | ||
424 | } else { | ||
425 | ret |= __put_user(ptr0[i^sw], addr + i); | ||
426 | ret |= __put_user(ptr1[i^sw], addr + i + 8); | ||
427 | } | ||
428 | } | ||
429 | if (ret) | ||
430 | return -EFAULT; | ||
431 | return 1; /* exception handled and fixed up */ | ||
432 | } | ||
433 | #endif /* CONFIG_PPC64 */ | ||
434 | |||
409 | #ifdef CONFIG_SPE | 435 | #ifdef CONFIG_SPE |
410 | 436 | ||
411 | static struct aligninfo spe_aligninfo[32] = { | 437 | static struct aligninfo spe_aligninfo[32] = { |
@@ -914,10 +940,20 @@ int fix_alignment(struct pt_regs *regs) | |||
914 | flush_fp_to_thread(current); | 940 | flush_fp_to_thread(current); |
915 | } | 941 | } |
916 | 942 | ||
917 | /* Special case for 16-byte FP loads and stores */ | 943 | if ((nb == 16)) { |
918 | if (nb == 16) { | 944 | if (flags & F) { |
919 | PPC_WARN_ALIGNMENT(fp_pair, regs); | 945 | /* Special case for 16-byte FP loads and stores */ |
920 | return emulate_fp_pair(addr, reg, flags); | 946 | PPC_WARN_ALIGNMENT(fp_pair, regs); |
947 | return emulate_fp_pair(addr, reg, flags); | ||
948 | } else { | ||
949 | #ifdef CONFIG_PPC64 | ||
950 | /* Special case for 16-byte loads and stores */ | ||
951 | PPC_WARN_ALIGNMENT(lq_stq, regs); | ||
952 | return emulate_lq_stq(regs, addr, reg, flags); | ||
953 | #else | ||
954 | return 0; | ||
955 | #endif | ||
956 | } | ||
921 | } | 957 | } |
922 | 958 | ||
923 | PPC_WARN_ALIGNMENT(unaligned, regs); | 959 | PPC_WARN_ALIGNMENT(unaligned, regs); |
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S index 37d1bb002aa9..1557e7c2c7e1 100644 --- a/arch/powerpc/kernel/cpu_setup_power.S +++ b/arch/powerpc/kernel/cpu_setup_power.S | |||
@@ -56,7 +56,6 @@ _GLOBAL(__setup_cpu_power8) | |||
56 | li r0,0 | 56 | li r0,0 |
57 | mtspr SPRN_LPID,r0 | 57 | mtspr SPRN_LPID,r0 |
58 | mfspr r3,SPRN_LPCR | 58 | mfspr r3,SPRN_LPCR |
59 | oris r3, r3, LPCR_AIL_3@h | ||
60 | bl __init_LPCR | 59 | bl __init_LPCR |
61 | bl __init_HFSCR | 60 | bl __init_HFSCR |
62 | bl __init_tlb_power8 | 61 | bl __init_tlb_power8 |
@@ -75,7 +74,6 @@ _GLOBAL(__restore_cpu_power8) | |||
75 | li r0,0 | 74 | li r0,0 |
76 | mtspr SPRN_LPID,r0 | 75 | mtspr SPRN_LPID,r0 |
77 | mfspr r3,SPRN_LPCR | 76 | mfspr r3,SPRN_LPCR |
78 | oris r3, r3, LPCR_AIL_3@h | ||
79 | bl __init_LPCR | 77 | bl __init_LPCR |
80 | bl __init_HFSCR | 78 | bl __init_HFSCR |
81 | bl __init_tlb_power8 | 79 | bl __init_tlb_power8 |
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index d9c650ec7dac..3afd3915921a 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S | |||
@@ -54,14 +54,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \ | |||
54 | xori r12,r12,MSR_LE ; \ | 54 | xori r12,r12,MSR_LE ; \ |
55 | mtspr SPRN_SRR1,r12 ; \ | 55 | mtspr SPRN_SRR1,r12 ; \ |
56 | rfid ; /* return to userspace */ \ | 56 | rfid ; /* return to userspace */ \ |
57 | b . ; \ | ||
58 | 2: mfspr r12,SPRN_SRR1 ; \ | ||
59 | andi. r12,r12,MSR_PR ; \ | ||
60 | bne 0b ; \ | ||
61 | mtspr SPRN_SRR0,r3 ; \ | ||
62 | mtspr SPRN_SRR1,r4 ; \ | ||
63 | mtspr SPRN_SDR1,r5 ; \ | ||
64 | rfid ; \ | ||
65 | b . ; /* prevent speculative execution */ | 57 | b . ; /* prevent speculative execution */ |
66 | 58 | ||
67 | #if defined(CONFIG_RELOCATABLE) | 59 | #if defined(CONFIG_RELOCATABLE) |
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index bf0aada02fe4..ad302f845e5d 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
@@ -152,7 +152,8 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) | |||
152 | new_paca->paca_index = cpu; | 152 | new_paca->paca_index = cpu; |
153 | new_paca->kernel_toc = kernel_toc; | 153 | new_paca->kernel_toc = kernel_toc; |
154 | new_paca->kernelbase = (unsigned long) _stext; | 154 | new_paca->kernelbase = (unsigned long) _stext; |
155 | new_paca->kernel_msr = MSR_KERNEL; | 155 | /* Only set MSR:IR/DR when MMU is initialized */ |
156 | new_paca->kernel_msr = MSR_KERNEL & ~(MSR_IR | MSR_DR); | ||
156 | new_paca->hw_cpu_id = 0xffff; | 157 | new_paca->hw_cpu_id = 0xffff; |
157 | new_paca->kexec_state = KEXEC_STATE_NONE; | 158 | new_paca->kexec_state = KEXEC_STATE_NONE; |
158 | new_paca->__current = &init_task; | 159 | new_paca->__current = &init_task; |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index af064d28b365..31d021506d21 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -610,6 +610,31 @@ out_and_saveregs: | |||
610 | tm_save_sprs(thr); | 610 | tm_save_sprs(thr); |
611 | } | 611 | } |
612 | 612 | ||
613 | extern void __tm_recheckpoint(struct thread_struct *thread, | ||
614 | unsigned long orig_msr); | ||
615 | |||
616 | void tm_recheckpoint(struct thread_struct *thread, | ||
617 | unsigned long orig_msr) | ||
618 | { | ||
619 | unsigned long flags; | ||
620 | |||
621 | /* We really can't be interrupted here as the TEXASR registers can't | ||
622 | * change and later in the trecheckpoint code, we have a userspace R1. | ||
623 | * So let's hard disable over this region. | ||
624 | */ | ||
625 | local_irq_save(flags); | ||
626 | hard_irq_disable(); | ||
627 | |||
628 | /* The TM SPRs are restored here, so that TEXASR.FS can be set | ||
629 | * before the trecheckpoint and no explosion occurs. | ||
630 | */ | ||
631 | tm_restore_sprs(thread); | ||
632 | |||
633 | __tm_recheckpoint(thread, orig_msr); | ||
634 | |||
635 | local_irq_restore(flags); | ||
636 | } | ||
637 | |||
613 | static inline void tm_recheckpoint_new_task(struct task_struct *new) | 638 | static inline void tm_recheckpoint_new_task(struct task_struct *new) |
614 | { | 639 | { |
615 | unsigned long msr; | 640 | unsigned long msr; |
@@ -628,13 +653,10 @@ static inline void tm_recheckpoint_new_task(struct task_struct *new) | |||
628 | if (!new->thread.regs) | 653 | if (!new->thread.regs) |
629 | return; | 654 | return; |
630 | 655 | ||
631 | /* The TM SPRs are restored here, so that TEXASR.FS can be set | 656 | if (!MSR_TM_ACTIVE(new->thread.regs->msr)){ |
632 | * before the trecheckpoint and no explosion occurs. | 657 | tm_restore_sprs(&new->thread); |
633 | */ | ||
634 | tm_restore_sprs(&new->thread); | ||
635 | |||
636 | if (!MSR_TM_ACTIVE(new->thread.regs->msr)) | ||
637 | return; | 658 | return; |
659 | } | ||
638 | msr = new->thread.tm_orig_msr; | 660 | msr = new->thread.tm_orig_msr; |
639 | /* Recheckpoint to restore original checkpointed register state. */ | 661 | /* Recheckpoint to restore original checkpointed register state. */ |
640 | TM_DEBUG("*** tm_recheckpoint of pid %d " | 662 | TM_DEBUG("*** tm_recheckpoint of pid %d " |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index dd72bebd708a..668aa4791fd7 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -347,45 +347,45 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
347 | #endif | 347 | #endif |
348 | } | 348 | } |
349 | 349 | ||
350 | if (found >= 0) { | 350 | /* Not the boot CPU */ |
351 | DBG("boot cpu: logical %d physical %d\n", found, | 351 | if (found < 0) |
352 | be32_to_cpu(intserv[found_thread])); | 352 | return 0; |
353 | boot_cpuid = found; | ||
354 | set_hard_smp_processor_id(found, | ||
355 | be32_to_cpu(intserv[found_thread])); | ||
356 | 353 | ||
357 | /* | 354 | DBG("boot cpu: logical %d physical %d\n", found, |
358 | * PAPR defines "logical" PVR values for cpus that | 355 | be32_to_cpu(intserv[found_thread])); |
359 | * meet various levels of the architecture: | 356 | boot_cpuid = found; |
360 | * 0x0f000001 Architecture version 2.04 | 357 | set_hard_smp_processor_id(found, be32_to_cpu(intserv[found_thread])); |
361 | * 0x0f000002 Architecture version 2.05 | ||
362 | * If the cpu-version property in the cpu node contains | ||
363 | * such a value, we call identify_cpu again with the | ||
364 | * logical PVR value in order to use the cpu feature | ||
365 | * bits appropriate for the architecture level. | ||
366 | * | ||
367 | * A POWER6 partition in "POWER6 architected" mode | ||
368 | * uses the 0x0f000002 PVR value; in POWER5+ mode | ||
369 | * it uses 0x0f000001. | ||
370 | */ | ||
371 | prop = of_get_flat_dt_prop(node, "cpu-version", NULL); | ||
372 | if (prop && (be32_to_cpup(prop) & 0xff000000) == 0x0f000000) | ||
373 | identify_cpu(0, be32_to_cpup(prop)); | ||
374 | 358 | ||
375 | identical_pvr_fixup(node); | 359 | /* |
376 | } | 360 | * PAPR defines "logical" PVR values for cpus that |
361 | * meet various levels of the architecture: | ||
362 | * 0x0f000001 Architecture version 2.04 | ||
363 | * 0x0f000002 Architecture version 2.05 | ||
364 | * If the cpu-version property in the cpu node contains | ||
365 | * such a value, we call identify_cpu again with the | ||
366 | * logical PVR value in order to use the cpu feature | ||
367 | * bits appropriate for the architecture level. | ||
368 | * | ||
369 | * A POWER6 partition in "POWER6 architected" mode | ||
370 | * uses the 0x0f000002 PVR value; in POWER5+ mode | ||
371 | * it uses 0x0f000001. | ||
372 | */ | ||
373 | prop = of_get_flat_dt_prop(node, "cpu-version", NULL); | ||
374 | if (prop && (be32_to_cpup(prop) & 0xff000000) == 0x0f000000) | ||
375 | identify_cpu(0, be32_to_cpup(prop)); | ||
376 | |||
377 | identical_pvr_fixup(node); | ||
377 | 378 | ||
378 | check_cpu_feature_properties(node); | 379 | check_cpu_feature_properties(node); |
379 | check_cpu_pa_features(node); | 380 | check_cpu_pa_features(node); |
380 | check_cpu_slb_size(node); | 381 | check_cpu_slb_size(node); |
381 | 382 | ||
382 | #ifdef CONFIG_PPC_PSERIES | 383 | #ifdef CONFIG_PPC64 |
383 | if (nthreads > 1) | 384 | if (nthreads > 1) |
384 | cur_cpu_spec->cpu_features |= CPU_FTR_SMT; | 385 | cur_cpu_spec->cpu_features |= CPU_FTR_SMT; |
385 | else | 386 | else |
386 | cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; | 387 | cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT; |
387 | #endif | 388 | #endif |
388 | |||
389 | return 0; | 389 | return 0; |
390 | } | 390 | } |
391 | 391 | ||
@@ -747,6 +747,10 @@ void __init early_init_devtree(void *params) | |||
747 | * (altivec support, boot CPU ID, ...) | 747 | * (altivec support, boot CPU ID, ...) |
748 | */ | 748 | */ |
749 | of_scan_flat_dt(early_init_dt_scan_cpus, NULL); | 749 | of_scan_flat_dt(early_init_dt_scan_cpus, NULL); |
750 | if (boot_cpuid < 0) { | ||
751 | printk("Failed to indentify boot CPU !\n"); | ||
752 | BUG(); | ||
753 | } | ||
750 | 754 | ||
751 | #if defined(CONFIG_SMP) && defined(CONFIG_PPC64) | 755 | #if defined(CONFIG_SMP) && defined(CONFIG_PPC64) |
752 | /* We'll later wait for secondaries to check in; there are | 756 | /* We'll later wait for secondaries to check in; there are |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index f386296ff378..8cd5ed049b5d 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -993,21 +993,24 @@ struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log, | |||
993 | (struct rtas_ext_event_log_v6 *)log->buffer; | 993 | (struct rtas_ext_event_log_v6 *)log->buffer; |
994 | struct pseries_errorlog *sect; | 994 | struct pseries_errorlog *sect; |
995 | unsigned char *p, *log_end; | 995 | unsigned char *p, *log_end; |
996 | uint32_t ext_log_length = rtas_error_extended_log_length(log); | ||
997 | uint8_t log_format = rtas_ext_event_log_format(ext_log); | ||
998 | uint32_t company_id = rtas_ext_event_company_id(ext_log); | ||
996 | 999 | ||
997 | /* Check that we understand the format */ | 1000 | /* Check that we understand the format */ |
998 | if (log->extended_log_length < sizeof(struct rtas_ext_event_log_v6) || | 1001 | if (ext_log_length < sizeof(struct rtas_ext_event_log_v6) || |
999 | ext_log->log_format != RTAS_V6EXT_LOG_FORMAT_EVENT_LOG || | 1002 | log_format != RTAS_V6EXT_LOG_FORMAT_EVENT_LOG || |
1000 | ext_log->company_id != RTAS_V6EXT_COMPANY_ID_IBM) | 1003 | company_id != RTAS_V6EXT_COMPANY_ID_IBM) |
1001 | return NULL; | 1004 | return NULL; |
1002 | 1005 | ||
1003 | log_end = log->buffer + log->extended_log_length; | 1006 | log_end = log->buffer + ext_log_length; |
1004 | p = ext_log->vendor_log; | 1007 | p = ext_log->vendor_log; |
1005 | 1008 | ||
1006 | while (p < log_end) { | 1009 | while (p < log_end) { |
1007 | sect = (struct pseries_errorlog *)p; | 1010 | sect = (struct pseries_errorlog *)p; |
1008 | if (sect->id == section_id) | 1011 | if (pseries_errorlog_id(sect) == section_id) |
1009 | return sect; | 1012 | return sect; |
1010 | p += sect->length; | 1013 | p += pseries_errorlog_length(sect); |
1011 | } | 1014 | } |
1012 | 1015 | ||
1013 | return NULL; | 1016 | return NULL; |
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 1130c53ad652..e736387fee6a 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c | |||
@@ -150,8 +150,8 @@ static void printk_log_rtas(char *buf, int len) | |||
150 | struct rtas_error_log *errlog = (struct rtas_error_log *)buf; | 150 | struct rtas_error_log *errlog = (struct rtas_error_log *)buf; |
151 | 151 | ||
152 | printk(RTAS_DEBUG "event: %d, Type: %s, Severity: %d\n", | 152 | printk(RTAS_DEBUG "event: %d, Type: %s, Severity: %d\n", |
153 | error_log_cnt, rtas_event_type(errlog->type), | 153 | error_log_cnt, rtas_event_type(rtas_error_type(errlog)), |
154 | errlog->severity); | 154 | rtas_error_severity(errlog)); |
155 | } | 155 | } |
156 | } | 156 | } |
157 | 157 | ||
@@ -159,14 +159,16 @@ static int log_rtas_len(char * buf) | |||
159 | { | 159 | { |
160 | int len; | 160 | int len; |
161 | struct rtas_error_log *err; | 161 | struct rtas_error_log *err; |
162 | uint32_t extended_log_length; | ||
162 | 163 | ||
163 | /* rtas fixed header */ | 164 | /* rtas fixed header */ |
164 | len = 8; | 165 | len = 8; |
165 | err = (struct rtas_error_log *)buf; | 166 | err = (struct rtas_error_log *)buf; |
166 | if (err->extended && err->extended_log_length) { | 167 | extended_log_length = rtas_error_extended_log_length(err); |
168 | if (rtas_error_extended(err) && extended_log_length) { | ||
167 | 169 | ||
168 | /* extended header */ | 170 | /* extended header */ |
169 | len += err->extended_log_length; | 171 | len += extended_log_length; |
170 | } | 172 | } |
171 | 173 | ||
172 | if (rtas_error_log_max == 0) | 174 | if (rtas_error_log_max == 0) |
@@ -293,15 +295,13 @@ void prrn_schedule_update(u32 scope) | |||
293 | 295 | ||
294 | static void handle_rtas_event(const struct rtas_error_log *log) | 296 | static void handle_rtas_event(const struct rtas_error_log *log) |
295 | { | 297 | { |
296 | if (log->type == RTAS_TYPE_PRRN) { | 298 | if (rtas_error_type(log) != RTAS_TYPE_PRRN || !prrn_is_enabled()) |
297 | /* For PRRN Events the extended log length is used to denote | 299 | return; |
298 | * the scope for calling rtas update-nodes. | ||
299 | */ | ||
300 | if (prrn_is_enabled()) | ||
301 | prrn_schedule_update(log->extended_log_length); | ||
302 | } | ||
303 | 300 | ||
304 | return; | 301 | /* For PRRN Events the extended log length is used to denote |
302 | * the scope for calling rtas update-nodes. | ||
303 | */ | ||
304 | prrn_schedule_update(rtas_error_extended_log_length(log)); | ||
305 | } | 305 | } |
306 | 306 | ||
307 | #else | 307 | #else |
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index bc76cc6b419c..79b7612ac6fa 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c | |||
@@ -76,6 +76,9 @@ EXPORT_SYMBOL(ppc_md); | |||
76 | struct machdep_calls *machine_id; | 76 | struct machdep_calls *machine_id; |
77 | EXPORT_SYMBOL(machine_id); | 77 | EXPORT_SYMBOL(machine_id); |
78 | 78 | ||
79 | int boot_cpuid = -1; | ||
80 | EXPORT_SYMBOL_GPL(boot_cpuid); | ||
81 | |||
79 | unsigned long klimit = (unsigned long) _end; | 82 | unsigned long klimit = (unsigned long) _end; |
80 | 83 | ||
81 | char cmd_line[COMMAND_LINE_SIZE]; | 84 | char cmd_line[COMMAND_LINE_SIZE]; |
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 04cc4fcca78b..ea4fda60e57b 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -44,8 +44,6 @@ | |||
44 | 44 | ||
45 | extern void bootx_init(unsigned long r4, unsigned long phys); | 45 | extern void bootx_init(unsigned long r4, unsigned long phys); |
46 | 46 | ||
47 | int boot_cpuid = -1; | ||
48 | EXPORT_SYMBOL_GPL(boot_cpuid); | ||
49 | int boot_cpuid_phys; | 47 | int boot_cpuid_phys; |
50 | EXPORT_SYMBOL_GPL(boot_cpuid_phys); | 48 | EXPORT_SYMBOL_GPL(boot_cpuid_phys); |
51 | 49 | ||
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 4933909cc5c0..fbe24377eda3 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -74,7 +74,6 @@ | |||
74 | #define DBG(fmt...) | 74 | #define DBG(fmt...) |
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | int boot_cpuid = 0; | ||
78 | int spinning_secondaries; | 77 | int spinning_secondaries; |
79 | u64 ppc64_pft_size; | 78 | u64 ppc64_pft_size; |
80 | 79 | ||
@@ -196,6 +195,19 @@ static void fixup_boot_paca(void) | |||
196 | get_paca()->data_offset = 0; | 195 | get_paca()->data_offset = 0; |
197 | } | 196 | } |
198 | 197 | ||
198 | static void cpu_ready_for_interrupts(void) | ||
199 | { | ||
200 | /* Set IR and DR in PACA MSR */ | ||
201 | get_paca()->kernel_msr = MSR_KERNEL; | ||
202 | |||
203 | /* Enable AIL if supported */ | ||
204 | if (cpu_has_feature(CPU_FTR_HVMODE) && | ||
205 | cpu_has_feature(CPU_FTR_ARCH_207S)) { | ||
206 | unsigned long lpcr = mfspr(SPRN_LPCR); | ||
207 | mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3); | ||
208 | } | ||
209 | } | ||
210 | |||
199 | /* | 211 | /* |
200 | * Early initialization entry point. This is called by head.S | 212 | * Early initialization entry point. This is called by head.S |
201 | * with MMU translation disabled. We rely on the "feature" of | 213 | * with MMU translation disabled. We rely on the "feature" of |
@@ -262,6 +274,14 @@ void __init early_setup(unsigned long dt_ptr) | |||
262 | /* Initialize the hash table or TLB handling */ | 274 | /* Initialize the hash table or TLB handling */ |
263 | early_init_mmu(); | 275 | early_init_mmu(); |
264 | 276 | ||
277 | /* | ||
278 | * At this point, we can let interrupts switch to virtual mode | ||
279 | * (the MMU has been setup), so adjust the MSR in the PACA to | ||
280 | * have IR and DR set and enable AIL if it exists | ||
281 | */ | ||
282 | cpu_ready_for_interrupts(); | ||
283 | |||
284 | /* Reserve large chunks of memory for use by CMA for KVM */ | ||
265 | kvm_cma_reserve(); | 285 | kvm_cma_reserve(); |
266 | 286 | ||
267 | /* | 287 | /* |
@@ -294,6 +314,13 @@ void early_setup_secondary(void) | |||
294 | 314 | ||
295 | /* Initialize the hash table or TLB handling */ | 315 | /* Initialize the hash table or TLB handling */ |
296 | early_init_mmu_secondary(); | 316 | early_init_mmu_secondary(); |
317 | |||
318 | /* | ||
319 | * At this point, we can let interrupts switch to virtual mode | ||
320 | * (the MMU has been setup), so adjust the MSR in the PACA to | ||
321 | * have IR and DR set. | ||
322 | */ | ||
323 | cpu_ready_for_interrupts(); | ||
297 | } | 324 | } |
298 | 325 | ||
299 | #endif /* CONFIG_SMP */ | 326 | #endif /* CONFIG_SMP */ |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index a67e00aa3caa..4e47db686b5d 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -881,6 +881,8 @@ static long restore_tm_user_regs(struct pt_regs *regs, | |||
881 | * transactional versions should be loaded. | 881 | * transactional versions should be loaded. |
882 | */ | 882 | */ |
883 | tm_enable(); | 883 | tm_enable(); |
884 | /* Make sure the transaction is marked as failed */ | ||
885 | current->thread.tm_texasr |= TEXASR_FS; | ||
884 | /* This loads the checkpointed FP/VEC state, if used */ | 886 | /* This loads the checkpointed FP/VEC state, if used */ |
885 | tm_recheckpoint(¤t->thread, msr); | 887 | tm_recheckpoint(¤t->thread, msr); |
886 | /* Get the top half of the MSR */ | 888 | /* Get the top half of the MSR */ |
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 8d253c29649b..d501dc4dc3e6 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -527,6 +527,8 @@ static long restore_tm_sigcontexts(struct pt_regs *regs, | |||
527 | } | 527 | } |
528 | #endif | 528 | #endif |
529 | tm_enable(); | 529 | tm_enable(); |
530 | /* Make sure the transaction is marked as failed */ | ||
531 | current->thread.tm_texasr |= TEXASR_FS; | ||
530 | /* This loads the checkpointed FP/VEC state, if used */ | 532 | /* This loads the checkpointed FP/VEC state, if used */ |
531 | tm_recheckpoint(¤t->thread, msr); | 533 | tm_recheckpoint(¤t->thread, msr); |
532 | 534 | ||
diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S index ef47bcbd4352..03567c05950a 100644 --- a/arch/powerpc/kernel/tm.S +++ b/arch/powerpc/kernel/tm.S | |||
@@ -307,7 +307,7 @@ dont_backup_fp: | |||
307 | * Call with IRQs off, stacks get all out of sync for | 307 | * Call with IRQs off, stacks get all out of sync for |
308 | * some periods in here! | 308 | * some periods in here! |
309 | */ | 309 | */ |
310 | _GLOBAL(tm_recheckpoint) | 310 | _GLOBAL(__tm_recheckpoint) |
311 | mfcr r5 | 311 | mfcr r5 |
312 | mflr r0 | 312 | mflr r0 |
313 | stw r5, 8(r1) | 313 | stw r5, 8(r1) |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index df86f0ce2d36..1bd7ca298fa1 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -1868,6 +1868,7 @@ struct ppc_emulated ppc_emulated = { | |||
1868 | #ifdef CONFIG_PPC64 | 1868 | #ifdef CONFIG_PPC64 |
1869 | WARN_EMULATED_SETUP(mfdscr), | 1869 | WARN_EMULATED_SETUP(mfdscr), |
1870 | WARN_EMULATED_SETUP(mtdscr), | 1870 | WARN_EMULATED_SETUP(mtdscr), |
1871 | WARN_EMULATED_SETUP(lq_stq), | ||
1871 | #endif | 1872 | #endif |
1872 | }; | 1873 | }; |
1873 | 1874 | ||