Page MenuHomeFreeBSD

D29155.id85846.diff
No OneTemporary

D29155.id85846.diff

Index: sys/amd64/amd64/db_trace.c
===================================================================
--- sys/amd64/amd64/db_trace.c
+++ sys/amd64/amd64/db_trace.c
@@ -389,7 +389,8 @@
db_md_set_watchpoint(db_expr_t addr, db_expr_t size)
{
- return (dbreg_set_watchpoint((vm_offset_t)addr, (vm_size_t)size));
+ return (dbreg_set_watchpoint((vm_offset_t)addr, (vm_size_t)size,
+ DBREG_DR7_WRONLY));
}
int
Index: sys/amd64/include/kdb.h
===================================================================
--- sys/amd64/include/kdb.h
+++ sys/amd64/include/kdb.h
@@ -36,6 +36,9 @@
#define KDB_STOPPEDPCB(pc) &stoppcbs[pc->pc_cpuid]
+int kdb_cpu_set_watchpoint(vm_offset_t addr, vm_size_t size, int access);
+int kdb_cpu_clr_watchpoint(vm_offset_t addr, vm_size_t size);
+
static __inline void
kdb_cpu_clear_singlestep(void)
{
Index: sys/arm/arm/debug_monitor.c
===================================================================
--- sys/arm/arm/debug_monitor.c
+++ sys/arm/arm/debug_monitor.c
@@ -326,6 +326,35 @@
}
}
+int
+kdb_cpu_set_watchpoint(vm_offset_t addr, size_t size, int access)
+{
+ enum dbg_access_t dbg_access;
+
+ switch (access) {
+ case KDB_DBG_ACCESS_R:
+ dbg_access = HW_WATCHPOINT_R;
+ break;
+ case KDB_DBG_ACCESS_W:
+ dbg_access = HW_WATCHPOINT_W;
+ break;
+ case KDB_DBG_ACCESS_RW:
+ dbg_access = HW_WATCHPOINT_RW;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ return (dbg_setup_watchpoint(addr, size, (enum dbg_access_t)access));
+}
+
+int
+kdb_cpu_clr_watchpoint(vm_offset_t addr, size_t size)
+{
+
+ return (dbg_remove_watchpoint(addr, size));
+}
+
int
dbg_setup_watchpoint(db_expr_t addr, db_expr_t size, enum dbg_access_t access)
{
@@ -624,7 +653,7 @@
if (i == ~0U) {
db_printf("Can not find slot for %s, max %d slots supported\n",
typestr, dbg_watchpoint_num);
- return (ENXIO);
+ return (EBUSY);
}
}
@@ -645,7 +674,8 @@
cr_size = DBG_WB_CTRL_LEN_8;
break;
default:
- db_printf("Unsupported address size for %s\n", typestr);
+ db_printf("Unsupported address size for %s: %zu\n", typestr,
+ conf->size);
return (EINVAL);
}
@@ -667,7 +697,8 @@
cr_access = DBG_WB_CTRL_LOAD | DBG_WB_CTRL_STORE;
break;
default:
- db_printf("Unsupported exception level for %s\n", typestr);
+ db_printf("Unsupported access type for %s: %d\n",
+ typestr, conf->access);
return (EINVAL);
}
Index: sys/arm/include/kdb.h
===================================================================
--- sys/arm/include/kdb.h
+++ sys/arm/include/kdb.h
@@ -41,6 +41,8 @@
extern void kdb_cpu_clear_singlestep(void);
extern void kdb_cpu_set_singlestep(void);
boolean_t kdb_cpu_pc_is_singlestep(db_addr_t);
+int kdb_cpu_set_watchpoint(vm_offset_t addr, size_t size, int access);
+int kdb_cpu_clr_watchpoint(vm_offset_t addr, size_t size);
static __inline void
kdb_cpu_sync_icache(unsigned char *addr, size_t size)
Index: sys/arm64/arm64/debug_monitor.c
===================================================================
--- sys/arm64/arm64/debug_monitor.c
+++ sys/arm64/arm64/debug_monitor.c
@@ -226,6 +226,35 @@
}
}
+int
+kdb_cpu_set_watchpoint(vm_offset_t addr, vm_size_t size, int access)
+{
+ enum dbg_access_t dbg_access;
+
+ switch (access) {
+ case KDB_DBG_ACCESS_R:
+ dbg_access = HW_BREAKPOINT_R;
+ break;
+ case KDB_DBG_ACCESS_W:
+ dbg_access = HW_BREAKPOINT_W;
+ break;
+ case KDB_DBG_ACCESS_RW:
+ dbg_access = HW_BREAKPOINT_RW;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ return (dbg_setup_watchpoint(NULL, addr, size, dbg_access));
+}
+
+int
+kdb_cpu_clr_watchpoint(vm_offset_t addr, vm_size_t size)
+{
+
+ return (dbg_remove_watchpoint(NULL, addr, size));
+}
+
static const char *
dbg_watchtype_str(uint32_t type)
{
@@ -362,7 +391,7 @@
if (i == -1) {
printf("Can not find slot for watchpoint, max %d"
" watchpoints supported\n", dbg_watchpoint_num);
- return (i);
+ return (EBUSY);
}
switch(size) {
@@ -379,8 +408,8 @@
wcr_size = DBG_WATCH_CTRL_LEN_8;
break;
default:
- printf("Unsupported address size for watchpoint\n");
- return (-1);
+ printf("Unsupported address size for watchpoint: %zu\n", size);
+ return (EINVAL);
}
if ((monitor->dbg_flags & DBGMON_KERNEL) == 0)
@@ -402,8 +431,8 @@
wcr_access = DBG_WATCH_CTRL_LOAD | DBG_WATCH_CTRL_STORE;
break;
default:
- printf("Unsupported exception level for watchpoint\n");
- return (-1);
+ printf("Unsupported access type for watchpoint: %d\n", access);
+ return (EINVAL);
}
monitor->dbg_wvr[i] = addr;
@@ -427,7 +456,7 @@
i = dbg_find_slot(monitor, DBG_TYPE_WATCHPOINT, addr);
if (i == -1) {
printf("Can not find watchpoint for address 0%lx\n", addr);
- return (i);
+ return (EINVAL);
}
monitor->dbg_wvr[i] = 0;
Index: sys/arm64/include/kdb.h
===================================================================
--- sys/arm64/include/kdb.h
+++ sys/arm64/include/kdb.h
@@ -39,6 +39,8 @@
void kdb_cpu_clear_singlestep(void);
void kdb_cpu_set_singlestep(void);
+int kdb_cpu_set_watchpoint(vm_offset_t addr, size_t size, int access);
+int kdb_cpu_clr_watchpoint(vm_offset_t addr, size_t size);
static __inline void
kdb_cpu_sync_icache(unsigned char *addr, size_t size)
Index: sys/i386/include/kdb.h
===================================================================
--- sys/i386/include/kdb.h
+++ sys/i386/include/kdb.h
@@ -36,6 +36,9 @@
#define KDB_STOPPEDPCB(pc) &stoppcbs[pc->pc_cpuid]
+int kdb_cpu_set_watchpoint(vm_offset_t addr, vm_size_t size, int access);
+int kdb_cpu_clr_watchpoint(vm_offset_t addr, vm_size_t size);
+
static __inline void
kdb_cpu_clear_singlestep(void)
{
Index: sys/mips/include/kdb.h
===================================================================
--- sys/mips/include/kdb.h
+++ sys/mips/include/kdb.h
@@ -55,4 +55,19 @@
kdb_cpu_sync_icache(unsigned char *addr, size_t size)
{
}
+
+static __inline int
+kdb_cpu_set_watchpoint(vm_offset_t addr, vm_size_t size, int access)
+{
+
+ return (ENXIO);
+}
+
+static __inline int
+kdb_cpu_clr_watchpoint(vm_offset_t addr, vm_size_t size)
+{
+
+ return (0);
+}
+
#endif /* _MACHINE_KDB_H_ */
Index: sys/powerpc/include/kdb.h
===================================================================
--- sys/powerpc/include/kdb.h
+++ sys/powerpc/include/kdb.h
@@ -54,4 +54,18 @@
{
}
+static __inline int
+kdb_cpu_set_watchpoint(vm_offset_t addr, vm_size_t size, int access)
+{
+
+ return (ENXIO);
+}
+
+static __inline int
+kdb_cpu_clr_watchpoint(vm_offset_t addr, vm_size_t size)
+{
+
+ return (0);
+}
+
#endif /* _MACHINE_KDB_H_ */
Index: sys/riscv/include/kdb.h
===================================================================
--- sys/riscv/include/kdb.h
+++ sys/riscv/include/kdb.h
@@ -59,4 +59,18 @@
{
}
+static __inline int
+kdb_cpu_set_watchpoint(vm_offset_t addr, vm_size_t size, int access)
+{
+
+ return (ENXIO);
+}
+
+static __inline int
+kdb_cpu_clr_watchpoint(vm_offset_t addr, vm_size_t size)
+{
+
+ return (0);
+}
+
#endif /* _MACHINE_KDB_H_ */
Index: sys/sys/kdb.h
===================================================================
--- sys/sys/kdb.h
+++ sys/sys/kdb.h
@@ -127,4 +127,10 @@
#define KDB_REQ_PANIC 2 /* User requested a panic */
#define KDB_REQ_REBOOT 3 /* User requested a clean reboot */
+/* Debug breakpoint/watchpoint access types */
+#define KDB_DBG_ACCESS_EXEC 0
+#define KDB_DBG_ACCESS_R 1
+#define KDB_DBG_ACCESS_W 2
+#define KDB_DBG_ACCESS_RW 3
+
#endif /* !_SYS_KDB_H_ */
Index: sys/x86/include/x86_var.h
===================================================================
--- sys/x86/include/x86_var.h
+++ sys/x86/include/x86_var.h
@@ -120,7 +120,7 @@
bool cpu_mwait_usable(void);
void cpu_probe_amdc1e(void);
void cpu_setregs(void);
-int dbreg_set_watchpoint(vm_offset_t addr, vm_size_t size);
+int dbreg_set_watchpoint(vm_offset_t addr, vm_size_t size, int access);
int dbreg_clr_watchpoint(vm_offset_t addr, vm_size_t size);
void dbreg_list_watchpoints(void);
bool disable_wp(void);
Index: sys/x86/x86/dbreg.c
===================================================================
--- sys/x86/x86/dbreg.c
+++ sys/x86/x86/dbreg.c
@@ -27,11 +27,13 @@
#include "opt_ddb.h"
#include <sys/types.h>
+#include <sys/kdb.h>
#include <sys/pcpu.h>
#include <sys/smp.h>
#include <sys/systm.h>
#include <machine/frame.h>
+#include <machine/kdb.h>
#include <machine/md_var.h>
#include <ddb/ddb.h>
@@ -127,7 +129,7 @@
}
int
-dbreg_set_watchpoint(vm_offset_t addr, vm_size_t size)
+dbreg_set_watchpoint(vm_offset_t addr, vm_size_t size, int access)
{
struct dbreg *d;
int avail, i, wsize;
@@ -140,6 +142,11 @@
d = &d_temp;
#endif
+ /* Validate the access type */
+ if (access != DBREG_DR7_EXEC && access != DBREG_DR7_WRONLY &&
+ access != DBREG_DR7_RDWR)
+ return (EINVAL);
+
fill_dbregs(NULL, d);
/*
@@ -153,7 +160,7 @@
}
if (avail * MAXWATCHSIZE < size)
- return (-1);
+ return (EBUSY);
for (i = 0; i < NDBREGS && size > 0; i++) {
if (!DBREG_DR7_ENABLED(d->dr[7], i)) {
@@ -164,7 +171,7 @@
wsize = 4;
else
wsize = size;
- dbreg_set_watchreg(i, addr, wsize, DBREG_DR7_WRONLY, d);
+ dbreg_set_watchreg(i, addr, wsize, access, d);
addr += wsize;
size -= wsize;
avail--;
@@ -265,3 +272,31 @@
}
}
#endif
+
+int
+kdb_cpu_set_watchpoint(vm_offset_t addr, vm_size_t size, int access)
+{
+
+ /* Convert the KDB access type */
+ switch (access) {
+ case KDB_DBG_ACCESS_W:
+ access = DBREG_DR7_WRONLY;
+ break;
+ case KDB_DBG_ACCESS_RW:
+ access = DBREG_DR7_RDWR;
+ break;
+ case KDB_DBG_ACCESS_R:
+ /* FALLTHROUGH: read-only not supported */
+ default:
+ return (EINVAL);
+ }
+
+ return (dbreg_set_watchpoint(addr, size, access));
+}
+
+int
+kdb_cpu_clr_watchpoint(vm_offset_t addr, vm_size_t size)
+{
+
+ return (dbreg_clr_watchpoint(addr, size));
+}

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 12, 9:41 PM (21 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15773067
Default Alt Text
D29155.id85846.diff (9 KB)

Event Timeline