powerpc: add POWER8 DAWR support
Subsystems (2)
cover powerpc: add POWER8 DAWR support
Add support for the Data Address Watchpoint Register (DAWR) as found in POWER8. This replaces the DABR found in POWER7 and earlier and allows for wider watchpoint areas.
Signature · 1 line
1.7.10.4
PATCH 1/7 powerpc: Remove extra zeros from 32 bit CPU features definitions
These are 32 bit, so no need to have a bunch of wasted 0s.
The 0s saved here can be put to better use elsewhere, like at the end of my pay check.
--- arch/powerpc/include/asm/cputable.h | 62 +++++++++++++++++------------------ 1 file changed, 31 insertions(+), 31 deletions(-)
arch/powerpc/include/asm/cputable.h +31 -31
@@ -106,37 +106,37 @@ extern const char *powerpc_base_platform;/* CPU kernel features */ /* Retain the 32b definitions all use bottom half of word */ -#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0000000000000001) -#define CPU_FTR_L2CR ASM_CONST(0x0000000000000002) -#define CPU_FTR_SPEC7450 ASM_CONST(0x0000000000000004) -#define CPU_FTR_ALTIVEC ASM_CONST(0x0000000000000008) -#define CPU_FTR_TAU ASM_CONST(0x0000000000000010) -#define CPU_FTR_CAN_DOZE ASM_CONST(0x0000000000000020) -#define CPU_FTR_USE_TB ASM_CONST(0x0000000000000040) -#define CPU_FTR_L2CSR ASM_CONST(0x0000000000000080) -#define CPU_FTR_601 ASM_CONST(0x0000000000000100) -#define CPU_FTR_DBELL ASM_CONST(0x0000000000000200) -#define CPU_FTR_CAN_NAP ASM_CONST(0x0000000000000400) -#define CPU_FTR_L3CR ASM_CONST(0x0000000000000800) -#define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x0000000000001000) -#define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x0000000000002000) -#define CPU_FTR_DUAL_PLL_750FX ASM_CONST(0x0000000000004000) -#define CPU_FTR_NO_DPM ASM_CONST(0x0000000000008000) -#define CPU_FTR_476_DD2 ASM_CONST(0x0000000000010000) -#define CPU_FTR_NEED_COHERENT ASM_CONST(0x0000000000020000) -#define CPU_FTR_NO_BTIC ASM_CONST(0x0000000000040000) -#define CPU_FTR_DEBUG_LVL_EXC ASM_CONST(0x0000000000080000) -#define CPU_FTR_NODSISRALIGN ASM_CONST(0x0000000000100000) -#define CPU_FTR_PPC_LE ASM_CONST(0x0000000000200000) -#define CPU_FTR_REAL_LE ASM_CONST(0x0000000000400000) -#define CPU_FTR_FPU_UNAVAILABLE ASM_CONST(0x0000000000800000) -#define CPU_FTR_UNIFIED_ID_CACHE ASM_CONST(0x0000000001000000) -#define CPU_FTR_SPE ASM_CONST(0x0000000002000000) -#define CPU_FTR_NEED_PAIRED_STWCX ASM_CONST(0x0000000004000000) -#define CPU_FTR_LWSYNC ASM_CONST(0x0000000008000000) -#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000010000000) -#define CPU_FTR_INDEXED_DCR ASM_CONST(0x0000000020000000) -#define CPU_FTR_EMB_HV ASM_CONST(0x0000000040000000) +#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x00000001) +#define CPU_FTR_L2CR ASM_CONST(0x00000002) +#define CPU_FTR_SPEC7450 ASM_CONST(0x00000004) +#define CPU_FTR_ALTIVEC ASM_CONST(0x00000008) +#define CPU_FTR_TAU ASM_CONST(0x00000010) +#define CPU_FTR_CAN_DOZE ASM_CONST(0x00000020) +#define CPU_FTR_USE_TB ASM_CONST(0x00000040) +#define CPU_FTR_L2CSR ASM_CONST(0x00000080) +#define CPU_FTR_601 ASM_CONST(0x00000100) +#define CPU_FTR_DBELL ASM_CONST(0x00000200) +#define CPU_FTR_CAN_NAP ASM_CONST(0x00000400) +#define CPU_FTR_L3CR ASM_CONST(0x00000800) +#define CPU_FTR_L3_DISABLE_NAP ASM_CONST(0x00001000) +#define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x00002000) +#define CPU_FTR_DUAL_PLL_750FX ASM_CONST(0x00004000) +#define CPU_FTR_NO_DPM ASM_CONST(0x00008000) +#define CPU_FTR_476_DD2 ASM_CONST(0x00010000) +#define CPU_FTR_NEED_COHERENT ASM_CONST(0x00020000) +#define CPU_FTR_NO_BTIC ASM_CONST(0x00040000) +#define CPU_FTR_DEBUG_LVL_EXC ASM_CONST(0x00080000) +#define CPU_FTR_NODSISRALIGN ASM_CONST(0x00100000) +#define CPU_FTR_PPC_LE ASM_CONST(0x00200000) +#define CPU_FTR_REAL_LE ASM_CONST(0x00400000) +#define CPU_FTR_FPU_UNAVAILABLE ASM_CONST(0x00800000) +#define CPU_FTR_UNIFIED_ID_CACHE ASM_CONST(0x01000000) +#define CPU_FTR_SPE ASM_CONST(0x02000000) +#define CPU_FTR_NEED_PAIRED_STWCX ASM_CONST(0x04000000) +#define CPU_FTR_LWSYNC ASM_CONST(0x08000000) +#define CPU_FTR_NOEXECUTE ASM_CONST(0x10000000) +#define CPU_FTR_INDEXED_DCR ASM_CONST(0x20000000) +#define CPU_FTR_EMB_HV ASM_CONST(0x40000000)/* * Add the 64-bit processor unique features in the top half of the word;
Signature · 1 line
1.7.10.4
PATCH 2/7 powerpc: Repack 64bit CPU features to remove holes
In reply to Michael NeulingThis frees up 7 bits for crazy new CPU features.
--- arch/powerpc/include/asm/cputable.h | 50 +++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-)
arch/powerpc/include/asm/cputable.h +25 -25
@@ -148,31 +148,31 @@ extern const char *powerpc_base_platform;#define LONG_ASM_CONST (x) 0#endif -#define CPU_FTR_HVMODE LONG_ASM_CONST(0x0000000200000000) -#define CPU_FTR_ARCH_201 LONG_ASM_CONST(0x0000000400000000) -#define CPU_FTR_ARCH_206 LONG_ASM_CONST(0x0000000800000000) -#define CPU_FTR_CFAR LONG_ASM_CONST(0x0000001000000000) -#define CPU_FTR_IABR LONG_ASM_CONST(0x0000002000000000) -#define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000004000000000) -#define CPU_FTR_CTRL LONG_ASM_CONST(0x0000008000000000) -#define CPU_FTR_SMT LONG_ASM_CONST(0x0000010000000000) -#define CPU_FTR_PAUSE_ZERO LONG_ASM_CONST(0x0000200000000000) -#define CPU_FTR_PURR LONG_ASM_CONST(0x0000400000000000) -#define CPU_FTR_CELL_TB_BUG LONG_ASM_CONST(0x0000800000000000) -#define CPU_FTR_SPURR LONG_ASM_CONST(0x0001000000000000) -#define CPU_FTR_DSCR LONG_ASM_CONST(0x0002000000000000) -#define CPU_FTR_VSX LONG_ASM_CONST(0x0010000000000000) -#define CPU_FTR_SAO LONG_ASM_CONST(0x0020000000000000) -#define CPU_FTR_CP_USE_DCBTZ LONG_ASM_CONST(0x0040000000000000) -#define CPU_FTR_UNALIGNED_LD_STD LONG_ASM_CONST(0x0080000000000000) -#define CPU_FTR_ASYM_SMT LONG_ASM_CONST(0x0100000000000000) -#define CPU_FTR_STCX_CHECKS_ADDRESS LONG_ASM_CONST(0x0200000000000000) -#define CPU_FTR_POPCNTB LONG_ASM_CONST(0x0400000000000000) -#define CPU_FTR_POPCNTD LONG_ASM_CONST(0x0800000000000000) -#define CPU_FTR_ICSWX LONG_ASM_CONST(0x1000000000000000) -#define CPU_FTR_VMX_COPY LONG_ASM_CONST(0x2000000000000000) -#define CPU_FTR_TM LONG_ASM_CONST(0x4000000000000000) -#define CPU_FTR_BCTAR LONG_ASM_CONST(0x8000000000000000) +#define CPU_FTR_HVMODE LONG_ASM_CONST(0x0000000100000000) +#define CPU_FTR_ARCH_201 LONG_ASM_CONST(0x0000000200000000) +#define CPU_FTR_ARCH_206 LONG_ASM_CONST(0x0000000400000000) +#define CPU_FTR_CFAR LONG_ASM_CONST(0x0000000800000000) +#define CPU_FTR_IABR LONG_ASM_CONST(0x0000001000000000) +#define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000002000000000) +#define CPU_FTR_CTRL LONG_ASM_CONST(0x0000004000000000) +#define CPU_FTR_SMT LONG_ASM_CONST(0x0000008000000000) +#define CPU_FTR_PAUSE_ZERO LONG_ASM_CONST(0x0000010000000000) +#define CPU_FTR_PURR LONG_ASM_CONST(0x0000020000000000) +#define CPU_FTR_CELL_TB_BUG LONG_ASM_CONST(0x0000040000000000) +#define CPU_FTR_SPURR LONG_ASM_CONST(0x0000080000000000) +#define CPU_FTR_DSCR LONG_ASM_CONST(0x0000100000000000) +#define CPU_FTR_VSX LONG_ASM_CONST(0x0000200000000000) +#define CPU_FTR_SAO LONG_ASM_CONST(0x0000400000000000) +#define CPU_FTR_CP_USE_DCBTZ LONG_ASM_CONST(0x0000800000000000) +#define CPU_FTR_UNALIGNED_LD_STD LONG_ASM_CONST(0x0001000000000000) +#define CPU_FTR_ASYM_SMT LONG_ASM_CONST(0x0002000000000000) +#define CPU_FTR_STCX_CHECKS_ADDRESS LONG_ASM_CONST(0x0004000000000000) +#define CPU_FTR_POPCNTB LONG_ASM_CONST(0x0008000000000000) +#define CPU_FTR_POPCNTD LONG_ASM_CONST(0x0010000000000000) +#define CPU_FTR_ICSWX LONG_ASM_CONST(0x0020000000000000) +#define CPU_FTR_VMX_COPY LONG_ASM_CONST(0x0040000000000000) +#define CPU_FTR_TM LONG_ASM_CONST(0x0080000000000000) +#define CPU_FTR_BCTAR LONG_ASM_CONST(0x0100000000000000)#ifndef __ASSEMBLY__
Signature · 1 line
1.7.10.4
PATCH 3/7 powerpc: Add helper functions set the DAWR and CIABR using set_mode
In reply to Michael NeulingFrom: Ian Munsie <[email protected]>
These are just wrappers around the new set_mode HCALL.
--- arch/powerpc/platforms/pseries/plpar_wrappers.h | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/powerpc/platforms/pseries/plpar_wrappers.h +10 -0
@@ -304,4 +304,14 @@ static inline long disable_reloc_on_exceptions(void) { return plpar_set_mode(0, 3, 0, 0); } +static inline long plapr_set_ciabr (unsigned long ciabr) +{ +return plpar_set_mode (0 ,1 , ciabr,0 ); +} + +static inline long plapr_set_watchpoint0 (unsigned long dawr0,unsigned long dawrx0) +{ +return plpar_set_mode (0 ,2 , dawr0, dawrx0); +} +#endif /* _PSERIES_PLPAR_WRAPPERS_H */
Signature · 1 line
1.7.10.4
PATCH 4/7 powerpc: Add DAWR CPU feature bit definition
In reply to Michael Neuling.. and add it to POWER8 cpu features.
--- arch/powerpc/include/asm/cputable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/powerpc/include/asm/cputable.h +2 -1
@@ -173,6 +173,7 @@ extern const char *powerpc_base_platform;#define CPU_FTR_VMX_COPY LONG_ASM_CONST(0x0040000000000000)#define CPU_FTR_TM LONG_ASM_CONST(0x0080000000000000)#define CPU_FTR_BCTAR LONG_ASM_CONST(0x0100000000000000) +#define CPU_FTR_DAWR LONG_ASM_CONST(0x0200000000000000)#ifndef __ASSEMBLY__
@@ -418,7 +419,7 @@ extern const char *powerpc_base_platform; CPU_FTR_DSCR | CPU_FTR_SAO | \ CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ - CPU_FTR_DBELL | CPU_FTR_TM_COMP | CPU_FTR_BCTAR) + CPU_FTR_DBELL | CPU_FTR_TM_COMP | CPU_FTR_BCTAR | CPU_FTR_DAWR)#define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
Signature · 1 line
1.7.10.4
PATCH 5/7 powerpc: Add DAWR/X SPR number definitions
In reply to Michael Neuling--- arch/powerpc/include/asm/reg.h | 5 +++++ 1 file changed, 5 insertions(+)
arch/powerpc/include/asm/reg.h +5 -0
@@ -222,6 +222,11 @@#define CTRL_CT1 0x40000000/* thread 1 */ #define CTRL_TE 0x00c00000/* thread enable */ #define CTRL_RUNLATCH 0x1 +#define SPRN_DAWR 0xB4 +#define SPRN_DAWRX 0xBC +#define DAWRX_USER (1UL << 0) +#define DAWRX_KERNEL (1UL << 1) +#define DAWRX_HYP (1UL << 2)#define SPRN_DABR 0x3F5/* Data Address Breakpoint Register */ #define DABR_TRANSLATION (1UL << 2)#define DABR_DATA_WRITE (1UL << 1)
Signature · 1 line
1.7.10.4
PATCH 6/7 powerpc: Hardware breakpoints rewrite to handle non DABR breakpoint registers
In reply to Michael NeulingThis is a rewrite so that we don't assume we are using the DABR throughout the code. We now use the arch_hw_breakpoint to store the breakpoint in a generic manner in the thread_struct, rather than storing the raw DABR value.
The ptrace GET/SET_DEBUGREG interface currently passes the raw DABR in from userspace. We keep this functionality, so that future changes (like the POWER8 DAWR), will still fake the DABR to userspace.
--- arch/powerpc/include/asm/debug.h | 15 ++++--- arch/powerpc/include/asm/hw_breakpoint.h | 33 +++++++++++--- arch/powerpc/include/asm/processor.h | 4 +- arch/powerpc/include/asm/reg.h | 3 -- arch/powerpc/kernel/exceptions-64s.S | 2 +- arch/powerpc/kernel/hw_breakpoint.c | 72 +++++++++++++----------------- arch/powerpc/kernel/kgdb.c | 10 ++--- arch/powerpc/kernel/process.c | 67 ++++++++++++++++++--------- arch/powerpc/kernel/ptrace.c | 60 +++++++++++++------------ arch/powerpc/kernel/ptrace32.c | 8 +++- arch/powerpc/kernel/signal.c | 5 ++- arch/powerpc/kernel/traps.c | 4 +- arch/powerpc/mm/fault.c | 4 +- arch/powerpc/xmon/xmon.c | 21 ++++++--- 14 files changed, 180 insertions(+), 128 deletions(-)
arch/powerpc/include/asm/debug.h +9 -6
@@ -4,6 +4,8 @@#ifndef _ASM_POWERPC_DEBUG_H#define _ASM_POWERPC_DEBUG_H +#include <asm/hw_breakpoint.h> +struct pt_regs ;extern struct dentry *powerpc_debugfs_root;
@@ -15,7 +17,7 @@ extern int (*__debugger_ipi)(struct pt_regs *regs);extern int (*__debugger_bpt)(struct pt_regs *regs);extern int (*__debugger_sstep)(struct pt_regs *regs);extern int (*__debugger_iabr_match)(struct pt_regs *regs); -extern int (*__debugger_dabr_match)(struct pt_regs *regs); +extern int (*__debugger_break_match)(struct pt_regs *regs);extern int (*__debugger_fault_handler)(struct pt_regs *regs);#define DEBUGGER_BOILERPLATE (__NAME) \
@@ -31,7 +33,7 @@ DEBUGGER_BOILERPLATE(debugger_ipi) DEBUGGER_BOILERPLATE(debugger_bpt) DEBUGGER_BOILERPLATE(debugger_sstep) DEBUGGER_BOILERPLATE(debugger_iabr_match) -DEBUGGER_BOILERPLATE(debugger_dabr_match) +DEBUGGER_BOILERPLATE(debugger_break_match) DEBUGGER_BOILERPLATE(debugger_fault_handler)#else
@@ -40,17 +42,18 @@ static inline int debugger_ipi(struct pt_regs *regs) { return 0; }static inline int debugger_bpt (struct pt_regs *regs) {return 0 ; }static inline int debugger_sstep (struct pt_regs *regs) {return 0 ; }static inline int debugger_iabr_match (struct pt_regs *regs) {return 0 ; } -static inline int debugger_dabr_match (struct pt_regs *regs) {return 0 ; } +static inline int debugger_break_match (struct pt_regs *regs) {return 0 ; }static inline int debugger_fault_handler (struct pt_regs *regs) {return 0 ; }#endif -extern int set_dabr (unsigned long dabr,unsigned long dabrx); +int set_break (struct arch_hw_breakpoint *brk);#ifdef CONFIG_PPC_ADV_DEBUG_REGS extern void do_send_trap (struct pt_regs *regs,unsigned long address,unsigned long error_code,int signal_code,int brkpt);#else -extern void do_dabr (struct pt_regs *regs,unsigned long address, -unsigned long error_code); + +extern void do_break (struct pt_regs *regs,unsigned long address, +unsigned long error_code);#endif #endif /* _ASM_POWERPC_DEBUG_H */
arch/powerpc/include/asm/hw_breakpoint.h +26 -7
@@ -24,16 +24,30 @@#define _PPC_BOOK3S_64_HW_BREAKPOINT_H#ifdef __KERNEL__ -#ifdef CONFIG_HAVE_HW_BREAKPOINT -struct arch_hw_breakpoint {unsigned long address; -unsigned long dabrx; -int type; -u8 len;/* length of the target data symbol */ -bool extraneous_interrupt; +u16 type; +u16 len;/* length of the target data symbol */ }; +/* Note: Don't change the the first 6 bits below as they are in the same order +* as the dabr and dabrx. +*/ +#define HW_BRK_TYPE_READ 0x01 +#define HW_BRK_TYPE_WRITE 0x02 +#define HW_BRK_TYPE_TRANSLATE 0x04 +#define HW_BRK_TYPE_USER 0x08 +#define HW_BRK_TYPE_KERNEL 0x10 +#define HW_BRK_TYPE_HYP 0x20 +#define HW_BRK_TYPE_EXTRANEOUS_IRQ 0x80 + +/* bits that overlap with the bottom 3 bits of the dabr */ +#define HW_BRK_TYPE_RDWR (HW_BRK_TYPE_READ | HW_BRK_TYPE_WRITE) +#define HW_BRK_TYPE_DABR (HW_BRK_TYPE_RDWR | HW_BRK_TYPE_TRANSLATE) +#define HW_BRK_TYPE_PRIV_ALL (HW_BRK_TYPE_USER | HW_BRK_TYPE_KERNEL | \ + HW_BRK_TYPE_HYP) + +#ifdef CONFIG_HAVE_HW_BREAKPOINT #include <linux/kdebug.h> #include <asm/reg.h> #include <asm/debug.h>
@@ -62,7 +76,12 @@ extern void ptrace_triggered(struct perf_event *bp, struct perf_sample_data *data, struct pt_regs *regs);static inline void hw_breakpoint_disable (void ) { -set_dabr (0 ,0 ); +struct arch_hw_breakpoint brk; + + brk.address =0 ; + brk.type =0 ; + brk.len =0 ; +set_break (&brk); }extern void thread_change_pc (struct task_struct *tsk,struct pt_regs *regs);
arch/powerpc/include/asm/processor.h +2 -2
@@ -23,6 +23,7 @@#include <linux/cache.h> #include <asm/ptrace.h> #include <asm/types.h> +#include <asm/hw_breakpoint.h> /* We do _not_ want to define new machine types at all, those must die * in favor of using the device-tree
@@ -216,8 +217,7 @@ struct thread_struct {struct perf_event *last_hit_ubp;#endif /* CONFIG_HAVE_HW_BREAKPOINT */ #endif -unsigned long dabr;/* Data address breakpoint register */ -unsigned long dabrx;/* ... extension */ +struct arch_hw_breakpoint hw_brk;/* info on the hardware breakpoint */ unsigned long trap_nr;/* last trap # on this thread */ #ifdef CONFIG_ALTIVEC /* Complete AltiVec register set */
arch/powerpc/include/asm/reg.h +0 -3
@@ -228,9 +228,6 @@#define DAWRX_KERNEL (1UL << 1)#define DAWRX_HYP (1UL << 2)#define SPRN_DABR 0x3F5/* Data Address Breakpoint Register */ -#define DABR_TRANSLATION (1UL << 2) -#define DABR_DATA_WRITE (1UL << 1) -#define DABR_DATA_READ (1UL << 0)#define SPRN_DABR2 0x13D/* e300 */ #define SPRN_DABRX 0x3F7/* Data Address Breakpoint Register Extension */ #define DABRX_USER (1UL << 0)
arch/powerpc/kernel/exceptions-64s.S +1 -1
@@ -1310,7 +1310,7 @@ handle_dabr_fault: ld r4,_DAR(r1) ld r5,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD - bl .do_dabr + bl .do_break 12: b .ret_from_except_lite
arch/powerpc/kernel/hw_breakpoint.c +30 -42
134 lines not on this page · raw message
arch/powerpc/kernel/kgdb.c +5 -5
@@ -198,7 +198,7 @@ static int kgdb_iabr_match(struct pt_regs *regs)return 1 ; } -static int kgdb_dabr_match (struct pt_regs *regs) +static int kgdb_break_match (struct pt_regs *regs) {if (user_mode (regs))return 0 ;
@@ -458,7 +458,7 @@ static void *old__debugger;static void *old__debugger_bpt;static void *old__debugger_sstep;static void *old__debugger_iabr_match; -static void *old__debugger_dabr_match; +static void *old__debugger_break_match;static void *old__debugger_fault_handler;int kgdb_arch_init (void )
@@ -468,7 +468,7 @@ int kgdb_arch_init(void) old__debugger_bpt = __debugger_bpt; old__debugger_sstep = __debugger_sstep; old__debugger_iabr_match = __debugger_iabr_match; - old__debugger_dabr_match = __debugger_dabr_match; + old__debugger_break_match = __debugger_break_match; old__debugger_fault_handler = __debugger_fault_handler; __debugger_ipi = kgdb_call_nmi_hook;
@@ -476,7 +476,7 @@ int kgdb_arch_init(void) __debugger_bpt = kgdb_handle_breakpoint; __debugger_sstep = kgdb_singlestep; __debugger_iabr_match = kgdb_iabr_match; - __debugger_dabr_match = kgdb_dabr_match; + __debugger_break_match = kgdb_break_match; __debugger_fault_handler = kgdb_not_implemented;return 0 ;
@@ -489,6 +489,6 @@ void kgdb_arch_exit(void) __debugger_bpt = old__debugger_bpt; __debugger_sstep = old__debugger_sstep; __debugger_iabr_match = old__debugger_iabr_match; - __debugger_dabr_match = old__debugger_dabr_match; + __debugger_breakx_match = old__debugger_break_match; __debugger_fault_handler = old__debugger_fault_handler; }
arch/powerpc/kernel/process.c +47 -20
121 lines not on this page · raw message
arch/powerpc/kernel/ptrace.c +32 -28
149 lines not on this page · raw message
arch/powerpc/kernel/ptrace32.c +7 -1
@@ -252,6 +252,9 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, }case PTRACE_GET_DEBUGREG : { +#ifndef CONFIG_PPC_ADV_DEBUG_REGS +unsigned long dabr_fake; +#endif ret = -EINVAL ;/* We only support one DABR and no IABRS at the moment */ if (addr >0 )
@@ -259,7 +262,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,#ifdef CONFIG_PPC_ADV_DEBUG_REGS ret =put_user (child->thread.dac1, (u32 __user *)data);#else - ret =put_user (child->thread.dabr, (u32 __user *)data); + dabr_fake = ( + (child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR )) | + (child->thread.hw_brk.type &HW_BRK_TYPE_DABR )); + ret =put_user (dabr_fake, (u32 __user *)data);#endif break ; }
arch/powerpc/kernel/signal.c +3 -2
@@ -130,8 +130,9 @@ static int do_signal(struct pt_regs *regs)* user space. The DABR will have been cleared if it * triggered inside the kernel. */ -if (current->thread.dabr) -set_dabr (current->thread.dabr, current->thread.dabrx); +if (current->thread.hw_brk.address && + current->thread.hw_brk.type) +set_break (¤t->thread.hw_brk);#endif /* Re-enable the breakpoints for the signal stack */ thread_change_pc (current, regs);
arch/powerpc/kernel/traps.c +2 -2
@@ -67,7 +67,7 @@ int (*__debugger_ipi)(struct pt_regs *regs) __read_mostly;int (*__debugger_bpt)(struct pt_regs *regs)__read_mostly ;int (*__debugger_sstep)(struct pt_regs *regs)__read_mostly ;int (*__debugger_iabr_match)(struct pt_regs *regs)__read_mostly ; -int (*__debugger_dabr_match)(struct pt_regs *regs)__read_mostly ; +int (*__debugger_break_match)(struct pt_regs *regs)__read_mostly ;int (*__debugger_fault_handler)(struct pt_regs *regs)__read_mostly ;EXPORT_SYMBOL (__debugger);
@@ -75,7 +75,7 @@ EXPORT_SYMBOL(__debugger_ipi);EXPORT_SYMBOL (__debugger_bpt);EXPORT_SYMBOL (__debugger_sstep);EXPORT_SYMBOL (__debugger_iabr_match); -EXPORT_SYMBOL (__debugger_dabr_match); +EXPORT_SYMBOL (__debugger_break_match);EXPORT_SYMBOL (__debugger_fault_handler);#endif
arch/powerpc/mm/fault.c +2 -2
@@ -249,8 +249,8 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE ) || \ defined(CONFIG_PPC_BOOK3S_64 ))if (error_code &DSISR_DABRMATCH ) { -/* DABR match */ -do_dabr (regs, address, error_code); +/* breakpoint match */ +do_break (regs, address, error_code);return 0 ; }#endif
arch/powerpc/xmon/xmon.c +14 -7
@@ -43,6 +43,7 @@#include <asm/setjmp.h> #include <asm/reg.h> #include <asm/debug.h> +#include <asm/hw_breakpoint.h> #ifdef CONFIG_PPC64 #include <asm/hvcall.h>
@@ -607,7 +608,7 @@ static int xmon_sstep(struct pt_regs *regs)return 1 ; } -static int xmon_dabr_match (struct pt_regs *regs) +static int xmon_break_match (struct pt_regs *regs) {if ((regs->msr & (MSR_IR |MSR_PR |MSR_64BIT )) != (MSR_IR |MSR_64BIT ))return 0 ;
@@ -740,8 +741,14 @@ static void insert_bpts(void)static void insert_cpu_bpts (void ) { -if (dabr.enabled) -set_dabr (dabr.address | (dabr.enabled &7 ),DABRX_ALL ); +struct arch_hw_breakpoint brk; + +if (dabr.enabled) { + brk.address = dabr.address; + brk.type = (dabr.enabled &HW_BRK_TYPE_DABR ) |HW_BRK_TYPE_PRIV_ALL ; + brk.len =8 ; +set_break (&brk); + }if (iabr &&cpu_has_feature (CPU_FTR_IABR ))mtspr (SPRN_IABR , iabr->address | (iabr->enabled & (BP_IABR |BP_IABR_TE )));
@@ -769,7 +776,7 @@ static void remove_bpts(void)static void remove_cpu_bpts (void ) { -set_dabr (0 ,0 ); +hw_breakpoint_disable ();if (cpu_has_feature (CPU_FTR_IABR ))mtspr (SPRN_IABR ,0 ); }
@@ -1138,7 +1145,7 @@ bpt_cmds(void)printf (badaddr);break ; } - dabr.address &= ~7 ; + dabr.address &= ~HW_BRK_TYPE_DABR ; dabr.enabled = mode |BP_DABR ; }break ;
@@ -2917,7 +2924,7 @@ static void xmon_init(int enable) __debugger_bpt = xmon_bpt; __debugger_sstep = xmon_sstep; __debugger_iabr_match = xmon_iabr_match; - __debugger_dabr_match = xmon_dabr_match; + __debugger_break_match = xmon_break_match; __debugger_fault_handler = xmon_fault_handler; }else { __debugger =NULL ;
@@ -2925,7 +2932,7 @@ static void xmon_init(int enable) __debugger_bpt =NULL ; __debugger_sstep =NULL ; __debugger_iabr_match =NULL ; - __debugger_dabr_match =NULL ; + __debugger_break_match =NULL ; __debugger_fault_handler =NULL ; } }
Signature · 1 line
1.7.10.4
PATCH 6/7 powerpc: Hardware breakpoints rewrite to handle non DABR breakpoint registers
This is a rewrite so that we don't assume we are using the DABR throughout the code. We now use the arch_hw_breakpoint to store the breakpoint in a generic manner in the thread_struct, rather than storing the raw DABR value.
The ptrace GET/SET_DEBUGREG interface currently passes the raw DABR in from userspace. We keep this functionality, so that future changes (like the POWER8 DAWR), will still fake the DABR to userspace.
---
Resending to fix a problem with 8xx defconfigs. Noticed by benh.
arch/powerpc/include/asm/debug.h | 15 +++--- arch/powerpc/include/asm/hw_breakpoint.h | 33 ++++++++++--- arch/powerpc/include/asm/processor.h | 4 +- arch/powerpc/include/asm/reg.h | 3 -- arch/powerpc/kernel/exceptions-64s.S | 2 +- arch/powerpc/kernel/hw_breakpoint.c | 72 ++++++++++++---------------- arch/powerpc/kernel/kgdb.c | 10 ++-- arch/powerpc/kernel/process.c | 75 +++++++++++++++++++++--------- arch/powerpc/kernel/ptrace.c | 60 +++++++++++++----------- arch/powerpc/kernel/ptrace32.c | 8 +++- arch/powerpc/kernel/signal.c | 5 +- arch/powerpc/kernel/traps.c | 4 +- arch/powerpc/mm/fault.c | 4 +- arch/powerpc/xmon/xmon.c | 21 ++++++--- 14 files changed, 187 insertions(+), 129 deletions(-)
arch/powerpc/include/asm/debug.h +9 -6
@@ -4,6 +4,8 @@#ifndef _ASM_POWERPC_DEBUG_H#define _ASM_POWERPC_DEBUG_H +#include <asm/hw_breakpoint.h> +struct pt_regs ;extern struct dentry *powerpc_debugfs_root;
@@ -15,7 +17,7 @@ extern int (*__debugger_ipi)(struct pt_regs *regs);extern int (*__debugger_bpt)(struct pt_regs *regs);extern int (*__debugger_sstep)(struct pt_regs *regs);extern int (*__debugger_iabr_match)(struct pt_regs *regs); -extern int (*__debugger_dabr_match)(struct pt_regs *regs); +extern int (*__debugger_break_match)(struct pt_regs *regs);extern int (*__debugger_fault_handler)(struct pt_regs *regs);#define DEBUGGER_BOILERPLATE (__NAME) \
@@ -31,7 +33,7 @@ DEBUGGER_BOILERPLATE(debugger_ipi) DEBUGGER_BOILERPLATE(debugger_bpt) DEBUGGER_BOILERPLATE(debugger_sstep) DEBUGGER_BOILERPLATE(debugger_iabr_match) -DEBUGGER_BOILERPLATE(debugger_dabr_match) +DEBUGGER_BOILERPLATE(debugger_break_match) DEBUGGER_BOILERPLATE(debugger_fault_handler)#else
@@ -40,17 +42,18 @@ static inline int debugger_ipi(struct pt_regs *regs) { return 0; }static inline int debugger_bpt (struct pt_regs *regs) {return 0 ; }static inline int debugger_sstep (struct pt_regs *regs) {return 0 ; }static inline int debugger_iabr_match (struct pt_regs *regs) {return 0 ; } -static inline int debugger_dabr_match (struct pt_regs *regs) {return 0 ; } +static inline int debugger_break_match (struct pt_regs *regs) {return 0 ; }static inline int debugger_fault_handler (struct pt_regs *regs) {return 0 ; }#endif -extern int set_dabr (unsigned long dabr,unsigned long dabrx); +int set_break (struct arch_hw_breakpoint *brk);#ifdef CONFIG_PPC_ADV_DEBUG_REGS extern void do_send_trap (struct pt_regs *regs,unsigned long address,unsigned long error_code,int signal_code,int brkpt);#else -extern void do_dabr (struct pt_regs *regs,unsigned long address, -unsigned long error_code); + +extern void do_break (struct pt_regs *regs,unsigned long address, +unsigned long error_code);#endif #endif /* _ASM_POWERPC_DEBUG_H */
arch/powerpc/include/asm/hw_breakpoint.h +26 -7
@@ -24,16 +24,30 @@#define _PPC_BOOK3S_64_HW_BREAKPOINT_H#ifdef __KERNEL__ -#ifdef CONFIG_HAVE_HW_BREAKPOINT -struct arch_hw_breakpoint {unsigned long address; -unsigned long dabrx; -int type; -u8 len;/* length of the target data symbol */ -bool extraneous_interrupt; +u16 type; +u16 len;/* length of the target data symbol */ }; +/* Note: Don't change the the first 6 bits below as they are in the same order +* as the dabr and dabrx. +*/ +#define HW_BRK_TYPE_READ 0x01 +#define HW_BRK_TYPE_WRITE 0x02 +#define HW_BRK_TYPE_TRANSLATE 0x04 +#define HW_BRK_TYPE_USER 0x08 +#define HW_BRK_TYPE_KERNEL 0x10 +#define HW_BRK_TYPE_HYP 0x20 +#define HW_BRK_TYPE_EXTRANEOUS_IRQ 0x80 + +/* bits that overlap with the bottom 3 bits of the dabr */ +#define HW_BRK_TYPE_RDWR (HW_BRK_TYPE_READ | HW_BRK_TYPE_WRITE) +#define HW_BRK_TYPE_DABR (HW_BRK_TYPE_RDWR | HW_BRK_TYPE_TRANSLATE) +#define HW_BRK_TYPE_PRIV_ALL (HW_BRK_TYPE_USER | HW_BRK_TYPE_KERNEL | \ + HW_BRK_TYPE_HYP) + +#ifdef CONFIG_HAVE_HW_BREAKPOINT #include <linux/kdebug.h> #include <asm/reg.h> #include <asm/debug.h>
@@ -62,7 +76,12 @@ extern void ptrace_triggered(struct perf_event *bp, struct perf_sample_data *data, struct pt_regs *regs);static inline void hw_breakpoint_disable (void ) { -set_dabr (0 ,0 ); +struct arch_hw_breakpoint brk; + + brk.address =0 ; + brk.type =0 ; + brk.len =0 ; +set_break (&brk); }extern void thread_change_pc (struct task_struct *tsk,struct pt_regs *regs);
arch/powerpc/include/asm/processor.h +2 -2
@@ -23,6 +23,7 @@#include <linux/cache.h> #include <asm/ptrace.h> #include <asm/types.h> +#include <asm/hw_breakpoint.h> /* We do _not_ want to define new machine types at all, those must die * in favor of using the device-tree
@@ -216,8 +217,7 @@ struct thread_struct {struct perf_event *last_hit_ubp;#endif /* CONFIG_HAVE_HW_BREAKPOINT */ #endif -unsigned long dabr;/* Data address breakpoint register */ -unsigned long dabrx;/* ... extension */ +struct arch_hw_breakpoint hw_brk;/* info on the hardware breakpoint */ unsigned long trap_nr;/* last trap # on this thread */ #ifdef CONFIG_ALTIVEC /* Complete AltiVec register set */
arch/powerpc/include/asm/reg.h +0 -3
@@ -227,9 +227,6 @@#define DAWRX_KERNEL (1UL << 1)#define DAWRX_HYP (1UL << 2)#define SPRN_DABR 0x3F5/* Data Address Breakpoint Register */ -#define DABR_TRANSLATION (1UL << 2) -#define DABR_DATA_WRITE (1UL << 1) -#define DABR_DATA_READ (1UL << 0)#define SPRN_DABR2 0x13D/* e300 */ #define SPRN_DABRX 0x3F7/* Data Address Breakpoint Register Extension */ #define DABRX_USER (1UL << 0)
arch/powerpc/kernel/exceptions-64s.S +1 -1
@@ -1310,7 +1310,7 @@ handle_dabr_fault: ld r4,_DAR(r1) ld r5,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD - bl .do_dabr + bl .do_break 12: b .ret_from_except_lite
arch/powerpc/kernel/hw_breakpoint.c +30 -42
134 lines not on this page · raw message
arch/powerpc/kernel/kgdb.c +5 -5
@@ -198,7 +198,7 @@ static int kgdb_iabr_match(struct pt_regs *regs)return 1 ; } -static int kgdb_dabr_match (struct pt_regs *regs) +static int kgdb_break_match (struct pt_regs *regs) {if (user_mode (regs))return 0 ;
@@ -458,7 +458,7 @@ static void *old__debugger;static void *old__debugger_bpt;static void *old__debugger_sstep;static void *old__debugger_iabr_match; -static void *old__debugger_dabr_match; +static void *old__debugger_break_match;static void *old__debugger_fault_handler;int kgdb_arch_init (void )
@@ -468,7 +468,7 @@ int kgdb_arch_init(void) old__debugger_bpt = __debugger_bpt; old__debugger_sstep = __debugger_sstep; old__debugger_iabr_match = __debugger_iabr_match; - old__debugger_dabr_match = __debugger_dabr_match; + old__debugger_break_match = __debugger_break_match; old__debugger_fault_handler = __debugger_fault_handler; __debugger_ipi = kgdb_call_nmi_hook;
@@ -476,7 +476,7 @@ int kgdb_arch_init(void) __debugger_bpt = kgdb_handle_breakpoint; __debugger_sstep = kgdb_singlestep; __debugger_iabr_match = kgdb_iabr_match; - __debugger_dabr_match = kgdb_dabr_match; + __debugger_break_match = kgdb_break_match; __debugger_fault_handler = kgdb_not_implemented;return 0 ;
@@ -489,6 +489,6 @@ void kgdb_arch_exit(void) __debugger_bpt = old__debugger_bpt; __debugger_sstep = old__debugger_sstep; __debugger_iabr_match = old__debugger_iabr_match; - __debugger_dabr_match = old__debugger_dabr_match; + __debugger_breakx_match = old__debugger_break_match; __debugger_fault_handler = old__debugger_fault_handler; }
arch/powerpc/kernel/process.c +54 -21
127 lines not on this page · raw message
arch/powerpc/kernel/ptrace.c +32 -28
149 lines not on this page · raw message
arch/powerpc/kernel/ptrace32.c +7 -1
@@ -252,6 +252,9 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, }case PTRACE_GET_DEBUGREG : { +#ifndef CONFIG_PPC_ADV_DEBUG_REGS +unsigned long dabr_fake; +#endif ret = -EINVAL ;/* We only support one DABR and no IABRS at the moment */ if (addr >0 )
@@ -259,7 +262,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,#ifdef CONFIG_PPC_ADV_DEBUG_REGS ret =put_user (child->thread.dac1, (u32 __user *)data);#else - ret =put_user (child->thread.dabr, (u32 __user *)data); + dabr_fake = ( + (child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR )) | + (child->thread.hw_brk.type &HW_BRK_TYPE_DABR )); + ret =put_user (dabr_fake, (u32 __user *)data);#endif break ; }
arch/powerpc/kernel/signal.c +3 -2
@@ -130,8 +130,9 @@ static int do_signal(struct pt_regs *regs)* user space. The DABR will have been cleared if it * triggered inside the kernel. */ -if (current->thread.dabr) -set_dabr (current->thread.dabr, current->thread.dabrx); +if (current->thread.hw_brk.address && + current->thread.hw_brk.type) +set_break (¤t->thread.hw_brk);#endif /* Re-enable the breakpoints for the signal stack */ thread_change_pc (current, regs);
arch/powerpc/kernel/traps.c +2 -2
@@ -67,7 +67,7 @@ int (*__debugger_ipi)(struct pt_regs *regs) __read_mostly;int (*__debugger_bpt)(struct pt_regs *regs)__read_mostly ;int (*__debugger_sstep)(struct pt_regs *regs)__read_mostly ;int (*__debugger_iabr_match)(struct pt_regs *regs)__read_mostly ; -int (*__debugger_dabr_match)(struct pt_regs *regs)__read_mostly ; +int (*__debugger_break_match)(struct pt_regs *regs)__read_mostly ;int (*__debugger_fault_handler)(struct pt_regs *regs)__read_mostly ;EXPORT_SYMBOL (__debugger);
@@ -75,7 +75,7 @@ EXPORT_SYMBOL(__debugger_ipi);EXPORT_SYMBOL (__debugger_bpt);EXPORT_SYMBOL (__debugger_sstep);EXPORT_SYMBOL (__debugger_iabr_match); -EXPORT_SYMBOL (__debugger_dabr_match); +EXPORT_SYMBOL (__debugger_break_match);EXPORT_SYMBOL (__debugger_fault_handler);#endif
arch/powerpc/mm/fault.c +2 -2
@@ -249,8 +249,8 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE ) || \ defined(CONFIG_PPC_BOOK3S_64 ))if (error_code &DSISR_DABRMATCH ) { -/* DABR match */ -do_dabr (regs, address, error_code); +/* breakpoint match */ +do_break (regs, address, error_code);return 0 ; }#endif
arch/powerpc/xmon/xmon.c +14 -7
@@ -43,6 +43,7 @@#include <asm/setjmp.h> #include <asm/reg.h> #include <asm/debug.h> +#include <asm/hw_breakpoint.h> #ifdef CONFIG_PPC64 #include <asm/hvcall.h>
@@ -607,7 +608,7 @@ static int xmon_sstep(struct pt_regs *regs)return 1 ; } -static int xmon_dabr_match (struct pt_regs *regs) +static int xmon_break_match (struct pt_regs *regs) {if ((regs->msr & (MSR_IR |MSR_PR |MSR_64BIT )) != (MSR_IR |MSR_64BIT ))return 0 ;
@@ -740,8 +741,14 @@ static void insert_bpts(void)static void insert_cpu_bpts (void ) { -if (dabr.enabled) -set_dabr (dabr.address | (dabr.enabled &7 ),DABRX_ALL ); +struct arch_hw_breakpoint brk; + +if (dabr.enabled) { + brk.address = dabr.address; + brk.type = (dabr.enabled &HW_BRK_TYPE_DABR ) |HW_BRK_TYPE_PRIV_ALL ; + brk.len =8 ; +set_break (&brk); + }if (iabr &&cpu_has_feature (CPU_FTR_IABR ))mtspr (SPRN_IABR , iabr->address | (iabr->enabled & (BP_IABR |BP_IABR_TE )));
@@ -769,7 +776,7 @@ static void remove_bpts(void)static void remove_cpu_bpts (void ) { -set_dabr (0 ,0 ); +hw_breakpoint_disable ();if (cpu_has_feature (CPU_FTR_IABR ))mtspr (SPRN_IABR ,0 ); }
@@ -1138,7 +1145,7 @@ bpt_cmds(void)printf (badaddr);break ; } - dabr.address &= ~7 ; + dabr.address &= ~HW_BRK_TYPE_DABR ; dabr.enabled = mode |BP_DABR ; }break ;
@@ -2917,7 +2924,7 @@ static void xmon_init(int enable) __debugger_bpt = xmon_bpt; __debugger_sstep = xmon_sstep; __debugger_iabr_match = xmon_iabr_match; - __debugger_dabr_match = xmon_dabr_match; + __debugger_break_match = xmon_break_match; __debugger_fault_handler = xmon_fault_handler; }else { __debugger =NULL ;
@@ -2925,7 +2932,7 @@ static void xmon_init(int enable) __debugger_bpt =NULL ; __debugger_sstep =NULL ; __debugger_iabr_match =NULL ; - __debugger_dabr_match =NULL ; + __debugger_break_match =NULL ; __debugger_fault_handler =NULL ; } }
Signature · 1 line
1.7.10.4
PATCH 1/1 powerpc: Fix typo in breakpoint kgdb code.
In reply to Michael NeulingCurrently we are getting:
arch/powerpc/kernel/kgdb.c: In function 'kgdb_arch_exit':
arch/powerpc/kernel/kgdb.c:492:2: error: '__debugger_breakx_match' undeclared (first use in this function) arch/powerpc/kernel/kgdb.c:492:2: note: each undeclared identifier is reported only once for each function it appears in
Fix the typo.
---
Stupid error. I guess my defconfigs didn't compile this code... sorry.
arch/powerpc/kernel/kgdb.c +1 -1
@@ -489,6 +489,6 @@ void kgdb_arch_exit(void) __debugger_bpt = old__debugger_bpt; __debugger_sstep = old__debugger_sstep; __debugger_iabr_match = old__debugger_iabr_match; - __debugger_breakx_match = old__debugger_break_match; + __debugger_break_match = old__debugger_break_match; __debugger_fault_handler = old__debugger_fault_handler; }
A message that is not in the archive (sent off-list or not yet received): 12813.1357794092__45363.9676016339$1357794149$gmane$org@ale.ozlabs.ibm.com
PATCH 1/1 powerpc: fix hw breakpoints on !HAVE_HW_BREAKPOINT configurations
This fixes a logic error that caused a failure to update the hw breakpoint registers when not using the hw-breakpoint interface.
--- arch/powerpc/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kernel/process.c +1 -1
@@ -690,7 +690,7 @@ struct task_struct *__switch_to(struct task_struct *prev,* schedule DABR */ #ifndef CONFIG_HAVE_HW_BREAKPOINT -if (unlikely (hw_brk_match (&__get_cpu_var (current_brk), &new->thread.hw_brk))) +if (unlikely (!hw_brk_match (&__get_cpu_var (current_brk), &new->thread.hw_brk)))set_breakpoint (&new->thread.hw_brk);#endif /* CONFIG_HAVE_HW_BREAKPOINT */ #endif
Signature · 7 lines
1.8.5.3 -- Andreas Schwab, [email protected] GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different."
Re: [PATCH] powerpc: fix hw breakpoints on !HAVE_HW_BREAKPOINT configurations
I'm not near my machine to test but looks good.
Thanks,
Mikey
Quoted 34 lines · Andreas Schwab
This fixes a logic error that caused a failure to update the hw breakpoint registers when not using the hw-breakpoint interface.
Signed-off-by Andreas Schwab <[email protected]>--- arch/powerpc/kernel/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)arch/powerpc/kernel/process.c +1
-1@@ -690,7 +690,7 @@ struct task_struct *__switch_to(struct task_struct*prev, * schedule DABR */ #ifndef CONFIG_HAVE_HW_BREAKPOINT -if (unlikely (hw_brk_match (&__get_cpu_var (current_brk), &new->thread.hw_brk))) +if (unlikely (!hw_brk_match (&__get_cpu_var (current_brk), &new->thread.hw_brk)))set_breakpoint(&new->thread.hw_brk);#endif /*
CONFIG_HAVE_HW_BREAKPOINT*/
#endif
--
1.8.5.3--
Andreas Schwab, [email protected]
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different."
PATCH 7/7 powerpc: Add the DAWR support to the set_break()
In reply to Michael NeulingThis adds DAWR supoprt to the set_break().
It does both bare metal and PAPR versions of setting the DAWR.
There is still some work we can do to make full use of the watchpoint but that will come later.
--- arch/powerpc/include/asm/machdep.h | 4 ++++ arch/powerpc/kernel/process.c | 23 +++++++++++++++++++++++ arch/powerpc/platforms/pseries/setup.c | 12 ++++++++++++ 3 files changed, 39 insertions(+)
arch/powerpc/include/asm/machdep.h +4 -0
@@ -180,6 +180,10 @@ struct machdep_calls {int (*set_dabr)(unsigned long dabr,unsigned long dabrx); +/* Set DAWR for this platform, leave empty for default implemenation */ +int (*set_dawr)(unsigned long dawr, +unsigned long dawrx); +#ifdef CONFIG_PPC32 /* XXX for now */ /* A general init function, called by ppc_init in init/main.c. May be NULL. */
arch/powerpc/kernel/process.c +23 -0
@@ -412,10 +412,33 @@ static inline int set_dabr(struct arch_hw_breakpoint *brk)return 0 ; } +static inline int set_dawr (struct arch_hw_breakpoint *brk) +{ +unsigned long dawr, dawrx; + + dawr = brk->address; + + dawrx = (brk->type & (HW_BRK_TYPE_READ |HW_BRK_TYPE_WRITE )) \ + << (63 -58 );//* read/write bits */ + dawrx |= ((brk->type & (HW_BRK_TYPE_TRANSLATE )) >>2 ) \ + << (63 -59 );//* translate */ + dawrx |= (brk->type & (HW_BRK_TYPE_PRIV_ALL )) \ + >>3 ;//* PRIM bits */ + +if (ppc_md.set_dawr) +return ppc_md.set_dawr (dawr, dawrx); +mtspr (SPRN_DAWR , dawr); +mtspr (SPRN_DAWRX , dawrx); +return 0 ; +} +int set_break (struct arch_hw_breakpoint *brk) {__get_cpu_var (current_brk) = *brk; +if (cpu_has_feature (CPU_FTR_DAWR )) +return set_dawr (brk); +return set_dabr (brk); }
arch/powerpc/platforms/pseries/setup.c +12 -0
@@ -65,6 +65,7 @@#include <asm/smp.h> #include <asm/firmware.h> #include <asm/eeh.h> +#include <asm/reg.h> #include "plpar_wrappers.h" #include "pseries.h"
@@ -500,6 +501,14 @@ static int pseries_set_xdabr(unsigned long dabr, unsigned long dabrx)return plpar_hcall_norets (H_SET_XDABR , dabr, dabrx); } +static int pseries_set_dawr (unsigned long dawr,unsigned long dawrx) +{ +/* PAPR says we can't set HYP */ + dawrx &= ~DAWRX_HYP ; + +return plapr_set_watchpoint0 (dawr, dawrx); +} +#define CMO_CHARACTERISTICS_TOKEN 44#define CMO_MAXLENGTH 1026
@@ -606,6 +615,9 @@ static void __init pSeries_init_early(void)else if (firmware_has_feature (FW_FEATURE_DABR )) ppc_md.set_dabr = pseries_set_dabr; +if (firmware_has_feature (FW_FEATURE_SET_MODE )) + ppc_md.set_dawr = pseries_set_dawr; +pSeries_cmo_feature_init ();iommu_init_early_pSeries ();
Signature · 1 line
1.7.10.4