Re: [RFC Patch 3/9] Modifying generic debug exception to use virtual debug registers



On Fri, 17 Oct 2008, Roland McGrath wrote:

Current Intel manuals say, "Certain debug exceptions may clear bits 0-3.
The remaining cntents of the DR6 register are never cleared by the processor."

Your experiments told us that "certain debug exceptions" includes at least
the data breakpoint hits. I assume that what it really means is all the
exceptions that set one of those four bits, i.e. ones due to DR[0-3] use.
Perhaps someone from Intel can clarify exactly what it means.

So this means that do_debug shouldn't modify the four low bits in vdr6.
[...]

Right.

I don't know how we should handle the BT (debug trap) and BS
(single-step exception) bits. Maybe the kprobes code can take care of
them.

BT is for task switch with TSS.T set. I don't think that can ever happen
in Linux, since we don't use hardware task-switching. If at all, maybe in
vm86 mode. I don't think there's a way to do it just from user_ldt.

I think BS (DR_STEP) should get set in vdr6 only when a SIGTRAP is
generated for the exception. It should never get cleared by the system,
only by PTRACE_POKEUSR. That is consistent with what we get now, AFAICT.

I don't think kprobes should "take care of" DR_STEP. It should eat a
DR_STEP that it's responsible for, and leave any others alone. i.e.,
CONFIG_KPROBE=n must not break the normal bookkeeping.

IIRC there can be one do_debug trap that's for both a breakpoint register
hit and a single-step (TF), with DR_STEP plus DR_TRAPn both set at once.
To handle that too, I think this will work:

do_debug does:

get_debugreg(condition, 6);
set_debugreg(0, 6);

Make sure the hw_breakpoint notifier is before the kprobes notifier.
hw_breakpoint is responsible for the low 4 bits of vdr6 and leaves its
other bits alone. It returns NOTIFY_STOP iff both this hit is not a ptrace
hit and hardware %db6 (args->err) has no other nonreserved bits set.

Ah yes, it's coming back to me now. The handler routines see the
original hardware DR6 contents in args->err. They want to turn off the
bits corresponding to events they take care of, leaving the remaining
bits intact. When the notifier chain is finished, any bits still left
in args->err have to be acted on by do_debug, by or'ing them into vdr6.

The problem is that, owing to the way the code is structured, this
can't be done. args->err is local to notify_die, so any changes made
to its value are not available in do_debug.

kprobes stays as it, returns NOTIFY_STOP iff it's swallowing the step.
do_debug stays mostly the same, replace:

tsk->thread.debugreg6 = condition;

with:

tsk->thread.vdr6 &= DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3;
tsk->thread.vdr6 |= condition & ~(DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3);

No, this can't be right. Or if it is, it's just by coincidence. What
we really want to do is:

tsk->thread.vdr6 |= args->err;

after notify_die() returns. Unfortunately this is impossible unless we
change things around. For example, instead of passing condition as an
argument to notify_die(), we could pass (long) &condition and change
the notifier routines to use (* (unsigned *) (args->err)) instead of
args->err.

kprobes stays as it, returns NOTIFY_STOP iff it's swallowing the step.

Oops, I think this breaks if there was also a ptrace db[0-3] hit in the
same exception. In that case, kprobes would need to not return NOTIFY_STOP
when it otherwise would, if thread.vdr6 has low bits set.

What should happen is kprobes returns NOTIFY_STOP if there are no
unreserved bits still set in args->err -- or (* (unsigned *)
(args->err)) -- when it is ready to return.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



Relevant Pages

  • Re: [RFC Patch 3/9] Modifying generic debug exception to use virtual debug registers
    ... generated for the exception. ... I don't think kprobes should "take care of" DR_STEP. ... IIRC there can be one do_debug trap that's for both a breakpoint register ... hit and a single-step, with DR_STEP plus DR_TRAPn both set at once. ...
    (Linux-Kernel)
  • Re: [RFC Patch 3/9] Modifying generic debug exception to use virtual debug registers
    ... I think this breaks if there was also a ptrace dbhit in the ... same exception. ... kprobes would need to not return NOTIFY_STOP ...
    (Linux-Kernel)
  • Problem with installing KB832880
    ... An exception was hit while trying to log a message. ... PreRequisite ... Die Installation des KB832880 wurde nicht abgeschlossen. ...
    (microsoft.public.windows.server.sbs)
  • Re: perf & Try Catch
    ... Throwing the exception is definitely of much more concern and where you ... should be concerned -- but you can wrap away - no hit there whatsoever. ... > try-catch instead of using a try-catch inside the loop. ... There is also a> small perf hit in the catch block when the exception is caught because the> runtime must examine each catch handler to determine if it is suitable to ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: perf & Try Catch
    ... execution time is increased by 39 percent. ... I can see why there'd be a onetime perf hit due to the extra ... The cost of the exception itself only occurs when it is ...
    (microsoft.public.dotnet.languages.csharp)