Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 330298
b: refs/heads/master
c: 4474ef0
h: refs/heads/master
v: v3
  • Loading branch information
Michael Neuling authored and Benjamin Herrenschmidt committed Sep 9, 2012
1 parent ff29e87 commit 5ff5e2c
Show file tree
Hide file tree
Showing 15 changed files with 47 additions and 31 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3ab96a02e829131c19db8ed99239289acdb4e3dc
refs/heads/master: 4474ef055c5d8cb8eaf002d69e49af71e3aa3a88
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/include/asm/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static inline int debugger_dabr_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);
extern int set_dabr(unsigned long dabr, unsigned long dabrx);
#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);
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/include/asm/hw_breakpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ 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);
set_dabr(0, 0);
}
extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);

Expand Down
3 changes: 2 additions & 1 deletion trunk/arch/powerpc/include/asm/machdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ struct machdep_calls {
void (*enable_pmcs)(void);

/* Set DABR for this platform, leave empty for default implemenation */
int (*set_dabr)(unsigned long dabr);
int (*set_dabr)(unsigned long dabr,
unsigned long dabrx);

#ifdef CONFIG_PPC32 /* XXX for now */
/* A general init function, called by ppc_init in init/main.c.
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/powerpc/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ struct thread_struct {
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
#endif
unsigned long dabr; /* Data address breakpoint register */
unsigned long dabrx; /* ... extension */
unsigned long trap_nr; /* last trap # on this thread */
#ifdef CONFIG_ALTIVEC
/* Complete AltiVec register set */
Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/powerpc/include/asm/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@
#define SPRN_DABRX 0x3F7 /* Data Address Breakpoint Register Extension */
#define DABRX_USER (1UL << 0)
#define DABRX_KERNEL (1UL << 1)
#define DABRX_HYP (1UL << 2)
#define DABRX_BTI (1UL << 3)
#define DABRX_ALL (DABRX_BTI | DABRX_HYP | DABRX_KERNEL | DABRX_USER)
#define SPRN_DAR 0x013 /* Data Address Register */
#define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */
#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
Expand Down
12 changes: 6 additions & 6 deletions trunk/arch/powerpc/kernel/hw_breakpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
* If so, DABR will be populated in single_step_dabr_instruction().
*/
if (current->thread.last_hit_ubp != bp)
set_dabr(info->address | info->type | DABR_TRANSLATION);
set_dabr(info->address | info->type | DABR_TRANSLATION, DABRX_ALL);

return 0;
}
Expand All @@ -97,7 +97,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
}

*slot = NULL;
set_dabr(0);
set_dabr(0, 0);
}

/*
Expand Down Expand Up @@ -197,7 +197,7 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)

info = counter_arch_bp(tsk->thread.last_hit_ubp);
regs->msr &= ~MSR_SE;
set_dabr(info->address | info->type | DABR_TRANSLATION);
set_dabr(info->address | info->type | DABR_TRANSLATION, DABRX_ALL);
tsk->thread.last_hit_ubp = NULL;
}

Expand All @@ -215,7 +215,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
unsigned long dar = regs->dar;

/* Disable breakpoints during exception handling */
set_dabr(0);
set_dabr(0, 0);

/*
* The counter may be concurrently released but that can only
Expand Down Expand Up @@ -281,7 +281,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
if (!info->extraneous_interrupt)
perf_bp_event(bp, regs);

set_dabr(info->address | info->type | DABR_TRANSLATION);
set_dabr(info->address | info->type | DABR_TRANSLATION, DABRX_ALL);
out:
rcu_read_unlock();
return rc;
Expand Down Expand Up @@ -313,7 +313,7 @@ int __kprobes single_step_dabr_instruction(struct die_args *args)
if (!info->extraneous_interrupt)
perf_bp_event(bp, regs);

set_dabr(info->address | info->type | DABR_TRANSLATION);
set_dabr(info->address | info->type | DABR_TRANSLATION, DABRX_ALL);
current->thread.last_hit_ubp = NULL;

/*
Expand Down
14 changes: 7 additions & 7 deletions trunk/arch/powerpc/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ void do_dabr(struct pt_regs *regs, unsigned long address,
return;

/* Clear the DABR */
set_dabr(0);
set_dabr(0, 0);

/* Deliver the signal to userspace */
info.si_signo = SIGTRAP;
Expand Down Expand Up @@ -366,18 +366,19 @@ static void set_debug_reg_defaults(struct thread_struct *thread)
{
if (thread->dabr) {
thread->dabr = 0;
set_dabr(0);
thread->dabrx = 0;
set_dabr(0, 0);
}
}
#endif /* !CONFIG_HAVE_HW_BREAKPOINT */
#endif /* CONFIG_PPC_ADV_DEBUG_REGS */

int set_dabr(unsigned long dabr)
int set_dabr(unsigned long dabr, unsigned long dabrx)
{
__get_cpu_var(current_dabr) = dabr;

if (ppc_md.set_dabr)
return ppc_md.set_dabr(dabr);
return ppc_md.set_dabr(dabr, dabrx);

/* XXX should we have a CPU_FTR_HAS_DABR ? */
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
Expand All @@ -387,9 +388,8 @@ int set_dabr(unsigned long dabr)
#endif
#elif defined(CONFIG_PPC_BOOK3S)
mtspr(SPRN_DABR, dabr);
mtspr(SPRN_DABRX, dabrx);
#endif


return 0;
}

Expand Down Expand Up @@ -482,7 +482,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
*/
#ifndef CONFIG_HAVE_HW_BREAKPOINT
if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
set_dabr(new->thread.dabr);
set_dabr(new->thread.dabr, new->thread.dabrx);
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
#endif

Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/powerpc/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
thread->ptrace_bps[0] = bp;
ptrace_put_breakpoints(task);
thread->dabr = data;
thread->dabrx = DABRX_ALL;
return 0;
}

Expand All @@ -983,6 +984,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,

/* Move contents to the DABR register */
task->thread.dabr = data;
task->thread.dabrx = DABRX_ALL;
#else /* CONFIG_PPC_ADV_DEBUG_REGS */
/* As described above, it was assumed 3 bits were passed with the data
* address, but we will assume only the mode bits will be passed
Expand Down Expand Up @@ -1397,6 +1399,7 @@ static long ppc_set_hwdebug(struct task_struct *child,
dabr |= DABR_DATA_WRITE;

child->thread.dabr = dabr;
child->thread.dabrx = DABRX_ALL;

return 1;
#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ static int do_signal(struct pt_regs *regs)
* triggered inside the kernel.
*/
if (current->thread.dabr)
set_dabr(current->thread.dabr);
set_dabr(current->thread.dabr, current->thread.dabrx);
#endif
/* Re-enable the breakpoints for the signal stack */
thread_change_pc(current, regs);
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/powerpc/platforms/cell/beat.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,9 @@ ssize_t beat_nvram_get_size(void)
return BEAT_NVRAM_SIZE;
}

int beat_set_xdabr(unsigned long dabr)
int beat_set_xdabr(unsigned long dabr, unsigned long dabrx)
{
if (beat_set_dabr(dabr, DABRX_KERNEL | DABRX_USER))
if (beat_set_dabr(dabr, dabrx))
return -1;
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/powerpc/platforms/cell/beat.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void beat_get_rtc_time(struct rtc_time *);
ssize_t beat_nvram_get_size(void);
ssize_t beat_nvram_read(char *, size_t, loff_t *);
ssize_t beat_nvram_write(char *, size_t, loff_t *);
int beat_set_xdabr(unsigned long);
int beat_set_xdabr(unsigned long, unsigned long);
void beat_power_save(void);
void beat_kexec_cpu_down(int, int);

Expand Down
10 changes: 7 additions & 3 deletions trunk/arch/powerpc/platforms/ps3/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,15 @@ early_param("ps3flash", early_parse_ps3flash);
#define prealloc_ps3flash_bounce_buffer() do { } while (0)
#endif

static int ps3_set_dabr(unsigned long dabr)
static int ps3_set_dabr(unsigned long dabr, unsigned long dabrx)
{
enum {DABR_USER = 1, DABR_KERNEL = 2,};
/* Have to set at least one bit in the DABRX */
if (dabrx == 0 && dabr == 0)
dabrx = DABRX_USER;
/* hypervisor only allows us to set BTI, Kernel and user */
dabrx &= DABRX_BTI | DABRX_KERNEL | DABRX_USER;

return lv1_set_dabr(dabr, DABR_KERNEL | DABR_USER) ? -1 : 0;
return lv1_set_dabr(dabr, dabrx) ? -1 : 0;
}

static void __init ps3_setup_arch(void)
Expand Down
14 changes: 9 additions & 5 deletions trunk/arch/powerpc/platforms/pseries/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,16 +414,20 @@ static int __init pSeries_init_panel(void)
}
machine_arch_initcall(pseries, pSeries_init_panel);

static int pseries_set_dabr(unsigned long dabr)
static int pseries_set_dabr(unsigned long dabr, unsigned long dabrx)
{
return plpar_hcall_norets(H_SET_DABR, dabr);
}

static int pseries_set_xdabr(unsigned long dabr)
static int pseries_set_xdabr(unsigned long dabr, unsigned long dabrx)
{
/* We want to catch accesses from kernel and userspace */
return plpar_hcall_norets(H_SET_XDABR, dabr,
H_DABRX_KERNEL | H_DABRX_USER);
/* Have to set at least one bit in the DABRX according to PAPR */
if (dabrx == 0 && dabr == 0)
dabrx = DABRX_USER;
/* PAPR says we can only set kernel and user bits */
dabrx &= H_DABRX_KERNEL | H_DABRX_USER;

return plpar_hcall_norets(H_SET_XDABR, dabr, dabrx);
}

#define CMO_CHARACTERISTICS_TOKEN 44
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/powerpc/xmon/xmon.c
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,7 @@ static void insert_bpts(void)
static void insert_cpu_bpts(void)
{
if (dabr.enabled)
set_dabr(dabr.address | (dabr.enabled & 7));
set_dabr(dabr.address | (dabr.enabled & 7), DABRX_ALL);
if (iabr && cpu_has_feature(CPU_FTR_IABR))
mtspr(SPRN_IABR, iabr->address
| (iabr->enabled & (BP_IABR|BP_IABR_TE)));
Expand Down Expand Up @@ -768,7 +768,7 @@ static void remove_bpts(void)

static void remove_cpu_bpts(void)
{
set_dabr(0);
set_dabr(0, 0);
if (cpu_has_feature(CPU_FTR_IABR))
mtspr(SPRN_IABR, 0);
}
Expand Down

0 comments on commit 5ff5e2c

Please sign in to comment.