Messages in this thread Patch in this message | | | Date | Mon, 26 Oct 2020 17:05:13 +0100 | From | Peter Zijlstra <> | Subject | Re: [REGRESSION] x86/debug: After PTRACE_SINGLESTEP DR_STEP is no longer reported in dr6 |
| |
On Mon, Oct 26, 2020 at 04:55:21PM +0100, Peter Zijlstra wrote: > On Mon, Oct 26, 2020 at 07:33:08AM -0700, Kyle Huey wrote: > > After resuming a ptracee with PTRACE_SINGLESTEP, in the following > > ptrace stop retrieving the dr6 value for the tracee gets a value that > > does not include DR_STEP (it is in fact always DR6_RESERVED). I > > bisected this to the 13cb73490f475f8e7669f9288be0bcfa85399b1f merge. I > > did not bisect further. > > > > I don't see any handling to ever set DR_STEP in virtual_dr6, so I > > think this code is just broken. > > > > Sorry for not testing this when I was CCd on the original patch series :) > > Urgh, now I have to try and remember how all that worked again ... > > I suspect it's either one (or both) of the last two: > > f4956cf83ed1 ("x86/debug: Support negative polarity DR6 bits") > d53d9bc0cf78 ("x86/debug: Change thread.debugreg6 to thread.virtual_dr6") > > > Just to clarify, the sequence is something like: > > - tracer: ptrace(PTRACE_SINGLESTEP) > - tracee: #DB, DR6 contains DR_STEP > - tracer: ptrace_get_debugreg(6) > > ? > > You're right that that would be broken, let me try and figure out what > the best way would be 'fix' that. > > Also, can you confirm that pthread_set_debugreg(6) should not do > anything useful?
Does something like this make sense?
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 3c70fb34028b..0e7641ac19a8 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -799,6 +799,13 @@ static __always_inline unsigned long debug_read_clear_dr6(void) */ current->thread.virtual_dr6 = 0; + /* + * If PTRACE requested SINGLE(BLOCK)STEP, make sure to reflect that in + * the ptrace visible DR6 copy. + */ + if (test_thread_flag(TIF_BLOCKSTEP) || test_thread_flag(TIF_SINGLESTEP)) + current->thread.virtual_dr6 |= dr6 & DR_STEP; + /* * The SDM says "The processor clears the BTF flag when it * generates a debug exception." Clear TIF_BLOCKSTEP to keep
| |