[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20081017232430.9F48C1544CB@magilla.localdomain>
Date: Fri, 17 Oct 2008 16:24:30 -0700 (PDT)
From: Roland McGrath <roland@...hat.com>
To: Alan Stern <stern@...land.harvard.edu>
Cc: prasad@...ux.vnet.ibm.com,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
<akpm@...ux-foundation.org>, <mingo@...e.hu>,
<jason.wessel@...driver.com>, <avi@...ranet.com>,
<richardj_moore@...ibm.com>
Subject: Re: [RFC Patch 3/9] Modifying generic debug exception to use virtual
debug registers
> I seem to recall doing some experiments to find out which bits in DR6
> the CPU would set and which it would clear. According to the 386
> manual the processor never clears any of the bits, but this was changed
> in later models. And I seem to recall that the experiments showed that
> gdb would not clear the bits either; it relied on the CPU to clear
> them.
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.
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);
Thanks,
Roland
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists