diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-05-26 22:00:52 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-05-26 22:00:52 -0400 |
| commit | 45f6bc5ff9c3387387f048ec85dcb4e69acf0b03 (patch) | |
| tree | d04952bb05b53a362bcd165fb910c5c1441b4c5d /arch/powerpc/kernel | |
| parent | 3138887bd8d18173f3c2baf1e43621c49090cd27 (diff) | |
| parent | e4aa937ec75df0eea0bee03bffa3303ad36c986b (diff) | |
Merge 3.10-rc3 into usb-next
We want these fixes.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/powerpc/kernel')
| -rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 6 | ||||
| -rw-r--r-- | arch/powerpc/kernel/cpu_setup_power.S | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/entry_32.S | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/entry_64.S | 33 | ||||
| -rw-r--r-- | arch/powerpc/kernel/exceptions-64e.S | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/machine_kexec_64.c | 4 | ||||
| -rw-r--r-- | arch/powerpc/kernel/misc_32.S | 11 | ||||
| -rw-r--r-- | arch/powerpc/kernel/misc_64.S | 11 | ||||
| -rw-r--r-- | arch/powerpc/kernel/pci-common.c | 12 | ||||
| -rw-r--r-- | arch/powerpc/kernel/pci_64.c | 10 | ||||
| -rw-r--r-- | arch/powerpc/kernel/pci_dn.c | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/ppc_ksyms.c | 3 | ||||
| -rw-r--r-- | arch/powerpc/kernel/process.c | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/ptrace.c | 5 | ||||
| -rw-r--r-- | arch/powerpc/kernel/rtas.c | 113 | ||||
| -rw-r--r-- | arch/powerpc/kernel/rtas_flash.c | 10 | ||||
| -rw-r--r-- | arch/powerpc/kernel/signal.c | 7 | ||||
| -rw-r--r-- | arch/powerpc/kernel/traps.c | 80 | ||||
| -rw-r--r-- | arch/powerpc/kernel/udbg.c | 3 |
19 files changed, 297 insertions, 45 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index b51a97cfedf8..6f16ffafa6f0 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
| @@ -127,6 +127,12 @@ int main(void) | |||
| 127 | DEFINE(THREAD_BESCR, offsetof(struct thread_struct, bescr)); | 127 | DEFINE(THREAD_BESCR, offsetof(struct thread_struct, bescr)); |
| 128 | DEFINE(THREAD_EBBHR, offsetof(struct thread_struct, ebbhr)); | 128 | DEFINE(THREAD_EBBHR, offsetof(struct thread_struct, ebbhr)); |
| 129 | DEFINE(THREAD_EBBRR, offsetof(struct thread_struct, ebbrr)); | 129 | DEFINE(THREAD_EBBRR, offsetof(struct thread_struct, ebbrr)); |
| 130 | DEFINE(THREAD_SIAR, offsetof(struct thread_struct, siar)); | ||
| 131 | DEFINE(THREAD_SDAR, offsetof(struct thread_struct, sdar)); | ||
| 132 | DEFINE(THREAD_SIER, offsetof(struct thread_struct, sier)); | ||
| 133 | DEFINE(THREAD_MMCR0, offsetof(struct thread_struct, mmcr0)); | ||
| 134 | DEFINE(THREAD_MMCR2, offsetof(struct thread_struct, mmcr2)); | ||
| 135 | DEFINE(THREAD_MMCRA, offsetof(struct thread_struct, mmcra)); | ||
| 130 | #endif | 136 | #endif |
| 131 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 137 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
| 132 | DEFINE(PACATMSCRATCH, offsetof(struct paca_struct, tm_scratch)); | 138 | DEFINE(PACATMSCRATCH, offsetof(struct paca_struct, tm_scratch)); |
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S index a283b6442b26..18b5b9cf8e37 100644 --- a/arch/powerpc/kernel/cpu_setup_power.S +++ b/arch/powerpc/kernel/cpu_setup_power.S | |||
| @@ -135,8 +135,12 @@ __init_HFSCR: | |||
| 135 | blr | 135 | blr |
| 136 | 136 | ||
| 137 | __init_TLB: | 137 | __init_TLB: |
| 138 | /* Clear the TLB */ | 138 | /* |
| 139 | li r6,128 | 139 | * Clear the TLB using the "IS 3" form of tlbiel instruction |
| 140 | * (invalidate by congruence class). P7 has 128 CCs, P8 has 512 | ||
| 141 | * so we just always do 512 | ||
| 142 | */ | ||
| 143 | li r6,512 | ||
| 140 | mtctr r6 | 144 | mtctr r6 |
| 141 | li r7,0xc00 /* IS field = 0b11 */ | 145 | li r7,0xc00 /* IS field = 0b11 */ |
| 142 | ptesync | 146 | ptesync |
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index e514de57a125..d22e73e4618b 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
| @@ -439,8 +439,6 @@ ret_from_fork: | |||
| 439 | ret_from_kernel_thread: | 439 | ret_from_kernel_thread: |
| 440 | REST_NVGPRS(r1) | 440 | REST_NVGPRS(r1) |
| 441 | bl schedule_tail | 441 | bl schedule_tail |
| 442 | li r3,0 | ||
| 443 | stw r3,0(r1) | ||
| 444 | mtlr r14 | 442 | mtlr r14 |
| 445 | mr r3,r15 | 443 | mr r3,r15 |
| 446 | PPC440EP_ERR42 | 444 | PPC440EP_ERR42 |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 915fbb4fc2fe..0e9095e47b5b 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <asm/irqflags.h> | 33 | #include <asm/irqflags.h> |
| 34 | #include <asm/ftrace.h> | 34 | #include <asm/ftrace.h> |
| 35 | #include <asm/hw_irq.h> | 35 | #include <asm/hw_irq.h> |
| 36 | #include <asm/context_tracking.h> | ||
| 36 | 37 | ||
| 37 | /* | 38 | /* |
| 38 | * System calls. | 39 | * System calls. |
| @@ -376,8 +377,6 @@ _GLOBAL(ret_from_fork) | |||
| 376 | _GLOBAL(ret_from_kernel_thread) | 377 | _GLOBAL(ret_from_kernel_thread) |
| 377 | bl .schedule_tail | 378 | bl .schedule_tail |
| 378 | REST_NVGPRS(r1) | 379 | REST_NVGPRS(r1) |
| 379 | li r3,0 | ||
| 380 | std r3,0(r1) | ||
| 381 | ld r14, 0(r14) | 380 | ld r14, 0(r14) |
| 382 | mtlr r14 | 381 | mtlr r14 |
| 383 | mr r3,r15 | 382 | mr r3,r15 |
| @@ -466,6 +465,20 @@ BEGIN_FTR_SECTION | |||
| 466 | std r0, THREAD_EBBHR(r3) | 465 | std r0, THREAD_EBBHR(r3) |
| 467 | mfspr r0, SPRN_EBBRR | 466 | mfspr r0, SPRN_EBBRR |
| 468 | std r0, THREAD_EBBRR(r3) | 467 | std r0, THREAD_EBBRR(r3) |
| 468 | |||
| 469 | /* PMU registers made user read/(write) by EBB */ | ||
| 470 | mfspr r0, SPRN_SIAR | ||
| 471 | std r0, THREAD_SIAR(r3) | ||
| 472 | mfspr r0, SPRN_SDAR | ||
| 473 | std r0, THREAD_SDAR(r3) | ||
| 474 | mfspr r0, SPRN_SIER | ||
| 475 | std r0, THREAD_SIER(r3) | ||
| 476 | mfspr r0, SPRN_MMCR0 | ||
| 477 | std r0, THREAD_MMCR0(r3) | ||
| 478 | mfspr r0, SPRN_MMCR2 | ||
| 479 | std r0, THREAD_MMCR2(r3) | ||
| 480 | mfspr r0, SPRN_MMCRA | ||
| 481 | std r0, THREAD_MMCRA(r3) | ||
| 469 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | 482 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) |
| 470 | #endif | 483 | #endif |
| 471 | 484 | ||
| @@ -561,6 +574,20 @@ BEGIN_FTR_SECTION | |||
| 561 | ld r0, THREAD_EBBRR(r4) | 574 | ld r0, THREAD_EBBRR(r4) |
| 562 | mtspr SPRN_EBBRR, r0 | 575 | mtspr SPRN_EBBRR, r0 |
| 563 | 576 | ||
| 577 | /* PMU registers made user read/(write) by EBB */ | ||
| 578 | ld r0, THREAD_SIAR(r4) | ||
| 579 | mtspr SPRN_SIAR, r0 | ||
| 580 | ld r0, THREAD_SDAR(r4) | ||
| 581 | mtspr SPRN_SDAR, r0 | ||
| 582 | ld r0, THREAD_SIER(r4) | ||
| 583 | mtspr SPRN_SIER, r0 | ||
| 584 | ld r0, THREAD_MMCR0(r4) | ||
| 585 | mtspr SPRN_MMCR0, r0 | ||
| 586 | ld r0, THREAD_MMCR2(r4) | ||
| 587 | mtspr SPRN_MMCR2, r0 | ||
| 588 | ld r0, THREAD_MMCRA(r4) | ||
| 589 | mtspr SPRN_MMCRA, r0 | ||
| 590 | |||
| 564 | ld r0,THREAD_TAR(r4) | 591 | ld r0,THREAD_TAR(r4) |
| 565 | mtspr SPRN_TAR,r0 | 592 | mtspr SPRN_TAR,r0 |
| 566 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) | 593 | END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) |
| @@ -634,7 +661,7 @@ _GLOBAL(ret_from_except_lite) | |||
| 634 | andi. r0,r4,_TIF_NEED_RESCHED | 661 | andi. r0,r4,_TIF_NEED_RESCHED |
| 635 | beq 1f | 662 | beq 1f |
| 636 | bl .restore_interrupts | 663 | bl .restore_interrupts |
| 637 | bl .schedule | 664 | SCHEDULE_USER |
| 638 | b .ret_from_except_lite | 665 | b .ret_from_except_lite |
| 639 | 666 | ||
| 640 | 1: bl .save_nvgprs | 667 | 1: bl .save_nvgprs |
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 42a756eec9ff..645170a07ada 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S | |||
| @@ -489,7 +489,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
| 489 | */ | 489 | */ |
| 490 | 490 | ||
| 491 | mfspr r14,SPRN_DBSR /* check single-step/branch taken */ | 491 | mfspr r14,SPRN_DBSR /* check single-step/branch taken */ |
| 492 | andis. r15,r14,DBSR_IC@h | 492 | andis. r15,r14,(DBSR_IC|DBSR_BT)@h |
| 493 | beq+ 1f | 493 | beq+ 1f |
| 494 | 494 | ||
| 495 | LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) | 495 | LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) |
| @@ -500,7 +500,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
| 500 | bge+ cr1,1f | 500 | bge+ cr1,1f |
| 501 | 501 | ||
| 502 | /* here it looks like we got an inappropriate debug exception. */ | 502 | /* here it looks like we got an inappropriate debug exception. */ |
| 503 | lis r14,DBSR_IC@h /* clear the IC event */ | 503 | lis r14,(DBSR_IC|DBSR_BT)@h /* clear the event */ |
| 504 | rlwinm r11,r11,0,~MSR_DE /* clear DE in the CSRR1 value */ | 504 | rlwinm r11,r11,0,~MSR_DE /* clear DE in the CSRR1 value */ |
| 505 | mtspr SPRN_DBSR,r14 | 505 | mtspr SPRN_DBSR,r14 |
| 506 | mtspr SPRN_CSRR1,r11 | 506 | mtspr SPRN_CSRR1,r11 |
| @@ -555,7 +555,7 @@ kernel_dbg_exc: | |||
| 555 | */ | 555 | */ |
| 556 | 556 | ||
| 557 | mfspr r14,SPRN_DBSR /* check single-step/branch taken */ | 557 | mfspr r14,SPRN_DBSR /* check single-step/branch taken */ |
| 558 | andis. r15,r14,DBSR_IC@h | 558 | andis. r15,r14,(DBSR_IC|DBSR_BT)@h |
| 559 | beq+ 1f | 559 | beq+ 1f |
| 560 | 560 | ||
| 561 | LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) | 561 | LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) |
| @@ -566,7 +566,7 @@ kernel_dbg_exc: | |||
| 566 | bge+ cr1,1f | 566 | bge+ cr1,1f |
| 567 | 567 | ||
| 568 | /* here it looks like we got an inappropriate debug exception. */ | 568 | /* here it looks like we got an inappropriate debug exception. */ |
| 569 | lis r14,DBSR_IC@h /* clear the IC event */ | 569 | lis r14,(DBSR_IC|DBSR_BT)@h /* clear the event */ |
| 570 | rlwinm r11,r11,0,~MSR_DE /* clear DE in the DSRR1 value */ | 570 | rlwinm r11,r11,0,~MSR_DE /* clear DE in the DSRR1 value */ |
| 571 | mtspr SPRN_DBSR,r14 | 571 | mtspr SPRN_DBSR,r14 |
| 572 | mtspr SPRN_DSRR1,r11 | 572 | mtspr SPRN_DSRR1,r11 |
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 466a2908bb63..611acdf30096 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
| 18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| 19 | #include <linux/cpu.h> | 19 | #include <linux/cpu.h> |
| 20 | #include <linux/hardirq.h> | ||
| 20 | 21 | ||
| 21 | #include <asm/page.h> | 22 | #include <asm/page.h> |
| 22 | #include <asm/current.h> | 23 | #include <asm/current.h> |
| @@ -335,10 +336,13 @@ void default_machine_kexec(struct kimage *image) | |||
| 335 | pr_debug("kexec: Starting switchover sequence.\n"); | 336 | pr_debug("kexec: Starting switchover sequence.\n"); |
| 336 | 337 | ||
| 337 | /* switch to a staticly allocated stack. Based on irq stack code. | 338 | /* switch to a staticly allocated stack. Based on irq stack code. |
| 339 | * We setup preempt_count to avoid using VMX in memcpy. | ||
| 338 | * XXX: the task struct will likely be invalid once we do the copy! | 340 | * XXX: the task struct will likely be invalid once we do the copy! |
| 339 | */ | 341 | */ |
| 340 | kexec_stack.thread_info.task = current_thread_info()->task; | 342 | kexec_stack.thread_info.task = current_thread_info()->task; |
| 341 | kexec_stack.thread_info.flags = 0; | 343 | kexec_stack.thread_info.flags = 0; |
| 344 | kexec_stack.thread_info.preempt_count = HARDIRQ_OFFSET; | ||
| 345 | kexec_stack.thread_info.cpu = current_thread_info()->cpu; | ||
| 342 | 346 | ||
| 343 | /* We need a static PACA, too; copy this CPU's PACA over and switch to | 347 | /* We need a static PACA, too; copy this CPU's PACA over and switch to |
| 344 | * it. Also poison per_cpu_offset to catch anyone using non-static | 348 | * it. Also poison per_cpu_offset to catch anyone using non-static |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 19e096bd0e73..e469f30e6eeb 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
| @@ -657,6 +657,17 @@ _GLOBAL(__ucmpdi2) | |||
| 657 | li r3,2 | 657 | li r3,2 |
| 658 | blr | 658 | blr |
| 659 | 659 | ||
| 660 | _GLOBAL(__bswapdi2) | ||
| 661 | rotlwi r9,r4,8 | ||
| 662 | rotlwi r10,r3,8 | ||
| 663 | rlwimi r9,r4,24,0,7 | ||
| 664 | rlwimi r10,r3,24,0,7 | ||
| 665 | rlwimi r9,r4,24,16,23 | ||
| 666 | rlwimi r10,r3,24,16,23 | ||
| 667 | mr r3,r9 | ||
| 668 | mr r4,r10 | ||
| 669 | blr | ||
| 670 | |||
| 660 | _GLOBAL(abs) | 671 | _GLOBAL(abs) |
| 661 | srawi r4,r3,31 | 672 | srawi r4,r3,31 |
| 662 | xor r3,r3,r4 | 673 | xor r3,r3,r4 |
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 5cfa8008693b..6820e45f557b 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S | |||
| @@ -234,6 +234,17 @@ _GLOBAL(__flush_dcache_icache) | |||
| 234 | isync | 234 | isync |
| 235 | blr | 235 | blr |
| 236 | 236 | ||
| 237 | _GLOBAL(__bswapdi2) | ||
| 238 | srdi r8,r3,32 | ||
| 239 | rlwinm r7,r3,8,0xffffffff | ||
| 240 | rlwimi r7,r3,24,0,7 | ||
| 241 | rlwinm r9,r8,8,0xffffffff | ||
| 242 | rlwimi r7,r3,24,16,23 | ||
| 243 | rlwimi r9,r8,24,0,7 | ||
| 244 | rlwimi r9,r8,24,16,23 | ||
| 245 | sldi r7,r7,32 | ||
| 246 | or r3,r7,r9 | ||
| 247 | blr | ||
| 237 | 248 | ||
| 238 | #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) | 249 | #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) |
| 239 | /* | 250 | /* |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index f5c5c90799a7..e9acf50dd5b2 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
| @@ -359,7 +359,6 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | |||
| 359 | enum pci_mmap_state mmap_state, | 359 | enum pci_mmap_state mmap_state, |
| 360 | int write_combine) | 360 | int write_combine) |
| 361 | { | 361 | { |
| 362 | unsigned long prot = pgprot_val(protection); | ||
| 363 | 362 | ||
| 364 | /* Write combine is always 0 on non-memory space mappings. On | 363 | /* Write combine is always 0 on non-memory space mappings. On |
| 365 | * memory space, if the user didn't pass 1, we check for a | 364 | * memory space, if the user didn't pass 1, we check for a |
| @@ -376,9 +375,9 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | |||
| 376 | 375 | ||
| 377 | /* XXX would be nice to have a way to ask for write-through */ | 376 | /* XXX would be nice to have a way to ask for write-through */ |
| 378 | if (write_combine) | 377 | if (write_combine) |
| 379 | return pgprot_noncached_wc(prot); | 378 | return pgprot_noncached_wc(protection); |
| 380 | else | 379 | else |
| 381 | return pgprot_noncached(prot); | 380 | return pgprot_noncached(protection); |
| 382 | } | 381 | } |
| 383 | 382 | ||
| 384 | /* | 383 | /* |
| @@ -1521,9 +1520,10 @@ static void pcibios_setup_phb_resources(struct pci_controller *hose, | |||
| 1521 | for (i = 0; i < 3; ++i) { | 1520 | for (i = 0; i < 3; ++i) { |
| 1522 | res = &hose->mem_resources[i]; | 1521 | res = &hose->mem_resources[i]; |
| 1523 | if (!res->flags) { | 1522 | if (!res->flags) { |
| 1524 | printk(KERN_ERR "PCI: Memory resource 0 not set for " | 1523 | if (i == 0) |
| 1525 | "host bridge %s (domain %d)\n", | 1524 | printk(KERN_ERR "PCI: Memory resource 0 not set for " |
| 1526 | hose->dn->full_name, hose->global_number); | 1525 | "host bridge %s (domain %d)\n", |
| 1526 | hose->dn->full_name, hose->global_number); | ||
| 1527 | continue; | 1527 | continue; |
| 1528 | } | 1528 | } |
| 1529 | offset = hose->mem_offset[i]; | 1529 | offset = hose->mem_offset[i]; |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 873050d26840..2e8629654ca8 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
| @@ -266,3 +266,13 @@ int pcibus_to_node(struct pci_bus *bus) | |||
| 266 | } | 266 | } |
| 267 | EXPORT_SYMBOL(pcibus_to_node); | 267 | EXPORT_SYMBOL(pcibus_to_node); |
| 268 | #endif | 268 | #endif |
| 269 | |||
| 270 | static void quirk_radeon_32bit_msi(struct pci_dev *dev) | ||
| 271 | { | ||
| 272 | struct pci_dn *pdn = pci_get_pdn(dev); | ||
| 273 | |||
| 274 | if (pdn) | ||
| 275 | pdn->force_32bit_msi = 1; | ||
| 276 | } | ||
| 277 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x68f2, quirk_radeon_32bit_msi); | ||
| 278 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0xaa68, quirk_radeon_32bit_msi); | ||
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index e7af165f8b9d..df038442548a 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c | |||
| @@ -32,6 +32,14 @@ | |||
| 32 | #include <asm/ppc-pci.h> | 32 | #include <asm/ppc-pci.h> |
| 33 | #include <asm/firmware.h> | 33 | #include <asm/firmware.h> |
| 34 | 34 | ||
| 35 | struct pci_dn *pci_get_pdn(struct pci_dev *pdev) | ||
| 36 | { | ||
| 37 | struct device_node *dn = pci_device_to_OF_node(pdev); | ||
| 38 | if (!dn) | ||
| 39 | return NULL; | ||
| 40 | return PCI_DN(dn); | ||
| 41 | } | ||
| 42 | |||
| 35 | /* | 43 | /* |
| 36 | * Traverse_func that inits the PCI fields of the device node. | 44 | * Traverse_func that inits the PCI fields of the device node. |
| 37 | * NOTE: this *must* be done before read/write config to the device. | 45 | * NOTE: this *must* be done before read/write config to the device. |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 78b8766fd79e..c29666586998 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
| @@ -143,7 +143,8 @@ EXPORT_SYMBOL(__lshrdi3); | |||
| 143 | int __ucmpdi2(unsigned long long, unsigned long long); | 143 | int __ucmpdi2(unsigned long long, unsigned long long); |
| 144 | EXPORT_SYMBOL(__ucmpdi2); | 144 | EXPORT_SYMBOL(__ucmpdi2); |
| 145 | #endif | 145 | #endif |
| 146 | 146 | long long __bswapdi2(long long); | |
| 147 | EXPORT_SYMBOL(__bswapdi2); | ||
| 147 | EXPORT_SYMBOL(memcpy); | 148 | EXPORT_SYMBOL(memcpy); |
| 148 | EXPORT_SYMBOL(memset); | 149 | EXPORT_SYMBOL(memset); |
| 149 | EXPORT_SYMBOL(memmove); | 150 | EXPORT_SYMBOL(memmove); |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index ceb4e7b62cf4..a902723fdc69 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
| @@ -339,6 +339,13 @@ static void set_debug_reg_defaults(struct thread_struct *thread) | |||
| 339 | 339 | ||
| 340 | static void prime_debug_regs(struct thread_struct *thread) | 340 | static void prime_debug_regs(struct thread_struct *thread) |
| 341 | { | 341 | { |
| 342 | /* | ||
| 343 | * We could have inherited MSR_DE from userspace, since | ||
| 344 | * it doesn't get cleared on exception entry. Make sure | ||
| 345 | * MSR_DE is clear before we enable any debug events. | ||
| 346 | */ | ||
| 347 | mtmsr(mfmsr() & ~MSR_DE); | ||
| 348 | |||
| 342 | mtspr(SPRN_IAC1, thread->iac1); | 349 | mtspr(SPRN_IAC1, thread->iac1); |
| 343 | mtspr(SPRN_IAC2, thread->iac2); | 350 | mtspr(SPRN_IAC2, thread->iac2); |
| 344 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 | 351 | #if CONFIG_PPC_ADV_DEBUG_IACS > 2 |
| @@ -971,6 +978,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
| 971 | * do some house keeping and then return from the fork or clone | 978 | * do some house keeping and then return from the fork or clone |
| 972 | * system call, using the stack frame created above. | 979 | * system call, using the stack frame created above. |
| 973 | */ | 980 | */ |
| 981 | ((unsigned long *)sp)[0] = 0; | ||
| 974 | sp -= sizeof(struct pt_regs); | 982 | sp -= sizeof(struct pt_regs); |
| 975 | kregs = (struct pt_regs *) sp; | 983 | kregs = (struct pt_regs *) sp; |
| 976 | sp -= STACK_FRAME_OVERHEAD; | 984 | sp -= STACK_FRAME_OVERHEAD; |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 3b14d320e69f..98c2fc198712 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <trace/syscall.h> | 32 | #include <trace/syscall.h> |
| 33 | #include <linux/hw_breakpoint.h> | 33 | #include <linux/hw_breakpoint.h> |
| 34 | #include <linux/perf_event.h> | 34 | #include <linux/perf_event.h> |
| 35 | #include <linux/context_tracking.h> | ||
| 35 | 36 | ||
| 36 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
| 37 | #include <asm/page.h> | 38 | #include <asm/page.h> |
| @@ -1788,6 +1789,8 @@ long do_syscall_trace_enter(struct pt_regs *regs) | |||
| 1788 | { | 1789 | { |
| 1789 | long ret = 0; | 1790 | long ret = 0; |
| 1790 | 1791 | ||
| 1792 | user_exit(); | ||
| 1793 | |||
| 1791 | secure_computing_strict(regs->gpr[0]); | 1794 | secure_computing_strict(regs->gpr[0]); |
| 1792 | 1795 | ||
| 1793 | if (test_thread_flag(TIF_SYSCALL_TRACE) && | 1796 | if (test_thread_flag(TIF_SYSCALL_TRACE) && |
| @@ -1832,4 +1835,6 @@ void do_syscall_trace_leave(struct pt_regs *regs) | |||
| 1832 | step = test_thread_flag(TIF_SINGLESTEP); | 1835 | step = test_thread_flag(TIF_SINGLESTEP); |
| 1833 | if (step || test_thread_flag(TIF_SYSCALL_TRACE)) | 1836 | if (step || test_thread_flag(TIF_SYSCALL_TRACE)) |
| 1834 | tracehook_report_syscall_exit(regs, step); | 1837 | tracehook_report_syscall_exit(regs, step); |
| 1838 | |||
| 1839 | user_enter(); | ||
| 1835 | } | 1840 | } |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 1fd6e7b2f390..52add6f3e201 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 20 | #include <linux/capability.h> | 20 | #include <linux/capability.h> |
| 21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 22 | #include <linux/cpu.h> | ||
| 22 | #include <linux/smp.h> | 23 | #include <linux/smp.h> |
| 23 | #include <linux/completion.h> | 24 | #include <linux/completion.h> |
| 24 | #include <linux/cpumask.h> | 25 | #include <linux/cpumask.h> |
| @@ -807,6 +808,95 @@ static void rtas_percpu_suspend_me(void *info) | |||
| 807 | __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1); | 808 | __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1); |
| 808 | } | 809 | } |
| 809 | 810 | ||
| 811 | enum rtas_cpu_state { | ||
| 812 | DOWN, | ||
| 813 | UP, | ||
| 814 | }; | ||
| 815 | |||
| 816 | #ifndef CONFIG_SMP | ||
| 817 | static int rtas_cpu_state_change_mask(enum rtas_cpu_state state, | ||
| 818 | cpumask_var_t cpus) | ||
| 819 | { | ||
| 820 | if (!cpumask_empty(cpus)) { | ||
| 821 | cpumask_clear(cpus); | ||
| 822 | return -EINVAL; | ||
| 823 | } else | ||
| 824 | return 0; | ||
| 825 | } | ||
| 826 | #else | ||
| 827 | /* On return cpumask will be altered to indicate CPUs changed. | ||
| 828 | * CPUs with states changed will be set in the mask, | ||
| 829 | * CPUs with status unchanged will be unset in the mask. */ | ||
| 830 | static int rtas_cpu_state_change_mask(enum rtas_cpu_state state, | ||
| 831 | cpumask_var_t cpus) | ||
| 832 | { | ||
| 833 | int cpu; | ||
| 834 | int cpuret = 0; | ||
| 835 | int ret = 0; | ||
| 836 | |||
| 837 | if (cpumask_empty(cpus)) | ||
| 838 | return 0; | ||
| 839 | |||
| 840 | for_each_cpu(cpu, cpus) { | ||
| 841 | switch (state) { | ||
| 842 | case DOWN: | ||
| 843 | cpuret = cpu_down(cpu); | ||
| 844 | break; | ||
| 845 | case UP: | ||
| 846 | cpuret = cpu_up(cpu); | ||
| 847 | break; | ||
| 848 | } | ||
| 849 | if (cpuret) { | ||
| 850 | pr_debug("%s: cpu_%s for cpu#%d returned %d.\n", | ||
| 851 | __func__, | ||
| 852 | ((state == UP) ? "up" : "down"), | ||
| 853 | cpu, cpuret); | ||
| 854 | if (!ret) | ||
| 855 | ret = cpuret; | ||
| 856 | if (state == UP) { | ||
| 857 | /* clear bits for unchanged cpus, return */ | ||
| 858 | cpumask_shift_right(cpus, cpus, cpu); | ||
| 859 | cpumask_shift_left(cpus, cpus, cpu); | ||
| 860 | break; | ||
| 861 | } else { | ||
| 862 | /* clear bit for unchanged cpu, continue */ | ||
| 863 | cpumask_clear_cpu(cpu, cpus); | ||
| 864 | } | ||
| 865 | } | ||
| 866 | } | ||
| 867 | |||
| 868 | return ret; | ||
| 869 | } | ||
| 870 | #endif | ||
| 871 | |||
| 872 | int rtas_online_cpus_mask(cpumask_var_t cpus) | ||
| 873 | { | ||
| 874 | int ret; | ||
| 875 | |||
| 876 | ret = rtas_cpu_state_change_mask(UP, cpus); | ||
| 877 | |||
| 878 | if (ret) { | ||
| 879 | cpumask_var_t tmp_mask; | ||
| 880 | |||
| 881 | if (!alloc_cpumask_var(&tmp_mask, GFP_TEMPORARY)) | ||
| 882 | return ret; | ||
| 883 | |||
| 884 | /* Use tmp_mask to preserve cpus mask from first failure */ | ||
| 885 | cpumask_copy(tmp_mask, cpus); | ||
| 886 | rtas_offline_cpus_mask(tmp_mask); | ||
| 887 | free_cpumask_var(tmp_mask); | ||
| 888 | } | ||
| 889 | |||
| 890 | return ret; | ||
| 891 | } | ||
| 892 | EXPORT_SYMBOL(rtas_online_cpus_mask); | ||
| 893 | |||
| 894 | int rtas_offline_cpus_mask(cpumask_var_t cpus) | ||
| 895 | { | ||
| 896 | return rtas_cpu_state_change_mask(DOWN, cpus); | ||
| 897 | } | ||
| 898 | EXPORT_SYMBOL(rtas_offline_cpus_mask); | ||
| 899 | |||
| 810 | int rtas_ibm_suspend_me(struct rtas_args *args) | 900 | int rtas_ibm_suspend_me(struct rtas_args *args) |
| 811 | { | 901 | { |
| 812 | long state; | 902 | long state; |
| @@ -814,6 +904,8 @@ int rtas_ibm_suspend_me(struct rtas_args *args) | |||
| 814 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; | 904 | unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; |
| 815 | struct rtas_suspend_me_data data; | 905 | struct rtas_suspend_me_data data; |
| 816 | DECLARE_COMPLETION_ONSTACK(done); | 906 | DECLARE_COMPLETION_ONSTACK(done); |
| 907 | cpumask_var_t offline_mask; | ||
| 908 | int cpuret; | ||
| 817 | 909 | ||
| 818 | if (!rtas_service_present("ibm,suspend-me")) | 910 | if (!rtas_service_present("ibm,suspend-me")) |
| 819 | return -ENOSYS; | 911 | return -ENOSYS; |
| @@ -837,11 +929,24 @@ int rtas_ibm_suspend_me(struct rtas_args *args) | |||
| 837 | return 0; | 929 | return 0; |
| 838 | } | 930 | } |
| 839 | 931 | ||
| 932 | if (!alloc_cpumask_var(&offline_mask, GFP_TEMPORARY)) | ||
| 933 | return -ENOMEM; | ||
| 934 | |||
| 840 | atomic_set(&data.working, 0); | 935 | atomic_set(&data.working, 0); |
| 841 | atomic_set(&data.done, 0); | 936 | atomic_set(&data.done, 0); |
| 842 | atomic_set(&data.error, 0); | 937 | atomic_set(&data.error, 0); |
| 843 | data.token = rtas_token("ibm,suspend-me"); | 938 | data.token = rtas_token("ibm,suspend-me"); |
| 844 | data.complete = &done; | 939 | data.complete = &done; |
| 940 | |||
| 941 | /* All present CPUs must be online */ | ||
| 942 | cpumask_andnot(offline_mask, cpu_present_mask, cpu_online_mask); | ||
| 943 | cpuret = rtas_online_cpus_mask(offline_mask); | ||
| 944 | if (cpuret) { | ||
| 945 | pr_err("%s: Could not bring present CPUs online.\n", __func__); | ||
| 946 | atomic_set(&data.error, cpuret); | ||
| 947 | goto out; | ||
| 948 | } | ||
| 949 | |||
| 845 | stop_topology_update(); | 950 | stop_topology_update(); |
| 846 | 951 | ||
| 847 | /* Call function on all CPUs. One of us will make the | 952 | /* Call function on all CPUs. One of us will make the |
| @@ -857,6 +962,14 @@ int rtas_ibm_suspend_me(struct rtas_args *args) | |||
| 857 | 962 | ||
| 858 | start_topology_update(); | 963 | start_topology_update(); |
| 859 | 964 | ||
| 965 | /* Take down CPUs not online prior to suspend */ | ||
| 966 | cpuret = rtas_offline_cpus_mask(offline_mask); | ||
| 967 | if (cpuret) | ||
| 968 | pr_warn("%s: Could not restore CPUs to offline state.\n", | ||
| 969 | __func__); | ||
| 970 | |||
| 971 | out: | ||
| 972 | free_cpumask_var(offline_mask); | ||
| 860 | return atomic_read(&data.error); | 973 | return atomic_read(&data.error); |
| 861 | } | 974 | } |
| 862 | #else /* CONFIG_PPC_PSERIES */ | 975 | #else /* CONFIG_PPC_PSERIES */ |
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 5b3022470126..2f3cdb01506d 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c | |||
| @@ -89,6 +89,7 @@ | |||
| 89 | 89 | ||
| 90 | /* Array sizes */ | 90 | /* Array sizes */ |
| 91 | #define VALIDATE_BUF_SIZE 4096 | 91 | #define VALIDATE_BUF_SIZE 4096 |
| 92 | #define VALIDATE_MSG_LEN 256 | ||
| 92 | #define RTAS_MSG_MAXLEN 64 | 93 | #define RTAS_MSG_MAXLEN 64 |
| 93 | 94 | ||
| 94 | /* Quirk - RTAS requires 4k list length and block size */ | 95 | /* Quirk - RTAS requires 4k list length and block size */ |
| @@ -466,7 +467,7 @@ static void validate_flash(struct rtas_validate_flash_t *args_buf) | |||
| 466 | } | 467 | } |
| 467 | 468 | ||
| 468 | static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, | 469 | static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, |
| 469 | char *msg) | 470 | char *msg, int msglen) |
| 470 | { | 471 | { |
| 471 | int n; | 472 | int n; |
| 472 | 473 | ||
| @@ -474,7 +475,8 @@ static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, | |||
| 474 | n = sprintf(msg, "%d\n", args_buf->update_results); | 475 | n = sprintf(msg, "%d\n", args_buf->update_results); |
| 475 | if ((args_buf->update_results >= VALIDATE_CUR_UNKNOWN) || | 476 | if ((args_buf->update_results >= VALIDATE_CUR_UNKNOWN) || |
| 476 | (args_buf->update_results == VALIDATE_TMP_UPDATE)) | 477 | (args_buf->update_results == VALIDATE_TMP_UPDATE)) |
| 477 | n += sprintf(msg + n, "%s\n", args_buf->buf); | 478 | n += snprintf(msg + n, msglen - n, "%s\n", |
| 479 | args_buf->buf); | ||
| 478 | } else { | 480 | } else { |
| 479 | n = sprintf(msg, "%d\n", args_buf->status); | 481 | n = sprintf(msg, "%d\n", args_buf->status); |
| 480 | } | 482 | } |
| @@ -486,11 +488,11 @@ static ssize_t validate_flash_read(struct file *file, char __user *buf, | |||
| 486 | { | 488 | { |
| 487 | struct rtas_validate_flash_t *const args_buf = | 489 | struct rtas_validate_flash_t *const args_buf = |
| 488 | &rtas_validate_flash_data; | 490 | &rtas_validate_flash_data; |
| 489 | char msg[RTAS_MSG_MAXLEN]; | 491 | char msg[VALIDATE_MSG_LEN]; |
| 490 | int msglen; | 492 | int msglen; |
| 491 | 493 | ||
| 492 | mutex_lock(&rtas_validate_flash_mutex); | 494 | mutex_lock(&rtas_validate_flash_mutex); |
| 493 | msglen = get_validate_flash_msg(args_buf, msg); | 495 | msglen = get_validate_flash_msg(args_buf, msg, VALIDATE_MSG_LEN); |
| 494 | mutex_unlock(&rtas_validate_flash_mutex); | 496 | mutex_unlock(&rtas_validate_flash_mutex); |
| 495 | 497 | ||
| 496 | return simple_read_from_buffer(buf, count, ppos, msg, msglen); | 498 | return simple_read_from_buffer(buf, count, ppos, msg, msglen); |
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index cf12eae02de5..577a8aa69c6e 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/signal.h> | 13 | #include <linux/signal.h> |
| 14 | #include <linux/uprobes.h> | 14 | #include <linux/uprobes.h> |
| 15 | #include <linux/key.h> | 15 | #include <linux/key.h> |
| 16 | #include <linux/context_tracking.h> | ||
| 16 | #include <asm/hw_breakpoint.h> | 17 | #include <asm/hw_breakpoint.h> |
| 17 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
| 18 | #include <asm/unistd.h> | 19 | #include <asm/unistd.h> |
| @@ -24,7 +25,7 @@ | |||
| 24 | * through debug.exception-trace sysctl. | 25 | * through debug.exception-trace sysctl. |
| 25 | */ | 26 | */ |
| 26 | 27 | ||
| 27 | int show_unhandled_signals = 0; | 28 | int show_unhandled_signals = 1; |
| 28 | 29 | ||
| 29 | /* | 30 | /* |
| 30 | * Allocate space for the signal frame | 31 | * Allocate space for the signal frame |
| @@ -159,6 +160,8 @@ static int do_signal(struct pt_regs *regs) | |||
| 159 | 160 | ||
| 160 | void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) | 161 | void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) |
| 161 | { | 162 | { |
| 163 | user_exit(); | ||
| 164 | |||
| 162 | if (thread_info_flags & _TIF_UPROBE) | 165 | if (thread_info_flags & _TIF_UPROBE) |
| 163 | uprobe_notify_resume(regs); | 166 | uprobe_notify_resume(regs); |
| 164 | 167 | ||
| @@ -169,4 +172,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) | |||
| 169 | clear_thread_flag(TIF_NOTIFY_RESUME); | 172 | clear_thread_flag(TIF_NOTIFY_RESUME); |
| 170 | tracehook_notify_resume(regs); | 173 | tracehook_notify_resume(regs); |
| 171 | } | 174 | } |
| 175 | |||
| 176 | user_enter(); | ||
| 172 | } | 177 | } |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 83efa2f7d926..a7a648f6b750 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/kdebug.h> | 35 | #include <linux/kdebug.h> |
| 36 | #include <linux/debugfs.h> | 36 | #include <linux/debugfs.h> |
| 37 | #include <linux/ratelimit.h> | 37 | #include <linux/ratelimit.h> |
| 38 | #include <linux/context_tracking.h> | ||
| 38 | 39 | ||
| 39 | #include <asm/emulated_ops.h> | 40 | #include <asm/emulated_ops.h> |
| 40 | #include <asm/pgtable.h> | 41 | #include <asm/pgtable.h> |
| @@ -667,6 +668,7 @@ int machine_check_generic(struct pt_regs *regs) | |||
| 667 | 668 | ||
| 668 | void machine_check_exception(struct pt_regs *regs) | 669 | void machine_check_exception(struct pt_regs *regs) |
| 669 | { | 670 | { |
| 671 | enum ctx_state prev_state = exception_enter(); | ||
| 670 | int recover = 0; | 672 | int recover = 0; |
| 671 | 673 | ||
| 672 | __get_cpu_var(irq_stat).mce_exceptions++; | 674 | __get_cpu_var(irq_stat).mce_exceptions++; |
| @@ -683,7 +685,7 @@ void machine_check_exception(struct pt_regs *regs) | |||
| 683 | recover = cur_cpu_spec->machine_check(regs); | 685 | recover = cur_cpu_spec->machine_check(regs); |
| 684 | 686 | ||
| 685 | if (recover > 0) | 687 | if (recover > 0) |
| 686 | return; | 688 | goto bail; |
| 687 | 689 | ||
| 688 | #if defined(CONFIG_8xx) && defined(CONFIG_PCI) | 690 | #if defined(CONFIG_8xx) && defined(CONFIG_PCI) |
| 689 | /* the qspan pci read routines can cause machine checks -- Cort | 691 | /* the qspan pci read routines can cause machine checks -- Cort |
| @@ -693,20 +695,23 @@ void machine_check_exception(struct pt_regs *regs) | |||
| 693 | * -- BenH | 695 | * -- BenH |
| 694 | */ | 696 | */ |
| 695 | bad_page_fault(regs, regs->dar, SIGBUS); | 697 | bad_page_fault(regs, regs->dar, SIGBUS); |
| 696 | return; | 698 | goto bail; |
| 697 | #endif | 699 | #endif |
| 698 | 700 | ||
| 699 | if (debugger_fault_handler(regs)) | 701 | if (debugger_fault_handler(regs)) |
| 700 | return; | 702 | goto bail; |
| 701 | 703 | ||
| 702 | if (check_io_access(regs)) | 704 | if (check_io_access(regs)) |
| 703 | return; | 705 | goto bail; |
| 704 | 706 | ||
| 705 | die("Machine check", regs, SIGBUS); | 707 | die("Machine check", regs, SIGBUS); |
| 706 | 708 | ||
| 707 | /* Must die if the interrupt is not recoverable */ | 709 | /* Must die if the interrupt is not recoverable */ |
| 708 | if (!(regs->msr & MSR_RI)) | 710 | if (!(regs->msr & MSR_RI)) |
| 709 | panic("Unrecoverable Machine check"); | 711 | panic("Unrecoverable Machine check"); |
| 712 | |||
| 713 | bail: | ||
| 714 | exception_exit(prev_state); | ||
| 710 | } | 715 | } |
| 711 | 716 | ||
| 712 | void SMIException(struct pt_regs *regs) | 717 | void SMIException(struct pt_regs *regs) |
| @@ -716,20 +721,29 @@ void SMIException(struct pt_regs *regs) | |||
| 716 | 721 | ||
| 717 | void unknown_exception(struct pt_regs *regs) | 722 | void unknown_exception(struct pt_regs *regs) |
| 718 | { | 723 | { |
| 724 | enum ctx_state prev_state = exception_enter(); | ||
| 725 | |||
| 719 | printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", | 726 | printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", |
| 720 | regs->nip, regs->msr, regs->trap); | 727 | regs->nip, regs->msr, regs->trap); |
| 721 | 728 | ||
| 722 | _exception(SIGTRAP, regs, 0, 0); | 729 | _exception(SIGTRAP, regs, 0, 0); |
| 730 | |||
| 731 | exception_exit(prev_state); | ||
| 723 | } | 732 | } |
| 724 | 733 | ||
| 725 | void instruction_breakpoint_exception(struct pt_regs *regs) | 734 | void instruction_breakpoint_exception(struct pt_regs *regs) |
| 726 | { | 735 | { |
| 736 | enum ctx_state prev_state = exception_enter(); | ||
| 737 | |||
| 727 | if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5, | 738 | if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5, |
| 728 | 5, SIGTRAP) == NOTIFY_STOP) | 739 | 5, SIGTRAP) == NOTIFY_STOP) |
| 729 | return; | 740 | goto bail; |
| 730 | if (debugger_iabr_match(regs)) | 741 | if (debugger_iabr_match(regs)) |
| 731 | return; | 742 | goto bail; |
| 732 | _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); | 743 | _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); |
| 744 | |||
| 745 | bail: | ||
| 746 | exception_exit(prev_state); | ||
| 733 | } | 747 | } |
| 734 | 748 | ||
| 735 | void RunModeException(struct pt_regs *regs) | 749 | void RunModeException(struct pt_regs *regs) |
| @@ -739,15 +753,20 @@ void RunModeException(struct pt_regs *regs) | |||
| 739 | 753 | ||
| 740 | void __kprobes single_step_exception(struct pt_regs *regs) | 754 | void __kprobes single_step_exception(struct pt_regs *regs) |
| 741 | { | 755 | { |
| 756 | enum ctx_state prev_state = exception_enter(); | ||
| 757 | |||
| 742 | clear_single_step(regs); | 758 | clear_single_step(regs); |
| 743 | 759 | ||
| 744 | if (notify_die(DIE_SSTEP, "single_step", regs, 5, | 760 | if (notify_die(DIE_SSTEP, "single_step", regs, 5, |
| 745 | 5, SIGTRAP) == NOTIFY_STOP) | 761 | 5, SIGTRAP) == NOTIFY_STOP) |
| 746 | return; | 762 | goto bail; |
| 747 | if (debugger_sstep(regs)) | 763 | if (debugger_sstep(regs)) |
| 748 | return; | 764 | goto bail; |
| 749 | 765 | ||
| 750 | _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip); | 766 | _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip); |
| 767 | |||
| 768 | bail: | ||
| 769 | exception_exit(prev_state); | ||
| 751 | } | 770 | } |
| 752 | 771 | ||
| 753 | /* | 772 | /* |
| @@ -1005,6 +1024,7 @@ int is_valid_bugaddr(unsigned long addr) | |||
| 1005 | 1024 | ||
| 1006 | void __kprobes program_check_exception(struct pt_regs *regs) | 1025 | void __kprobes program_check_exception(struct pt_regs *regs) |
| 1007 | { | 1026 | { |
| 1027 | enum ctx_state prev_state = exception_enter(); | ||
| 1008 | unsigned int reason = get_reason(regs); | 1028 | unsigned int reason = get_reason(regs); |
| 1009 | extern int do_mathemu(struct pt_regs *regs); | 1029 | extern int do_mathemu(struct pt_regs *regs); |
| 1010 | 1030 | ||
| @@ -1014,26 +1034,26 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
| 1014 | if (reason & REASON_FP) { | 1034 | if (reason & REASON_FP) { |
| 1015 | /* IEEE FP exception */ | 1035 | /* IEEE FP exception */ |
| 1016 | parse_fpe(regs); | 1036 | parse_fpe(regs); |
| 1017 | return; | 1037 | goto bail; |
| 1018 | } | 1038 | } |
| 1019 | if (reason & REASON_TRAP) { | 1039 | if (reason & REASON_TRAP) { |
| 1020 | /* Debugger is first in line to stop recursive faults in | 1040 | /* Debugger is first in line to stop recursive faults in |
| 1021 | * rcu_lock, notify_die, or atomic_notifier_call_chain */ | 1041 | * rcu_lock, notify_die, or atomic_notifier_call_chain */ |
| 1022 | if (debugger_bpt(regs)) | 1042 | if (debugger_bpt(regs)) |
| 1023 | return; | 1043 | goto bail; |
| 1024 | 1044 | ||
| 1025 | /* trap exception */ | 1045 | /* trap exception */ |
| 1026 | if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP) | 1046 | if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP) |
| 1027 | == NOTIFY_STOP) | 1047 | == NOTIFY_STOP) |
| 1028 | return; | 1048 | goto bail; |
| 1029 | 1049 | ||
| 1030 | if (!(regs->msr & MSR_PR) && /* not user-mode */ | 1050 | if (!(regs->msr & MSR_PR) && /* not user-mode */ |
| 1031 | report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { | 1051 | report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { |
| 1032 | regs->nip += 4; | 1052 | regs->nip += 4; |
| 1033 | return; | 1053 | goto bail; |
| 1034 | } | 1054 | } |
| 1035 | _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); | 1055 | _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); |
| 1036 | return; | 1056 | goto bail; |
| 1037 | } | 1057 | } |
| 1038 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM | 1058 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
| 1039 | if (reason & REASON_TM) { | 1059 | if (reason & REASON_TM) { |
| @@ -1049,7 +1069,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
| 1049 | if (!user_mode(regs) && | 1069 | if (!user_mode(regs) && |
| 1050 | report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { | 1070 | report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { |
| 1051 | regs->nip += 4; | 1071 | regs->nip += 4; |
| 1052 | return; | 1072 | goto bail; |
| 1053 | } | 1073 | } |
| 1054 | /* If usermode caused this, it's done something illegal and | 1074 | /* If usermode caused this, it's done something illegal and |
| 1055 | * gets a SIGILL slap on the wrist. We call it an illegal | 1075 | * gets a SIGILL slap on the wrist. We call it an illegal |
| @@ -1059,7 +1079,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
| 1059 | */ | 1079 | */ |
| 1060 | if (user_mode(regs)) { | 1080 | if (user_mode(regs)) { |
| 1061 | _exception(SIGILL, regs, ILL_ILLOPN, regs->nip); | 1081 | _exception(SIGILL, regs, ILL_ILLOPN, regs->nip); |
| 1062 | return; | 1082 | goto bail; |
| 1063 | } else { | 1083 | } else { |
| 1064 | printk(KERN_EMERG "Unexpected TM Bad Thing exception " | 1084 | printk(KERN_EMERG "Unexpected TM Bad Thing exception " |
| 1065 | "at %lx (msr 0x%x)\n", regs->nip, reason); | 1085 | "at %lx (msr 0x%x)\n", regs->nip, reason); |
| @@ -1083,16 +1103,16 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
| 1083 | switch (do_mathemu(regs)) { | 1103 | switch (do_mathemu(regs)) { |
| 1084 | case 0: | 1104 | case 0: |
| 1085 | emulate_single_step(regs); | 1105 | emulate_single_step(regs); |
| 1086 | return; | 1106 | goto bail; |
| 1087 | case 1: { | 1107 | case 1: { |
| 1088 | int code = 0; | 1108 | int code = 0; |
| 1089 | code = __parse_fpscr(current->thread.fpscr.val); | 1109 | code = __parse_fpscr(current->thread.fpscr.val); |
| 1090 | _exception(SIGFPE, regs, code, regs->nip); | 1110 | _exception(SIGFPE, regs, code, regs->nip); |
| 1091 | return; | 1111 | goto bail; |
| 1092 | } | 1112 | } |
| 1093 | case -EFAULT: | 1113 | case -EFAULT: |
| 1094 | _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); | 1114 | _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); |
| 1095 | return; | 1115 | goto bail; |
| 1096 | } | 1116 | } |
| 1097 | /* fall through on any other errors */ | 1117 | /* fall through on any other errors */ |
| 1098 | #endif /* CONFIG_MATH_EMULATION */ | 1118 | #endif /* CONFIG_MATH_EMULATION */ |
| @@ -1103,10 +1123,10 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
| 1103 | case 0: | 1123 | case 0: |
| 1104 | regs->nip += 4; | 1124 | regs->nip += 4; |
| 1105 | emulate_single_step(regs); | 1125 | emulate_single_step(regs); |
| 1106 | return; | 1126 | goto bail; |
| 1107 | case -EFAULT: | 1127 | case -EFAULT: |
| 1108 | _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); | 1128 | _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); |
| 1109 | return; | 1129 | goto bail; |
| 1110 | } | 1130 | } |
| 1111 | } | 1131 | } |
| 1112 | 1132 | ||
| @@ -1114,10 +1134,14 @@ void __kprobes program_check_exception(struct pt_regs *regs) | |||
| 1114 | _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); | 1134 | _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); |
| 1115 | else | 1135 | else |
| 1116 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); | 1136 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); |
| 1137 | |||
| 1138 | bail: | ||
| 1139 | exception_exit(prev_state); | ||
| 1117 | } | 1140 | } |
| 1118 | 1141 | ||
| 1119 | void alignment_exception(struct pt_regs *regs) | 1142 | void alignment_exception(struct pt_regs *regs) |
| 1120 | { | 1143 | { |
| 1144 | enum ctx_state prev_state = exception_enter(); | ||
| 1121 | int sig, code, fixed = 0; | 1145 | int sig, code, fixed = 0; |
| 1122 | 1146 | ||
| 1123 | /* We restore the interrupt state now */ | 1147 | /* We restore the interrupt state now */ |
| @@ -1131,7 +1155,7 @@ void alignment_exception(struct pt_regs *regs) | |||
| 1131 | if (fixed == 1) { | 1155 | if (fixed == 1) { |
| 1132 | regs->nip += 4; /* skip over emulated instruction */ | 1156 | regs->nip += 4; /* skip over emulated instruction */ |
| 1133 | emulate_single_step(regs); | 1157 | emulate_single_step(regs); |
| 1134 | return; | 1158 | goto bail; |
| 1135 | } | 1159 | } |
| 1136 | 1160 | ||
| 1137 | /* Operand address was bad */ | 1161 | /* Operand address was bad */ |
| @@ -1146,6 +1170,9 @@ void alignment_exception(struct pt_regs *regs) | |||
| 1146 | _exception(sig, regs, code, regs->dar); | 1170 | _exception(sig, regs, code, regs->dar); |
| 1147 | else | 1171 | else |
| 1148 | bad_page_fault(regs, regs->dar, sig); | 1172 | bad_page_fault(regs, regs->dar, sig); |
| 1173 | |||
| 1174 | bail: | ||
| 1175 | exception_exit(prev_state); | ||
| 1149 | } | 1176 | } |
| 1150 | 1177 | ||
| 1151 | void StackOverflow(struct pt_regs *regs) | 1178 | void StackOverflow(struct pt_regs *regs) |
| @@ -1174,23 +1201,32 @@ void trace_syscall(struct pt_regs *regs) | |||
| 1174 | 1201 | ||
| 1175 | void kernel_fp_unavailable_exception(struct pt_regs *regs) | 1202 | void kernel_fp_unavailable_exception(struct pt_regs *regs) |
| 1176 | { | 1203 | { |
| 1204 | enum ctx_state prev_state = exception_enter(); | ||
| 1205 | |||
| 1177 | printk(KERN_EMERG "Unrecoverable FP Unavailable Exception " | 1206 | printk(KERN_EMERG "Unrecoverable FP Unavailable Exception " |
| 1178 | "%lx at %lx\n", regs->trap, regs->nip); | 1207 | "%lx at %lx\n", regs->trap, regs->nip); |
| 1179 | die("Unrecoverable FP Unavailable Exception", regs, SIGABRT); | 1208 | die("Unrecoverable FP Unavailable Exception", regs, SIGABRT); |
| 1209 | |||
| 1210 | exception_exit(prev_state); | ||
| 1180 | } | 1211 | } |
| 1181 | 1212 | ||
| 1182 | void altivec_unavailable_exception(struct pt_regs *regs) | 1213 | void altivec_unavailable_exception(struct pt_regs *regs) |
| 1183 | { | 1214 | { |
| 1215 | enum ctx_state prev_state = exception_enter(); | ||
| 1216 | |||
| 1184 | if (user_mode(regs)) { | 1217 | if (user_mode(regs)) { |
| 1185 | /* A user program has executed an altivec instruction, | 1218 | /* A user program has executed an altivec instruction, |
| 1186 | but this kernel doesn't support altivec. */ | 1219 | but this kernel doesn't support altivec. */ |
| 1187 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); | 1220 | _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); |
| 1188 | return; | 1221 | goto bail; |
| 1189 | } | 1222 | } |
| 1190 | 1223 | ||
| 1191 | printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " | 1224 | printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " |
| 1192 | "%lx at %lx\n", regs->trap, regs->nip); | 1225 | "%lx at %lx\n", regs->trap, regs->nip); |
| 1193 | die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); | 1226 | die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); |
| 1227 | |||
| 1228 | bail: | ||
| 1229 | exception_exit(prev_state); | ||
| 1194 | } | 1230 | } |
| 1195 | 1231 | ||
| 1196 | void vsx_unavailable_exception(struct pt_regs *regs) | 1232 | void vsx_unavailable_exception(struct pt_regs *regs) |
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index 13b867093499..9d3fdcd66290 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c | |||
| @@ -64,6 +64,9 @@ void __init udbg_early_init(void) | |||
| 64 | udbg_init_usbgecko(); | 64 | udbg_init_usbgecko(); |
| 65 | #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP) | 65 | #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP) |
| 66 | udbg_init_wsp(); | 66 | udbg_init_wsp(); |
| 67 | #elif defined(CONFIG_PPC_EARLY_DEBUG_MEMCONS) | ||
| 68 | /* In memory console */ | ||
| 69 | udbg_init_memcons(); | ||
| 67 | #elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC) | 70 | #elif defined(CONFIG_PPC_EARLY_DEBUG_EHV_BC) |
| 68 | udbg_init_ehv_bc(); | 71 | udbg_init_ehv_bc(); |
| 69 | #elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC) | 72 | #elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC) |
