PPC64-HWBKPT: Disable interrupts for data breakpoint exceptions
Subsystems (2)
A message that is not in the archive (sent off-list or not yet received): 20100330095040.565675261@pr
PATCH 1/2 PPC64-HWBKPT: Disable interrupts for data breakpoint exceptions
Data address breakpoint exceptions are currently handled along with page-faults which require interrupts to remain in enabled state. Since exception handling for data breakpoints aren't pre-empt safe, we handle them separately.
Signed-off-by K.Prasad <[email protected]>
--- arch/powerpc/kernel/exceptions-64s.S | 13 ++++++++++++- arch/powerpc/mm/fault.c | 5 +++-- 2 files changed, 15 insertions(+), 3 deletions(-)
arch/powerpc/kernel/exceptions-64s.S +12 -1
@@ -735,8 +735,11 @@ _STATIC(do_hash_page) std r3,_DAR(r1) std r4,_DSISR(r1) - andis. r0,r4,0xa450 /* weird error? */ + andis. r0,r4,0xa410 /* weird error? */ bne- handle_page_fault /* if not, try to insert a HPTE */ + andis. r0,r4,DSISR_DABRMATCH@h + bne- handle_dabr_fault + BEGIN_FTR_SECTION andis. r0,r4,0x0020 /* Is it a segment table fault? */ bne- do_ste_alloc /* If so handle it */
@@ -823,6 +826,14 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISER bl .raw_local_irq_restore b 11f +/* We have a data breakpoint exception - handle it */ +handle_dabr_fault: + ld r4,_DAR(r1) + ld r5,_DSISR(r1) + addi r3,r1,STACK_FRAME_OVERHEAD + bl .do_dabr + b .ret_from_except_lite + /* Here we have a page fault that hash_page can't handle. */ handle_page_fault: ENABLE_INTS
arch/powerpc/mm/fault.c +3 -2
@@ -151,13 +151,14 @@ int __kprobes do_page_fault(struct pt_reif (!user_mode (regs) && (address >=TASK_SIZE ))return SIGSEGV ; -#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE )) +#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);return 0 ; } -#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/ +#endif if (in_atomic () || mm ==NULL ) {if (!user_mode (regs))
PATCH 2/2 PPC64-HWBKPT: Implement hw-breakpoints for PPC64
In reply to a message not in the archiveImplement perf-events based hw-breakpoint interfaces for PPC64 processors. These interfaces help arbitrate requests from various users and schedules them as appropriate.
Signed-off-by K.Prasad <[email protected]>
--- arch/powerpc/Kconfig | 1 arch/powerpc/include/asm/cputable.h | 4 arch/powerpc/include/asm/hw_breakpoint.h | 50 ++++ arch/powerpc/include/asm/processor.h | 8 arch/powerpc/kernel/Makefile | 1 arch/powerpc/kernel/hw_breakpoint.c | 324 +++++++++++++++++++++++++++++++ arch/powerpc/kernel/machine_kexec_64.c | 3 arch/powerpc/kernel/process.c | 6 arch/powerpc/kernel/ptrace.c | 81 +++++++ 9 files changed, 478 insertions(+)
arch/powerpc/include/asm/hw_breakpoint.h new file +50 -0
@@ -0,0 +1,50 @@ +#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H +#define _PPC_BOOK3S_64_HW_BREAKPOINT_H + +#ifdef __KERNEL__ +#define __ARCH_HW_BREAKPOINT_H +#ifdef CONFIG_PPC_BOOK3S_64 + +struct arch_hw_breakpoint { +u8 len;/* length of the target data symbol */ +int type; +unsigned long address; +}; + +#include <linux/kdebug.h> +#include <asm/reg.h> +#include <asm/system.h> + +struct perf_event ; +struct pmu ; +struct perf_sample_data ; + +#define HW_BREAKPOINT_ALIGN 0x7 +/* Maximum permissible length of any HW Breakpoint */ +#define HW_BREAKPOINT_LEN 0x8 + +extern int arch_validate_hwbkpt_settings (struct perf_event *bp, +struct task_struct *tsk); +extern int hw_breakpoint_exceptions_notify (struct notifier_block *unused, +unsigned long val,void *data); +int arch_install_hw_breakpoint (struct perf_event *bp); +void arch_uninstall_hw_breakpoint (struct perf_event *bp); +void hw_breakpoint_pmu_read (struct perf_event *bp); +extern void flush_ptrace_hw_breakpoint (struct task_struct *tsk); + +extern struct pmu perf_ops_bp; +extern void ptrace_triggered (struct perf_event *bp,int nmi, +struct perf_sample_data *data,struct pt_regs *regs); +static inline void hw_breakpoint_disable (void ) +{ +set_dabr (0 ); +} + +#else +static inline void hw_breakpoint_disable (void ) +{ +/* Function is defined only on PPC_BOOK3S_64 for now */ +} +#endif /* CONFIG_PPC_BOOK3S_64 */ +#endif /* __KERNEL__ */ +#endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
arch/powerpc/kernel/hw_breakpoint.c new file +324 -0
324 lines not on this page · raw message
arch/powerpc/Kconfig +1 -0
@@ -140,6 +140,7 @@ config PPC select HAVE_SYSCALL_WRAPPERS if PPC64 select GENERIC_ATOMIC64 if PPC32 select HAVE_PERF_EVENTS + select HAVE_HW_BREAKPOINT if PPC_BOOK3S_64 config EARLY_PRINTK bool
arch/powerpc/kernel/Makefile +1 -0
@@ -34,6 +34,7 @@ obj-y += vdso32/ obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ signal_64.o ptrace32.o \ paca.o nvram_64.o firmware.o +obj-$(CONFIG_PPC_BOOK3S_64) += hw_breakpoint.o obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o obj64-$(CONFIG_RELOCATABLE) += reloc_64.o obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o
arch/powerpc/include/asm/processor.h +8 -0
@@ -209,6 +209,14 @@ struct thread_struct {#ifdef CONFIG_PPC64 unsigned long start_tb;/* Start purr when proc switched in */ unsigned long accum_tb;/* Total accumilated purr for process */ +#ifdef CONFIG_PPC_BOOK3S_64 +struct perf_event *ptrace_bps[HBP_NUM ]; +/* +* Helps identify source of single-step exception and subsequent +* hw-breakpoint enablement +*/ +struct perf_event *last_hit_ubp; +#endif /* CONFIG_PPC_BOOK3S_64 */ #endif unsigned long dabr;/* Data address breakpoint register */ #ifdef CONFIG_ALTIVEC
arch/powerpc/kernel/ptrace.c +81 -0
102 lines not on this page · raw message
arch/powerpc/kernel/process.c +6 -0
@@ -459,8 +459,14 @@ struct task_struct *__switch_to(struct t#ifdef CONFIG_PPC_ADV_DEBUG_REGS switch_booke_debug_regs (&new->thread);#else +/* +* For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would +* schedule DABR +*/ +#ifndef CONFIG_PPC_BOOK3S_64 if (unlikely (__get_cpu_var (current_dabr) != new->thread.dabr))set_dabr (new->thread.dabr); +#endif /* CONFIG_PPC_BOOK3S_64 */ #endif
arch/powerpc/include/asm/cputable.h +4 -0
@@ -511,6 +511,10 @@ static inline int cpu_has_feature(unsign & feature); } +#ifdef CONFIG_PPC_BOOK3S_64 +#define HBP_NUM 1 +#endif /* CONFIG_PPC_BOOK3S_64 */ +#endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */
arch/powerpc/kernel/machine_kexec_64.c +3 -0
@@ -15,6 +15,7 @@#include <linux/thread_info.h> #include <linux/init_task.h> #include <linux/errno.h> +#include <linux/hw_breakpoint.h> #include <asm/page.h> #include <asm/current.h>
@@ -161,6 +162,7 @@ void kexec_copy_flush(struct kimage *ima*/ static void kexec_smp_down (void *arg) { +hw_breakpoint_disable ();if (ppc_md.kexec_cpu_down) ppc_md.kexec_cpu_down (0 ,1 );
@@ -174,6 +176,7 @@ static void kexec_prepare_cpus(void)int my_cpu, i, notified=-1 ;smp_call_function (kexec_smp_down,NULL ,/* wait */ 0 ); +hw_breakpoint_disable (); my_cpu =get_cpu ();/* check the others cpus are now down (via paca hw cpu id == -1) */