Re: [PATCH v5 10/13] powerpc/ptrace: split out ADV_DEBUG_REGS related functions.
Le 24/03/2020 à 07:23, Michael Ellerman a écrit : Christophe Leroy writes: On 03/20/2020 02:12 AM, Michael Ellerman wrote: Christophe Leroy writes: Move ADV_DEBUG_REGS functions out of ptrace.c, into ptrace-adv.c and ptrace-noadv.c Signed-off-by: Christophe Leroy --- v4: Leave hw_breakpoint.h for ptrace.c --- arch/powerpc/kernel/ptrace/Makefile | 4 + arch/powerpc/kernel/ptrace/ptrace-adv.c | 468 arch/powerpc/kernel/ptrace/ptrace-decl.h | 5 + arch/powerpc/kernel/ptrace/ptrace-noadv.c | 236 arch/powerpc/kernel/ptrace/ptrace.c | 650 -- 5 files changed, 713 insertions(+), 650 deletions(-) create mode 100644 arch/powerpc/kernel/ptrace/ptrace-adv.c create mode 100644 arch/powerpc/kernel/ptrace/ptrace-noadv.c This is somehow breaking the ptrace-hwbreak selftest on Power8: test: ptrace-hwbreak tags: git_version:v5.6-rc6-892-g7a285a6067d6 PTRACE_SET_DEBUGREG, WO, len: 1: Ok PTRACE_SET_DEBUGREG, WO, len: 2: Ok PTRACE_SET_DEBUGREG, WO, len: 4: Ok PTRACE_SET_DEBUGREG, WO, len: 8: Ok PTRACE_SET_DEBUGREG, RO, len: 1: Ok PTRACE_SET_DEBUGREG, RO, len: 2: Ok PTRACE_SET_DEBUGREG, RO, len: 4: Ok PTRACE_SET_DEBUGREG, RO, len: 8: Ok PTRACE_SET_DEBUGREG, RW, len: 1: Ok PTRACE_SET_DEBUGREG, RW, len: 2: Ok PTRACE_SET_DEBUGREG, RW, len: 4: Ok PTRACE_SET_DEBUGREG, RW, len: 8: Ok PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO, len: 1: Ok PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RO, len: 1: Ok PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RW, len: 1: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, WO, len: 6: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RO, len: 6: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RW, len: 6: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, WO, len: 6: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, RO, len: 6: Fail failure: ptrace-hwbreak I haven't had time to work out why yet. A (big) part of commit c3f68b0478e7 ("powerpc/watchpoint: Fix ptrace code that muck around with address/len") was lost during rebase. I'll send a fix, up to you to squash it in or commit it as is. Thanks. One person asked me if I sent the fix already. So yes, it is there: https://patchwork.ozlabs.org/patch/1259348/ Christophe
Re: [PATCH v5 10/13] powerpc/ptrace: split out ADV_DEBUG_REGS related functions.
Christophe Leroy writes: > On 03/20/2020 02:12 AM, Michael Ellerman wrote: >> Christophe Leroy writes: >>> Move ADV_DEBUG_REGS functions out of ptrace.c, into >>> ptrace-adv.c and ptrace-noadv.c >>> >>> Signed-off-by: Christophe Leroy >>> --- >>> v4: Leave hw_breakpoint.h for ptrace.c >>> --- >>> arch/powerpc/kernel/ptrace/Makefile | 4 + >>> arch/powerpc/kernel/ptrace/ptrace-adv.c | 468 >>> arch/powerpc/kernel/ptrace/ptrace-decl.h | 5 + >>> arch/powerpc/kernel/ptrace/ptrace-noadv.c | 236 >>> arch/powerpc/kernel/ptrace/ptrace.c | 650 -- >>> 5 files changed, 713 insertions(+), 650 deletions(-) >>> create mode 100644 arch/powerpc/kernel/ptrace/ptrace-adv.c >>> create mode 100644 arch/powerpc/kernel/ptrace/ptrace-noadv.c >> >> This is somehow breaking the ptrace-hwbreak selftest on Power8: >> >>test: ptrace-hwbreak >>tags: git_version:v5.6-rc6-892-g7a285a6067d6 >>PTRACE_SET_DEBUGREG, WO, len: 1: Ok >>PTRACE_SET_DEBUGREG, WO, len: 2: Ok >>PTRACE_SET_DEBUGREG, WO, len: 4: Ok >>PTRACE_SET_DEBUGREG, WO, len: 8: Ok >>PTRACE_SET_DEBUGREG, RO, len: 1: Ok >>PTRACE_SET_DEBUGREG, RO, len: 2: Ok >>PTRACE_SET_DEBUGREG, RO, len: 4: Ok >>PTRACE_SET_DEBUGREG, RO, len: 8: Ok >>PTRACE_SET_DEBUGREG, RW, len: 1: Ok >>PTRACE_SET_DEBUGREG, RW, len: 2: Ok >>PTRACE_SET_DEBUGREG, RW, len: 4: Ok >>PTRACE_SET_DEBUGREG, RW, len: 8: Ok >>PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO, len: 1: Ok >>PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RO, len: 1: Ok >>PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RW, len: 1: Ok >>PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, WO, len: 6: Ok >>PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RO, len: 6: Ok >>PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RW, len: 6: Ok >>PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, WO, len: 6: Ok >>PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, RO, len: 6: Fail >>failure: ptrace-hwbreak >> >> I haven't had time to work out why yet. >> > > A (big) part of commit c3f68b0478e7 ("powerpc/watchpoint: Fix ptrace > code that muck around with address/len") was lost during rebase. > > I'll send a fix, up to you to squash it in or commit it as is. Thanks. cheers
Re: [PATCH v5 10/13] powerpc/ptrace: split out ADV_DEBUG_REGS related functions.
On 03/20/2020 02:12 AM, Michael Ellerman wrote: Christophe Leroy writes: Move ADV_DEBUG_REGS functions out of ptrace.c, into ptrace-adv.c and ptrace-noadv.c Signed-off-by: Christophe Leroy --- v4: Leave hw_breakpoint.h for ptrace.c --- arch/powerpc/kernel/ptrace/Makefile | 4 + arch/powerpc/kernel/ptrace/ptrace-adv.c | 468 arch/powerpc/kernel/ptrace/ptrace-decl.h | 5 + arch/powerpc/kernel/ptrace/ptrace-noadv.c | 236 arch/powerpc/kernel/ptrace/ptrace.c | 650 -- 5 files changed, 713 insertions(+), 650 deletions(-) create mode 100644 arch/powerpc/kernel/ptrace/ptrace-adv.c create mode 100644 arch/powerpc/kernel/ptrace/ptrace-noadv.c This is somehow breaking the ptrace-hwbreak selftest on Power8: test: ptrace-hwbreak tags: git_version:v5.6-rc6-892-g7a285a6067d6 PTRACE_SET_DEBUGREG, WO, len: 1: Ok PTRACE_SET_DEBUGREG, WO, len: 2: Ok PTRACE_SET_DEBUGREG, WO, len: 4: Ok PTRACE_SET_DEBUGREG, WO, len: 8: Ok PTRACE_SET_DEBUGREG, RO, len: 1: Ok PTRACE_SET_DEBUGREG, RO, len: 2: Ok PTRACE_SET_DEBUGREG, RO, len: 4: Ok PTRACE_SET_DEBUGREG, RO, len: 8: Ok PTRACE_SET_DEBUGREG, RW, len: 1: Ok PTRACE_SET_DEBUGREG, RW, len: 2: Ok PTRACE_SET_DEBUGREG, RW, len: 4: Ok PTRACE_SET_DEBUGREG, RW, len: 8: Ok PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO, len: 1: Ok PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RO, len: 1: Ok PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RW, len: 1: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, WO, len: 6: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RO, len: 6: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RW, len: 6: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, WO, len: 6: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, RO, len: 6: Fail failure: ptrace-hwbreak I haven't had time to work out why yet. A (big) part of commit c3f68b0478e7 ("powerpc/watchpoint: Fix ptrace code that muck around with address/len") was lost during rebase. I'll send a fix, up to you to squash it in or commit it as is. Christophe
Re: [PATCH v5 10/13] powerpc/ptrace: split out ADV_DEBUG_REGS related functions.
Christophe Leroy writes: > Move ADV_DEBUG_REGS functions out of ptrace.c, into > ptrace-adv.c and ptrace-noadv.c > > Signed-off-by: Christophe Leroy > --- > v4: Leave hw_breakpoint.h for ptrace.c > --- > arch/powerpc/kernel/ptrace/Makefile | 4 + > arch/powerpc/kernel/ptrace/ptrace-adv.c | 468 > arch/powerpc/kernel/ptrace/ptrace-decl.h | 5 + > arch/powerpc/kernel/ptrace/ptrace-noadv.c | 236 > arch/powerpc/kernel/ptrace/ptrace.c | 650 -- > 5 files changed, 713 insertions(+), 650 deletions(-) > create mode 100644 arch/powerpc/kernel/ptrace/ptrace-adv.c > create mode 100644 arch/powerpc/kernel/ptrace/ptrace-noadv.c This is somehow breaking the ptrace-hwbreak selftest on Power8: test: ptrace-hwbreak tags: git_version:v5.6-rc6-892-g7a285a6067d6 PTRACE_SET_DEBUGREG, WO, len: 1: Ok PTRACE_SET_DEBUGREG, WO, len: 2: Ok PTRACE_SET_DEBUGREG, WO, len: 4: Ok PTRACE_SET_DEBUGREG, WO, len: 8: Ok PTRACE_SET_DEBUGREG, RO, len: 1: Ok PTRACE_SET_DEBUGREG, RO, len: 2: Ok PTRACE_SET_DEBUGREG, RO, len: 4: Ok PTRACE_SET_DEBUGREG, RO, len: 8: Ok PTRACE_SET_DEBUGREG, RW, len: 1: Ok PTRACE_SET_DEBUGREG, RW, len: 2: Ok PTRACE_SET_DEBUGREG, RW, len: 4: Ok PTRACE_SET_DEBUGREG, RW, len: 8: Ok PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO, len: 1: Ok PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RO, len: 1: Ok PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RW, len: 1: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, WO, len: 6: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RO, len: 6: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, RW, len: 6: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, WO, len: 6: Ok PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW UNALIGNED, RO, len: 6: Fail failure: ptrace-hwbreak I haven't had time to work out why yet. cheers > diff --git a/arch/powerpc/kernel/ptrace/Makefile > b/arch/powerpc/kernel/ptrace/Makefile > index 7addc5994bb9..e9d97c2d063e 100644 > --- a/arch/powerpc/kernel/ptrace/Makefile > +++ b/arch/powerpc/kernel/ptrace/Makefile > @@ -14,3 +14,7 @@ endif > obj-$(CONFIG_ALTIVEC)+= ptrace-altivec.o > obj-$(CONFIG_SPE)+= ptrace-spe.o > obj-$(CONFIG_PPC_TRANSACTIONAL_MEM) += ptrace-tm.o > +obj-$(CONFIG_PPC_ADV_DEBUG_REGS) += ptrace-adv.o > +ifneq ($(CONFIG_PPC_ADV_DEBUG_REGS),y) > +obj-y+= ptrace-noadv.o > +endif > diff --git a/arch/powerpc/kernel/ptrace/ptrace-adv.c > b/arch/powerpc/kernel/ptrace/ptrace-adv.c > new file mode 100644 > index ..eebcd41edc3d > --- /dev/null > +++ b/arch/powerpc/kernel/ptrace/ptrace-adv.c > @@ -0,0 +1,468 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > + > +#include > +#include > + > +#include "ptrace-decl.h" > + > +void user_enable_single_step(struct task_struct *task) > +{ > + struct pt_regs *regs = task->thread.regs; > + > + if (regs != NULL) { > + task->thread.debug.dbcr0 &= ~DBCR0_BT; > + task->thread.debug.dbcr0 |= DBCR0_IDM | DBCR0_IC; > + regs->msr |= MSR_DE; > + } > + set_tsk_thread_flag(task, TIF_SINGLESTEP); > +} > + > +void user_enable_block_step(struct task_struct *task) > +{ > + struct pt_regs *regs = task->thread.regs; > + > + if (regs != NULL) { > + task->thread.debug.dbcr0 &= ~DBCR0_IC; > + task->thread.debug.dbcr0 = DBCR0_IDM | DBCR0_BT; > + regs->msr |= MSR_DE; > + } > + set_tsk_thread_flag(task, TIF_SINGLESTEP); > +} > + > +void user_disable_single_step(struct task_struct *task) > +{ > + struct pt_regs *regs = task->thread.regs; > + > + if (regs != NULL) { > + /* > + * The logic to disable single stepping should be as > + * simple as turning off the Instruction Complete flag. > + * And, after doing so, if all debug flags are off, turn > + * off DBCR0(IDM) and MSR(DE) Torez > + */ > + task->thread.debug.dbcr0 &= ~(DBCR0_IC | DBCR0_BT); > + /* > + * Test to see if any of the DBCR_ACTIVE_EVENTS bits are set. > + */ > + if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0, > + task->thread.debug.dbcr1)) { > + /* > + * All debug events were off. > + */ > + task->thread.debug.dbcr0 &= ~DBCR0_IDM; > + regs->msr &= ~MSR_DE; > + } > + } > + clear_tsk_thread_flag(task, TIF_SINGLESTEP); > +} > + > +int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, > unsigned long data) > +{ > +#ifdef CONFIG_HAVE_HW_BREAKPOINT > + int ret; > + struct thread_struct *thread = >thread; > + struct perf_event *bp; > + struct perf_event_attr attr; > +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ > + > + /* For ppc64 we support one DABR and no IABR's at the moment
[PATCH v5 10/13] powerpc/ptrace: split out ADV_DEBUG_REGS related functions.
Move ADV_DEBUG_REGS functions out of ptrace.c, into ptrace-adv.c and ptrace-noadv.c Signed-off-by: Christophe Leroy --- v4: Leave hw_breakpoint.h for ptrace.c --- arch/powerpc/kernel/ptrace/Makefile | 4 + arch/powerpc/kernel/ptrace/ptrace-adv.c | 468 arch/powerpc/kernel/ptrace/ptrace-decl.h | 5 + arch/powerpc/kernel/ptrace/ptrace-noadv.c | 236 arch/powerpc/kernel/ptrace/ptrace.c | 650 -- 5 files changed, 713 insertions(+), 650 deletions(-) create mode 100644 arch/powerpc/kernel/ptrace/ptrace-adv.c create mode 100644 arch/powerpc/kernel/ptrace/ptrace-noadv.c diff --git a/arch/powerpc/kernel/ptrace/Makefile b/arch/powerpc/kernel/ptrace/Makefile index 7addc5994bb9..e9d97c2d063e 100644 --- a/arch/powerpc/kernel/ptrace/Makefile +++ b/arch/powerpc/kernel/ptrace/Makefile @@ -14,3 +14,7 @@ endif obj-$(CONFIG_ALTIVEC) += ptrace-altivec.o obj-$(CONFIG_SPE) += ptrace-spe.o obj-$(CONFIG_PPC_TRANSACTIONAL_MEM)+= ptrace-tm.o +obj-$(CONFIG_PPC_ADV_DEBUG_REGS) += ptrace-adv.o +ifneq ($(CONFIG_PPC_ADV_DEBUG_REGS),y) +obj-y += ptrace-noadv.o +endif diff --git a/arch/powerpc/kernel/ptrace/ptrace-adv.c b/arch/powerpc/kernel/ptrace/ptrace-adv.c new file mode 100644 index ..eebcd41edc3d --- /dev/null +++ b/arch/powerpc/kernel/ptrace/ptrace-adv.c @@ -0,0 +1,468 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include + +#include "ptrace-decl.h" + +void user_enable_single_step(struct task_struct *task) +{ + struct pt_regs *regs = task->thread.regs; + + if (regs != NULL) { + task->thread.debug.dbcr0 &= ~DBCR0_BT; + task->thread.debug.dbcr0 |= DBCR0_IDM | DBCR0_IC; + regs->msr |= MSR_DE; + } + set_tsk_thread_flag(task, TIF_SINGLESTEP); +} + +void user_enable_block_step(struct task_struct *task) +{ + struct pt_regs *regs = task->thread.regs; + + if (regs != NULL) { + task->thread.debug.dbcr0 &= ~DBCR0_IC; + task->thread.debug.dbcr0 = DBCR0_IDM | DBCR0_BT; + regs->msr |= MSR_DE; + } + set_tsk_thread_flag(task, TIF_SINGLESTEP); +} + +void user_disable_single_step(struct task_struct *task) +{ + struct pt_regs *regs = task->thread.regs; + + if (regs != NULL) { + /* +* The logic to disable single stepping should be as +* simple as turning off the Instruction Complete flag. +* And, after doing so, if all debug flags are off, turn +* off DBCR0(IDM) and MSR(DE) Torez +*/ + task->thread.debug.dbcr0 &= ~(DBCR0_IC | DBCR0_BT); + /* +* Test to see if any of the DBCR_ACTIVE_EVENTS bits are set. +*/ + if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0, + task->thread.debug.dbcr1)) { + /* +* All debug events were off. +*/ + task->thread.debug.dbcr0 &= ~DBCR0_IDM; + regs->msr &= ~MSR_DE; + } + } + clear_tsk_thread_flag(task, TIF_SINGLESTEP); +} + +int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned long data) +{ +#ifdef CONFIG_HAVE_HW_BREAKPOINT + int ret; + struct thread_struct *thread = >thread; + struct perf_event *bp; + struct perf_event_attr attr; +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ + + /* For ppc64 we support one DABR and no IABR's at the moment (ppc64). +* For embedded processors we support one DAC and no IAC's at the +* moment. +*/ + if (addr > 0) + return -EINVAL; + + /* The bottom 3 bits in dabr are flags */ + if ((data & ~0x7UL) >= TASK_SIZE) + return -EIO; + + /* 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 +* as to not cause alignment restrictions for DAC-based processors. +*/ + + /* DAC's hold the whole address without any mode flags */ + task->thread.debug.dac1 = data & ~0x3UL; + + if (task->thread.debug.dac1 == 0) { + dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W); + if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0, + task->thread.debug.dbcr1)) { + task->thread.regs->msr &= ~MSR_DE; + task->thread.debug.dbcr0 &= ~DBCR0_IDM; + } + return 0; + } + + /* Read or Write bits must be set */ + + if (!(data & 0x3UL)) + return -EINVAL; + + /* Set the Internal Debugging flag (IDM bit 1) for the DBCR0 register */ + task->thread.debug.dbcr0 |=