aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64/amd64/machdep.c
diff options
context:
space:
mode:
authorBrian S. Dean <bsd@FreeBSD.org>2000-02-20 20:51:23 +0000
committerBrian S. Dean <bsd@FreeBSD.org>2000-02-20 20:51:23 +0000
commitde8050f9b844e288f17964759ff76c4166b63219 (patch)
tree832aec96b2aeaaab21defbd348161e37e3ae6ebd /sys/amd64/amd64/machdep.c
parent6ecfb1da4406ecda2cfa28b8ff4160e6a5e44bf4 (diff)
downloadsrc-de8050f9b844e288f17964759ff76c4166b63219.tar.gz
src-de8050f9b844e288f17964759ff76c4166b63219.zip
Don't forget to reset the hardware debug registers when a process that
was using them exits. Don't allow a user process to cause the kernel to take a TRCTRAP on a user space address. Reviewed by: jlemon, sef Approved by: jkh
Notes
Notes: svn path=/head/; revision=57362
Diffstat (limited to 'sys/amd64/amd64/machdep.c')
-rw-r--r--sys/amd64/amd64/machdep.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 397efdcdd463..1efc7e48f8e8 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -2239,6 +2239,76 @@ set_dbregs(p, dbregs)
return (0);
}
+/*
+ * Return > 0 if a hardware breakpoint has been hit, and the
+ * breakpoint was in user space. Return 0, otherwise.
+ */
+int
+user_dbreg_trap(void)
+{
+ u_int32_t dr7, dr6; /* debug registers dr6 and 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;
+
+ dr7 = rdr7();
+ if ((dr7 & 0x000000ff) == 0) {
+ /*
+ * all GE and LE bits in the dr7 register are zero,
+ * thus the trap couldn't have been caused by the
+ * hardware debug registers
+ */
+ return 0;
+ }
+
+ 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
+ * which ones and if any of them are user space addresses
+ */
+
+ if (bp & 0x01) {
+ addr[nbp++] = (caddr_t)rdr0();
+ }
+ if (bp & 0x02) {
+ addr[nbp++] = (caddr_t)rdr1();
+ }
+ if (bp & 0x04) {
+ addr[nbp++] = (caddr_t)rdr2();
+ }
+ if (bp & 0x08) {
+ addr[nbp++] = (caddr_t)rdr3();
+ }
+
+ for (i=0; i<nbp; i++) {
+ if (addr[i] <
+ (caddr_t)VM_MAXUSER_ADDRESS) {
+ /*
+ * addr[i] is in user space
+ */
+ return nbp;
+ }
+ }
+
+ /*
+ * None of the breakpoints are in user space.
+ */
+ return 0;
+}
+
+
#ifndef DDB
void
Debugger(const char *msg)