aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/debug.h3
-rw-r--r--arch/powerpc/include/asm/eeh.h1
-rw-r--r--arch/powerpc/include/asm/elf.h2
-rw-r--r--arch/powerpc/include/asm/hw_breakpoint.h2
-rw-r--r--arch/powerpc/include/uapi/asm/Kbuild1
-rw-r--r--arch/powerpc/kernel/eeh.c1
-rw-r--r--arch/powerpc/kernel/hw_breakpoint.c8
-rw-r--r--arch/powerpc/kernel/module_64.c2
-rw-r--r--arch/powerpc/kernel/process.c15
-rw-r--r--arch/powerpc/kernel/signal.c2
-rw-r--r--arch/powerpc/kernel/time.c3
-rw-r--r--arch/powerpc/platforms/powernv/eeh-ioda.c110
-rw-r--r--arch/powerpc/xmon/xmon.c2
13 files changed, 40 insertions, 112 deletions
diff --git a/arch/powerpc/include/asm/debug.h b/arch/powerpc/include/asm/debug.h
index d2516308ed1e..a954e4975049 100644
--- a/arch/powerpc/include/asm/debug.h
+++ b/arch/powerpc/include/asm/debug.h
@@ -46,7 +46,8 @@ static inline int debugger_break_match(struct pt_regs *regs) { return 0; }
46static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; } 46static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
47#endif 47#endif
48 48
49int set_breakpoint(struct arch_hw_breakpoint *brk); 49void set_breakpoint(struct arch_hw_breakpoint *brk);
50void __set_breakpoint(struct arch_hw_breakpoint *brk);
50#ifdef CONFIG_PPC_ADV_DEBUG_REGS 51#ifdef CONFIG_PPC_ADV_DEBUG_REGS
51extern void do_send_trap(struct pt_regs *regs, unsigned long address, 52extern void do_send_trap(struct pt_regs *regs, unsigned long address,
52 unsigned long error_code, int signal_code, int brkpt); 53 unsigned long error_code, int signal_code, int brkpt);
diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index d12529f34524..b76f58c124ca 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -109,7 +109,6 @@ struct eeh_pe {
109#define EEH_DEV_NO_HANDLER (1 << 8) /* No error handler */ 109#define EEH_DEV_NO_HANDLER (1 << 8) /* No error handler */
110#define EEH_DEV_SYSFS (1 << 9) /* Sysfs created */ 110#define EEH_DEV_SYSFS (1 << 9) /* Sysfs created */
111#define EEH_DEV_REMOVED (1 << 10) /* Removed permanently */ 111#define EEH_DEV_REMOVED (1 << 10) /* Removed permanently */
112#define EEH_DEV_FRESET (1 << 11) /* Fundamental reset */
113 112
114struct eeh_dev { 113struct eeh_dev {
115 int mode; /* EEH mode */ 114 int mode; /* EEH mode */
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 935b5e7a1436..888d8f3f2524 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -90,6 +90,8 @@ typedef elf_vrregset_t elf_fpxregset_t;
90do { \ 90do { \
91 if (((ex).e_flags & 0x3) == 2) \ 91 if (((ex).e_flags & 0x3) == 2) \
92 set_thread_flag(TIF_ELF2ABI); \ 92 set_thread_flag(TIF_ELF2ABI); \
93 else \
94 clear_thread_flag(TIF_ELF2ABI); \
93 if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ 95 if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
94 set_thread_flag(TIF_32BIT); \ 96 set_thread_flag(TIF_32BIT); \
95 else \ 97 else \
diff --git a/arch/powerpc/include/asm/hw_breakpoint.h b/arch/powerpc/include/asm/hw_breakpoint.h
index eb0f4ac75c4c..ac6432d9be46 100644
--- a/arch/powerpc/include/asm/hw_breakpoint.h
+++ b/arch/powerpc/include/asm/hw_breakpoint.h
@@ -79,7 +79,7 @@ static inline void hw_breakpoint_disable(void)
79 brk.address = 0; 79 brk.address = 0;
80 brk.type = 0; 80 brk.type = 0;
81 brk.len = 0; 81 brk.len = 0;
82 set_breakpoint(&brk); 82 __set_breakpoint(&brk);
83} 83}
84extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs); 84extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
85 85
diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild
index 48be855ef37b..7a3f795ac218 100644
--- a/arch/powerpc/include/uapi/asm/Kbuild
+++ b/arch/powerpc/include/uapi/asm/Kbuild
@@ -15,7 +15,6 @@ header-y += ioctls.h
15header-y += ipcbuf.h 15header-y += ipcbuf.h
16header-y += kvm.h 16header-y += kvm.h
17header-y += kvm_para.h 17header-y += kvm_para.h
18header-y += linkage.h
19header-y += mman.h 18header-y += mman.h
20header-y += msgbuf.h 19header-y += msgbuf.h
21header-y += nvram.h 20header-y += nvram.h
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 3764fb788d6c..7051ea3101b9 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -36,6 +36,7 @@
36#include <linux/of.h> 36#include <linux/of.h>
37 37
38#include <linux/atomic.h> 38#include <linux/atomic.h>
39#include <asm/debug.h>
39#include <asm/eeh.h> 40#include <asm/eeh.h>
40#include <asm/eeh_event.h> 41#include <asm/eeh_event.h>
41#include <asm/io.h> 42#include <asm/io.h>
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index b0a1792279bb..0bb5918faaaf 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -72,7 +72,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
72 * If so, DABR will be populated in single_step_dabr_instruction(). 72 * If so, DABR will be populated in single_step_dabr_instruction().
73 */ 73 */
74 if (current->thread.last_hit_ubp != bp) 74 if (current->thread.last_hit_ubp != bp)
75 set_breakpoint(info); 75 __set_breakpoint(info);
76 76
77 return 0; 77 return 0;
78} 78}
@@ -198,7 +198,7 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
198 198
199 info = counter_arch_bp(tsk->thread.last_hit_ubp); 199 info = counter_arch_bp(tsk->thread.last_hit_ubp);
200 regs->msr &= ~MSR_SE; 200 regs->msr &= ~MSR_SE;
201 set_breakpoint(info); 201 __set_breakpoint(info);
202 tsk->thread.last_hit_ubp = NULL; 202 tsk->thread.last_hit_ubp = NULL;
203} 203}
204 204
@@ -284,7 +284,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
284 if (!(info->type & HW_BRK_TYPE_EXTRANEOUS_IRQ)) 284 if (!(info->type & HW_BRK_TYPE_EXTRANEOUS_IRQ))
285 perf_bp_event(bp, regs); 285 perf_bp_event(bp, regs);
286 286
287 set_breakpoint(info); 287 __set_breakpoint(info);
288out: 288out:
289 rcu_read_unlock(); 289 rcu_read_unlock();
290 return rc; 290 return rc;
@@ -316,7 +316,7 @@ int __kprobes single_step_dabr_instruction(struct die_args *args)
316 if (!(info->type & HW_BRK_TYPE_EXTRANEOUS_IRQ)) 316 if (!(info->type & HW_BRK_TYPE_EXTRANEOUS_IRQ))
317 perf_bp_event(bp, regs); 317 perf_bp_event(bp, regs);
318 318
319 set_breakpoint(info); 319 __set_breakpoint(info);
320 current->thread.last_hit_ubp = NULL; 320 current->thread.last_hit_ubp = NULL;
321 321
322 /* 322 /*
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index ef349d077129..077d2ce6c5a7 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -134,7 +134,7 @@ static u32 ppc64_stub_insns[] = {
134 0xe98b0020, /* ld r12,32(r11) */ 134 0xe98b0020, /* ld r12,32(r11) */
135#if !defined(_CALL_ELF) || _CALL_ELF != 2 135#if !defined(_CALL_ELF) || _CALL_ELF != 2
136 /* Set up new r2 from function descriptor */ 136 /* Set up new r2 from function descriptor */
137 0xe84b0026, /* ld r2,40(r11) */ 137 0xe84b0028, /* ld r2,40(r11) */
138#endif 138#endif
139 0x7d8903a6, /* mtctr r12 */ 139 0x7d8903a6, /* mtctr r12 */
140 0x4e800420 /* bctr */ 140 0x4e800420 /* bctr */
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 2ae1b99166c6..8a1edbe26b8f 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -496,14 +496,21 @@ static inline int set_dawr(struct arch_hw_breakpoint *brk)
496 return 0; 496 return 0;
497} 497}
498 498
499int set_breakpoint(struct arch_hw_breakpoint *brk) 499void __set_breakpoint(struct arch_hw_breakpoint *brk)
500{ 500{
501 __get_cpu_var(current_brk) = *brk; 501 __get_cpu_var(current_brk) = *brk;
502 502
503 if (cpu_has_feature(CPU_FTR_DAWR)) 503 if (cpu_has_feature(CPU_FTR_DAWR))
504 return set_dawr(brk); 504 set_dawr(brk);
505 else
506 set_dabr(brk);
507}
505 508
506 return set_dabr(brk); 509void set_breakpoint(struct arch_hw_breakpoint *brk)
510{
511 preempt_disable();
512 __set_breakpoint(brk);
513 preempt_enable();
507} 514}
508 515
509#ifdef CONFIG_PPC64 516#ifdef CONFIG_PPC64
@@ -835,7 +842,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
835 */ 842 */
836#ifndef CONFIG_HAVE_HW_BREAKPOINT 843#ifndef CONFIG_HAVE_HW_BREAKPOINT
837 if (unlikely(!hw_brk_match(&__get_cpu_var(current_brk), &new->thread.hw_brk))) 844 if (unlikely(!hw_brk_match(&__get_cpu_var(current_brk), &new->thread.hw_brk)))
838 set_breakpoint(&new->thread.hw_brk); 845 __set_breakpoint(&new->thread.hw_brk);
839#endif /* CONFIG_HAVE_HW_BREAKPOINT */ 846#endif /* CONFIG_HAVE_HW_BREAKPOINT */
840#endif 847#endif
841 848
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 8fc4177ed65a..1c794cef2883 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -134,7 +134,7 @@ static int do_signal(struct pt_regs *regs)
134 */ 134 */
135 if (current->thread.hw_brk.address && 135 if (current->thread.hw_brk.address &&
136 current->thread.hw_brk.type) 136 current->thread.hw_brk.type)
137 set_breakpoint(&current->thread.hw_brk); 137 __set_breakpoint(&current->thread.hw_brk);
138#endif 138#endif
139 /* Re-enable the breakpoints for the signal stack */ 139 /* Re-enable the breakpoints for the signal stack */
140 thread_change_pc(current, regs); 140 thread_change_pc(current, regs);
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 122a580f7322..7e711bdcc6da 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -813,9 +813,6 @@ static void __init clocksource_init(void)
813static int decrementer_set_next_event(unsigned long evt, 813static int decrementer_set_next_event(unsigned long evt,
814 struct clock_event_device *dev) 814 struct clock_event_device *dev)
815{ 815{
816 /* Don't adjust the decrementer if some irq work is pending */
817 if (test_irq_work_pending())
818 return 0;
819 __get_cpu_var(decrementers_next_tb) = get_tb_or_rtc() + evt; 816 __get_cpu_var(decrementers_next_tb) = get_tb_or_rtc() + evt;
820 set_dec(evt); 817 set_dec(evt);
821 818
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
index 79d0cdf786d0..753f08e36dfa 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -477,127 +477,49 @@ out:
477 return 0; 477 return 0;
478} 478}
479 479
480static bool ioda_eeh_is_plx_dnport(struct pci_dev *dev, int *reg,
481 int *mask, int *len)
482{
483 unsigned short *pid;
484 unsigned short ids[] = {
485 0x10b5, 0x8748, 0x0080, 0x0400, /* PLX#8748 */
486 0x0000, 0x0000, 0x0000, 0x0000, /* End flag */
487 };
488
489 if (!pci_is_pcie(dev))
490 return false;
491 if (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM)
492 return false;
493
494 pid = &ids[0];
495 while (!reg) {
496 if (pid[0] == 0x0)
497 break;
498
499 if (dev->vendor == pid[0] &&
500 dev->device == pid[1]) {
501 *reg = pid[2];
502 *mask = pid[3];
503 *len = 2;
504 return true;
505 }
506 }
507
508 *reg = PCI_BRIDGE_CONTROL;
509 *mask = PCI_BRIDGE_CTL_BUS_RESET;
510 *len = 2;
511 return false;
512}
513
514static int ioda_eeh_bridge_reset(struct pci_dev *dev, int option) 480static int ioda_eeh_bridge_reset(struct pci_dev *dev, int option)
515 481
516{ 482{
517 struct device_node *dn = pci_device_to_OF_node(dev); 483 struct device_node *dn = pci_device_to_OF_node(dev);
518 struct eeh_dev *edev = of_node_to_eeh_dev(dn); 484 struct eeh_dev *edev = of_node_to_eeh_dev(dn);
519 int aer = edev ? edev->aer_cap : 0; 485 int aer = edev ? edev->aer_cap : 0;
520 int reg, mask, val, len; 486 u32 ctrl;
521 bool is_plx_dnport;
522 487
523 pr_debug("%s: Reset PCI bus %04x:%02x with option %d\n", 488 pr_debug("%s: Reset PCI bus %04x:%02x with option %d\n",
524 __func__, pci_domain_nr(dev->bus), 489 __func__, pci_domain_nr(dev->bus),
525 dev->bus->number, option); 490 dev->bus->number, option);
526 491
527
528 is_plx_dnport = ioda_eeh_is_plx_dnport(dev, &reg, &mask, &len);
529 if (option == EEH_RESET_FUNDAMENTAL)
530 if (!is_plx_dnport || !edev)
531 option = EEH_RESET_HOT;
532
533 if (option == EEH_RESET_HOT) {
534 reg = PCI_BRIDGE_CONTROL;
535 mask = PCI_BRIDGE_CTL_BUS_RESET;
536 len = 2;
537 }
538
539 if (option == EEH_RESET_DEACTIVATE) {
540 if (!is_plx_dnport || !edev ||
541 !(edev->mode & EEH_DEV_FRESET)) {
542 reg = PCI_BRIDGE_CONTROL;
543 mask = PCI_BRIDGE_CTL_BUS_RESET;
544 len = 2;
545 }
546 }
547
548 switch (option) { 492 switch (option) {
549 case EEH_RESET_FUNDAMENTAL: 493 case EEH_RESET_FUNDAMENTAL:
550 edev->mode |= EEH_DEV_FRESET;
551 /* Fall through */
552 case EEH_RESET_HOT: 494 case EEH_RESET_HOT:
495 /* Don't report linkDown event */
553 if (aer) { 496 if (aer) {
554 /* Mask receiver error */
555 eeh_ops->read_config(dn, aer + PCI_ERR_COR_MASK,
556 4, &val);
557 val |= PCI_ERR_COR_RCVR;
558 eeh_ops->write_config(dn, aer + PCI_ERR_COR_MASK,
559 4, val);
560
561 /* Mask linkDown */
562 eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK, 497 eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK,
563 4, &val); 498 4, &ctrl);
564 val |= PCI_ERR_UNC_SURPDN; 499 ctrl |= PCI_ERR_UNC_SURPDN;
565 eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK, 500 eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK,
566 4, val); 501 4, ctrl);
567 } 502 }
568 503
569 eeh_ops->read_config(dn, reg, len, &val); 504 eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl);
570 val |= mask; 505 ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
571 eeh_ops->write_config(dn, reg, len, val); 506 eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl);
572 msleep(EEH_PE_RST_HOLD_TIME); 507 msleep(EEH_PE_RST_HOLD_TIME);
573 508
574 break; 509 break;
575 case EEH_RESET_DEACTIVATE: 510 case EEH_RESET_DEACTIVATE:
576 eeh_ops->read_config(dn, reg, len, &val); 511 eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl);
577 val &= ~mask; 512 ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
578 eeh_ops->write_config(dn, reg, len, val); 513 eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl);
579 msleep(EEH_PE_RST_SETTLE_TIME); 514 msleep(EEH_PE_RST_SETTLE_TIME);
580 515
581 if (edev) 516 /* Continue reporting linkDown event */
582 edev->mode &= ~EEH_DEV_FRESET;
583 if (aer) { 517 if (aer) {
584 /* Clear receive error and enable it */
585 eeh_ops->write_config(dn, aer + PCI_ERR_COR_STATUS,
586 4, PCI_ERR_COR_RCVR);
587 eeh_ops->read_config(dn, aer + PCI_ERR_COR_MASK,
588 4, &val);
589 val &= ~PCI_ERR_COR_RCVR;
590 eeh_ops->write_config(dn, aer + PCI_ERR_COR_MASK,
591 4, val);
592
593 /* Clear linkDown and enable it */
594 eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_STATUS,
595 4, PCI_ERR_UNC_SURPDN);
596 eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK, 518 eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK,
597 4, &val); 519 4, &ctrl);
598 val &= ~PCI_ERR_UNC_SURPDN; 520 ctrl &= ~PCI_ERR_UNC_SURPDN;
599 eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK, 521 eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK,
600 4, val); 522 4, ctrl);
601 } 523 }
602 524
603 break; 525 break;
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 08504e75b2c7..d3759b7a5535 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -759,7 +759,7 @@ static void insert_cpu_bpts(void)
759 brk.address = dabr.address; 759 brk.address = dabr.address;
760 brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL; 760 brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
761 brk.len = 8; 761 brk.len = 8;
762 set_breakpoint(&brk); 762 __set_breakpoint(&brk);
763 } 763 }
764 if (iabr && cpu_has_feature(CPU_FTR_IABR)) 764 if (iabr && cpu_has_feature(CPU_FTR_IABR))
765 mtspr(SPRN_IABR, iabr->address 765 mtspr(SPRN_IABR, iabr->address