Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F170668837
D15189.id42682.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D15189.id42682.diff
View Options
Index: sys/amd64/amd64/machdep.c
===================================================================
--- sys/amd64/amd64/machdep.c
+++ sys/amd64/amd64/machdep.c
@@ -2485,14 +2485,23 @@
* breakpoint was in user space. Return 0, otherwise.
*/
int
-user_dbreg_trap(void)
+user_dbreg_trap(register_t dr6)
{
- u_int64_t dr7, dr6; /* debug registers dr6 and dr7 */
+ u_int64_t dr7;
u_int64_t bp; /* breakpoint bits extracted from dr6 */
int nbp; /* number of breakpoints that triggered */
caddr_t addr[4]; /* breakpoint addresses */
int i;
-
+
+ bp = dr6 & DBREG_DR6_BMASK;
+ if (bp == 0) {
+ /*
+ * None of the breakpoint bits are set meaning this
+ * trap was not caused by any of the debug registers
+ */
+ return 0;
+ }
+
dr7 = rdr7();
if ((dr7 & 0x000000ff) == 0) {
/*
@@ -2504,16 +2513,6 @@
}
nbp = 0;
- dr6 = rdr6();
- bp = dr6 & 0x0000000f;
-
- if (!bp) {
- /*
- * None of the breakpoint bits are set meaning this
- * trap was not caused by any of the debug registers
- */
- return 0;
- }
/*
* at least one of the breakpoints were hit, check to see
Index: sys/amd64/amd64/trap.c
===================================================================
--- sys/amd64/amd64/trap.c
+++ sys/amd64/amd64/trap.c
@@ -126,7 +126,7 @@
"", /* 7 unused */
"", /* 8 unused */
"general protection fault", /* 9 T_PROTFLT */
- "trace trap", /* 10 T_TRCTRAP */
+ "debug exception", /* 10 T_TRCTRAP */
"", /* 11 unused */
"page fault", /* 12 T_PAGEFLT */
"", /* 13 unused */
@@ -173,10 +173,7 @@
ksiginfo_t ksi;
struct thread *td;
struct proc *p;
- register_t addr;
-#ifdef KDB
- register_t dr6;
-#endif
+ register_t addr, dr6;
int signo, ucode;
u_int type;
@@ -185,6 +182,7 @@
signo = 0;
ucode = 0;
addr = 0;
+ dr6 = 0;
VM_CNT_INC(v_trap);
type = frame->tf_trapno;
@@ -272,18 +270,23 @@
break;
case T_BPTFLT: /* bpt instruction fault */
- case T_TRCTRAP: /* trace trap */
enable_intr();
#ifdef KDTRACE_HOOKS
- if (type == T_BPTFLT) {
- if (dtrace_pid_probe_ptr != NULL &&
- dtrace_pid_probe_ptr(frame) == 0)
- return;
- }
+ if (dtrace_pid_probe_ptr != NULL &&
+ dtrace_pid_probe_ptr(frame) == 0)
+ return;
#endif
- frame->tf_rflags &= ~PSL_T;
signo = SIGTRAP;
- ucode = (type == T_TRCTRAP ? TRAP_TRACE : TRAP_BRKPT);
+ ucode = TRAP_BRKPT;
+ break;
+
+ case T_TRCTRAP: /* debug exception */
+ enable_intr();
+ signo = SIGTRAP;
+ ucode = TRAP_TRACE;
+ dr6 = rdr6();
+ if (dr6 & DBREG_DR6_BS)
+ frame->tf_rflags &= ~PSL_T;
break;
case T_ARITHTRAP: /* arithmetic trap */
@@ -521,9 +524,13 @@
}
break;
- case T_TRCTRAP: /* trace trap */
+ case T_TRCTRAP: /* debug exception */
+ /* Clear any pending debug events. */
+ dr6 = rdr6();
+ load_dr6(0);
+
/*
- * Ignore debug register trace traps due to
+ * Ignore debug register exceptions due to
* accesses in the user's address space, which
* can happen under several conditions such as
* if a user sets a watchpoint on a buffer and
@@ -532,14 +539,8 @@
* in kernel space because that is useful when
* debugging the kernel.
*/
- if (user_dbreg_trap()) {
- /*
- * Reset breakpoint bits because the
- * processor doesn't
- */
- load_dr6(rdr6() & ~0xf);
+ if (user_dbreg_trap(dr6))
return;
- }
/*
* Malicious user code can configure a debug
@@ -595,9 +596,6 @@
* Otherwise, debugger traps "can't happen".
*/
#ifdef KDB
- /* XXX %dr6 is not quite reentrant. */
- dr6 = rdr6();
- load_dr6(dr6 & ~0x4000);
if (kdb_trap(type, dr6, frame))
return;
#endif
@@ -640,6 +638,13 @@
}
KASSERT((read_rflags() & PSL_I) != 0, ("interrupts disabled"));
trapsignal(td, &ksi);
+
+ /*
+ * Clear any pending debug exceptions after allowing a
+ * debugger to read DR6 while stopped in trapsignal().
+ */
+ if (type == T_TRCTRAP)
+ load_dr6(0);
userret:
userret(td, frame);
KASSERT(PCB_USER_FPU(td->td_pcb),
Index: sys/amd64/include/db_machdep.h
===================================================================
--- sys/amd64/include/db_machdep.h
+++ sys/amd64/include/db_machdep.h
@@ -30,6 +30,7 @@
#define _MACHINE_DB_MACHDEP_H_
#include <machine/frame.h>
+#include <machine/reg.h>
#include <machine/trap.h>
typedef vm_offset_t db_addr_t; /* address - unsigned */
@@ -64,7 +65,8 @@
* unknown addresses and doesn't turn them off while it is running.
*/
#define IS_BREAKPOINT_TRAP(type, code) ((type) == T_BPTFLT)
-#define IS_SSTEP_TRAP(type, code) ((type) == T_TRCTRAP && (code) & 0x4000)
+#define IS_SSTEP_TRAP(type, code) \
+ ((type) == T_TRCTRAP && (code) & DBREG_DR6_BS)
#define IS_WATCHPOINT_TRAP(type, code) 0
#define I_CALL 0xe8
Index: sys/amd64/vmm/amd/svm.c
===================================================================
--- sys/amd64/vmm/amd/svm.c
+++ sys/amd64/vmm/amd/svm.c
@@ -42,6 +42,7 @@
#include <machine/cpufunc.h>
#include <machine/psl.h>
#include <machine/md_var.h>
+#include <machine/reg.h>
#include <machine/specialreg.h>
#include <machine/smp.h>
#include <machine/vmm.h>
@@ -507,8 +508,8 @@
PAT_VALUE(7, PAT_UNCACHEABLE);
/* Set up DR6/7 to power-on state */
- state->dr6 = 0xffff0ff0;
- state->dr7 = 0x400;
+ state->dr6 = DBREG_DR6_RESERVED1;
+ state->dr7 = DBREG_DR7_RESERVED1;
}
/*
Index: sys/amd64/vmm/intel/vmx.c
===================================================================
--- sys/amd64/vmm/intel/vmx.c
+++ sys/amd64/vmm/intel/vmx.c
@@ -46,6 +46,7 @@
#include <machine/psl.h>
#include <machine/cpufunc.h>
#include <machine/md_var.h>
+#include <machine/reg.h>
#include <machine/segments.h>
#include <machine/smp.h>
#include <machine/specialreg.h>
@@ -994,8 +995,8 @@
exc_bitmap = 1 << IDT_MC;
error += vmwrite(VMCS_EXCEPTION_BITMAP, exc_bitmap);
- vmx->ctx[i].guest_dr6 = 0xffff0ff0;
- error += vmwrite(VMCS_GUEST_DR7, 0x400);
+ vmx->ctx[i].guest_dr6 = DBREG_DR6_RESERVED1;
+ error += vmwrite(VMCS_GUEST_DR7, DBREG_DR7_RESERVED1);
if (virtual_interrupt_delivery) {
error += vmwrite(VMCS_APIC_ACCESS, APIC_ACCESS_ADDRESS);
Index: sys/i386/i386/machdep.c
===================================================================
--- sys/i386/i386/machdep.c
+++ sys/i386/i386/machdep.c
@@ -3151,14 +3151,23 @@
* breakpoint was in user space. Return 0, otherwise.
*/
int
-user_dbreg_trap(void)
+user_dbreg_trap(register_t dr6)
{
- u_int32_t dr7, dr6; /* debug registers dr6 and dr7 */
+ u_int32_t dr7;
u_int32_t bp; /* breakpoint bits extracted from dr6 */
int nbp; /* number of breakpoints that triggered */
caddr_t addr[4]; /* breakpoint addresses */
int i;
-
+
+ bp = dr6 & DBREG_DR6_BMASK;
+ if (bp == 0) {
+ /*
+ * None of the breakpoint bits are set meaning this
+ * trap was not caused by any of the debug registers
+ */
+ return 0;
+ }
+
dr7 = rdr7();
if ((dr7 & 0x000000ff) == 0) {
/*
@@ -3170,16 +3179,6 @@
}
nbp = 0;
- dr6 = rdr6();
- bp = dr6 & 0x0000000f;
-
- if (!bp) {
- /*
- * None of the breakpoint bits are set meaning this
- * trap was not caused by any of the debug registers
- */
- return 0;
- }
/*
* at least one of the breakpoints were hit, check to see
Index: sys/i386/i386/trap.c
===================================================================
--- sys/i386/i386/trap.c
+++ sys/i386/i386/trap.c
@@ -132,7 +132,7 @@
[T_BPTFLT] = { .ei = false, .msg = "breakpoint instruction fault" },
[T_ARITHTRAP] = { .ei = true, .msg = "arithmetic trap" },
[T_PROTFLT] = { .ei = true, .msg = "general protection fault" },
- [T_TRCTRAP] = { .ei = false, .msg = "trace trap" },
+ [T_TRCTRAP] = { .ei = false, .msg = "debug exception" },
[T_PAGEFLT] = { .ei = true, .msg = "page fault" },
[T_ALIGNFLT] = { .ei = true, .msg = "alignment fault" },
[T_DIVIDE] = { .ei = true, .msg = "integer divide fault" },
@@ -199,12 +199,9 @@
ksiginfo_t ksi;
struct thread *td;
struct proc *p;
-#ifdef KDB
- register_t dr6;
-#endif
int signo, ucode;
u_int type;
- register_t addr;
+ register_t addr, dr6;
vm_offset_t eva;
#ifdef POWERFAIL_NMI
static int lastalert = 0;
@@ -215,6 +212,7 @@
signo = 0;
ucode = 0;
addr = 0;
+ dr6 = 0;
VM_CNT_INC(v_trap);
type = frame->tf_trapno;
@@ -323,19 +321,24 @@
break;
case T_BPTFLT: /* bpt instruction fault */
- case T_TRCTRAP: /* trace trap */
enable_intr();
#ifdef KDTRACE_HOOKS
- if (type == T_BPTFLT) {
- if (dtrace_pid_probe_ptr != NULL &&
- dtrace_pid_probe_ptr(frame) == 0)
- return;
- }
+ if (dtrace_pid_probe_ptr != NULL &&
+ dtrace_pid_probe_ptr(frame) == 0)
+ return;
#endif
+ signo = SIGTRAP;
+ ucode = TRAP_BRKPT;
+ break;
+
+ case T_TRCTRAP: /* debug exception */
+ enable_intr();
user_trctrap_out:
- frame->tf_eflags &= ~PSL_T;
signo = SIGTRAP;
- ucode = (type == T_TRCTRAP ? TRAP_TRACE : TRAP_BRKPT);
+ ucode = TRAP_TRACE;
+ dr6 = rdr6();
+ if (dr6 & DBREG_DR6_BS)
+ frame->tf_rflags &= ~PSL_T;
break;
case T_ARITHTRAP: /* arithmetic trap */
@@ -643,10 +646,14 @@
}
break;
- case T_TRCTRAP: /* trace trap */
+ case T_TRCTRAP: /* debug exception */
kernel_trctrap:
+ /* Clear any pending debug events. */
+ dr6 = rdr6();
+ load_dr6(0);
+
/*
- * Ignore debug register trace traps due to
+ * Ignore debug register exceptions due to
* accesses in the user's address space, which
* can happen under several conditions such as
* if a user sets a watchpoint on a buffer and
@@ -655,15 +662,9 @@
* in kernel space because that is useful when
* debugging the kernel.
*/
- if (user_dbreg_trap() &&
- !(curpcb->pcb_flags & PCB_VM86CALL)) {
- /*
- * Reset breakpoint bits because the
- * processor doesn't
- */
- load_dr6(rdr6() & ~0xf);
+ if (user_dbreg_trap(dr6) &&
+ !(curpcb->pcb_flags & PCB_VM86CALL))
return;
- }
/*
* Malicious user code can configure a debug
@@ -703,9 +704,6 @@
* Otherwise, debugger traps "can't happen".
*/
#ifdef KDB
- /* XXX %dr6 is not quite reentrant. */
- dr6 = rdr6();
- load_dr6(dr6 & ~0x4000);
if (kdb_trap(type, dr6, frame))
return;
#endif
@@ -759,6 +757,12 @@
KASSERT((read_eflags() & PSL_I) != 0, ("interrupts disabled"));
trapsignal(td, &ksi);
+ /*
+ * Clear any pending debug exceptions after allowing a
+ * debugger to read DR6 while stopped in trapsignal().
+ */
+ if (type == T_TRCTRAP)
+ load_dr6(0);
user:
userret(td, frame);
KASSERT(PCB_USER_FPU(td->td_pcb),
Index: sys/i386/include/db_machdep.h
===================================================================
--- sys/i386/include/db_machdep.h
+++ sys/i386/include/db_machdep.h
@@ -30,6 +30,7 @@
#define _MACHINE_DB_MACHDEP_H_
#include <machine/frame.h>
+#include <machine/reg.h>
#include <machine/trap.h>
typedef vm_offset_t db_addr_t; /* address - unsigned */
@@ -67,7 +68,8 @@
* unknown addresses and doesn't turn them off while it is running.
*/
#define IS_BREAKPOINT_TRAP(type, code) ((type) == T_BPTFLT)
-#define IS_SSTEP_TRAP(type, code) ((type) == T_TRCTRAP && (code) & 0x4000)
+#define IS_SSTEP_TRAP(type, code) \
+ ((type) == T_TRCTRAP && (code) & DBREG_DR6_BS)
#define IS_WATCHPOINT_TRAP(type, code) 0
#define I_CALL 0xe8
Index: sys/x86/include/reg.h
===================================================================
--- sys/x86/include/reg.h
+++ sys/x86/include/reg.h
@@ -206,6 +206,14 @@
/* Index 8-15: reserved */
};
+#define DBREG_DR6_RESERVED1 0xffff0ff0
+#define DBREG_DR6_BMASK 0x000f
+#define DBREG_DR6_B(i) (1 << (i))
+#define DBREG_DR6_BD 0x2000
+#define DBREG_DR6_BS 0x4000
+#define DBREG_DR6_BT 0x8000
+
+#define DBREG_DR7_RESERVED1 0x0400
#define DBREG_DR7_LOCAL_ENABLE 0x01
#define DBREG_DR7_GLOBAL_ENABLE 0x02
#define DBREG_DR7_LEN_1 0x00 /* 1 byte length */
@@ -236,6 +244,8 @@
#undef __dbreg64
#ifdef _KERNEL
+struct thread;
+
/*
* XXX these interfaces are MI, so they should be declared in a MI place.
*/
Index: sys/x86/include/x86_var.h
===================================================================
--- sys/x86/include/x86_var.h
+++ sys/x86/include/x86_var.h
@@ -143,7 +143,7 @@
void pagecopy(void *from, void *to);
void printcpuinfo(void);
int pti_get_default(void);
-int user_dbreg_trap(void);
+int user_dbreg_trap(register_t dr6);
int minidumpsys(struct dumperinfo *);
struct pcb *get_pcb_td(struct thread *td);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Sep 6, 10:32 PM (1 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38421791
Default Alt Text
D15189.id42682.diff (12 KB)
Attached To
Mode
D15189: Cleanups related to debug exceptions on x86.
Attached
Detach File
Event Timeline
Log In to Comment