Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142742886
D22195.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D22195.diff
View Options
Index: head/sys/arm64/arm64/debug_monitor.c
===================================================================
--- head/sys/arm64/arm64/debug_monitor.c
+++ head/sys/arm64/arm64/debug_monitor.c
@@ -36,6 +36,7 @@
#include <sys/types.h>
#include <sys/kdb.h>
#include <sys/pcpu.h>
+#include <sys/proc.h>
#include <sys/systm.h>
#include <machine/armreg.h>
@@ -59,6 +60,10 @@
.dbg_flags = DBGMON_KERNEL
};
+/* Called from the exception handlers */
+void dbg_monitor_enter(struct thread *);
+void dbg_monitor_exit(struct thread *, struct trapframe *);
+
/* Watchpoints/breakpoints control register bitfields */
#define DBG_WATCH_CTRL_LEN_1 (0x1 << 5)
#define DBG_WATCH_CTRL_LEN_2 (0x3 << 5)
@@ -496,4 +501,58 @@
}
dbg_enable();
+}
+
+void
+dbg_monitor_enter(struct thread *thread)
+{
+ int i;
+
+ if ((kernel_monitor.dbg_flags & DBGMON_ENABLED) != 0) {
+ /* Install the kernel version of the registers */
+ dbg_register_sync(&kernel_monitor);
+ } else if ((thread->td_pcb->pcb_dbg_regs.dbg_flags & DBGMON_ENABLED) != 0) {
+ /* Disable the user breakpoints until we return to userspace */
+ for (i = 0; i < dbg_watchpoint_num; i++) {
+ dbg_wb_write_reg(DBG_REG_BASE_WCR, i, 0);
+ dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0);
+ }
+
+ for (i = 0; i < dbg_breakpoint_num; ++i) {
+ dbg_wb_write_reg(DBG_REG_BASE_BCR, i, 0);
+ dbg_wb_write_reg(DBG_REG_BASE_BVR, i, 0);
+ }
+ WRITE_SPECIALREG(mdscr_el1,
+ READ_SPECIALREG(mdscr_el1) &
+ ~(DBG_MDSCR_MDE | DBG_MDSCR_KDE));
+ isb();
+ }
+}
+
+void
+dbg_monitor_exit(struct thread *thread, struct trapframe *frame)
+{
+ int i;
+
+ frame->tf_spsr |= PSR_D;
+ if ((thread->td_pcb->pcb_dbg_regs.dbg_flags & DBGMON_ENABLED) != 0) {
+ /* Install the kernel version of the registers */
+ dbg_register_sync(&thread->td_pcb->pcb_dbg_regs);
+ frame->tf_spsr &= ~PSR_D;
+ } else if ((kernel_monitor.dbg_flags & DBGMON_ENABLED) != 0) {
+ /* Disable the user breakpoints until we return to userspace */
+ for (i = 0; i < dbg_watchpoint_num; i++) {
+ dbg_wb_write_reg(DBG_REG_BASE_WCR, i, 0);
+ dbg_wb_write_reg(DBG_REG_BASE_WVR, i, 0);
+ }
+
+ for (i = 0; i < dbg_breakpoint_num; ++i) {
+ dbg_wb_write_reg(DBG_REG_BASE_BCR, i, 0);
+ dbg_wb_write_reg(DBG_REG_BASE_BVR, i, 0);
+ }
+ WRITE_SPECIALREG(mdscr_el1,
+ READ_SPECIALREG(mdscr_el1) &
+ ~(DBG_MDSCR_MDE | DBG_MDSCR_KDE));
+ isb();
+ }
}
Index: head/sys/arm64/arm64/exception.S
===================================================================
--- head/sys/arm64/arm64/exception.S
+++ head/sys/arm64/arm64/exception.S
@@ -73,6 +73,9 @@
mov w0, #1
blr x1
1:
+
+ ldr x0, [x18, #(PC_CURTHREAD)]
+ bl dbg_monitor_enter
.endif
msr daifclr, #8 /* Enable the debug exception */
.endm
@@ -87,6 +90,10 @@
msr daifset, #10
.endif
.if \el == 0
+ ldr x0, [x18, #PC_CURTHREAD]
+ mov x1, sp
+ bl dbg_monitor_exit
+
/* Remove the SSBD (CVE-2018-3639) workaround if needed */
ldr x1, [x18, #PC_SSBD]
cbz x1, 1f
Index: head/sys/arm64/arm64/identcpu.c
===================================================================
--- head/sys/arm64/arm64/identcpu.c
+++ head/sys/arm64/arm64/identcpu.c
@@ -320,7 +320,7 @@
MRS_FIELD(ID_AA64DFR0, CTX_CMPs, false, MRS_EXACT,
id_aa64dfr0_ctx_cmps),
MRS_FIELD(ID_AA64DFR0, WRPs, false, MRS_EXACT, id_aa64dfr0_wrps),
- MRS_FIELD(ID_AA64DFR0, BRPs, false, MRS_EXACT, id_aa64dfr0_brps),
+ MRS_FIELD(ID_AA64DFR0, BRPs, false, MRS_LOWER, id_aa64dfr0_brps),
MRS_FIELD(ID_AA64DFR0, PMUVer, false, MRS_EXACT, id_aa64dfr0_pmuver),
MRS_FIELD(ID_AA64DFR0, TraceVer, false, MRS_EXACT,
id_aa64dfr0_tracever),
Index: head/sys/arm64/arm64/machdep.c
===================================================================
--- head/sys/arm64/arm64/machdep.c
+++ head/sys/arm64/arm64/machdep.c
@@ -281,17 +281,60 @@
int
fill_dbregs(struct thread *td, struct dbreg *regs)
{
+ struct debug_monitor_state *monitor;
+ int count, i;
+ uint8_t debug_ver, nbkpts;
- printf("ARM64TODO: fill_dbregs");
- return (EDOOFUS);
+ memset(regs, 0, sizeof(*regs));
+
+ extract_user_id_field(ID_AA64DFR0_EL1, ID_AA64DFR0_DebugVer_SHIFT,
+ &debug_ver);
+ extract_user_id_field(ID_AA64DFR0_EL1, ID_AA64DFR0_BRPs_SHIFT,
+ &nbkpts);
+
+ /*
+ * The BRPs field contains the number of breakpoints - 1. Armv8-A
+ * allows the hardware to provide 2-16 breakpoints so this won't
+ * overflow an 8 bit value.
+ */
+ count = nbkpts + 1;
+
+ regs->db_info = debug_ver;
+ regs->db_info <<= 8;
+ regs->db_info |= count;
+
+ monitor = &td->td_pcb->pcb_dbg_regs;
+ if ((monitor->dbg_flags & DBGMON_ENABLED) != 0) {
+ for (i = 0; i < count; i++) {
+ regs->db_regs[i].dbr_addr = monitor->dbg_bvr[i];
+ regs->db_regs[i].dbr_ctrl = monitor->dbg_bcr[i];
+ }
+ }
+
+ return (0);
}
int
set_dbregs(struct thread *td, struct dbreg *regs)
{
+ struct debug_monitor_state *monitor;
+ int count;
+ int i;
- printf("ARM64TODO: set_dbregs");
- return (EDOOFUS);
+ monitor = &td->td_pcb->pcb_dbg_regs;
+ count = 0;
+ monitor->dbg_enable_count = 0;
+ for (i = 0; i < DBG_BRP_MAX; i++) {
+ /* TODO: Check these values */
+ monitor->dbg_bvr[i] = regs->db_regs[i].dbr_addr;
+ monitor->dbg_bcr[i] = regs->db_regs[i].dbr_ctrl;
+ if ((monitor->dbg_bcr[i] & 1) != 0)
+ monitor->dbg_enable_count++;
+ }
+ if (monitor->dbg_enable_count > 0)
+ monitor->dbg_flags |= DBGMON_ENABLED;
+
+ return (0);
}
#ifdef COMPAT_FREEBSD32
Index: head/sys/arm64/arm64/trap.c
===================================================================
--- head/sys/arm64/arm64/trap.c
+++ head/sys/arm64/arm64/trap.c
@@ -482,6 +482,7 @@
call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_elr);
userret(td, frame);
break;
+ case EXCP_BRKPT_EL0:
case EXCP_BRK:
call_trapsignal(td, SIGTRAP, TRAP_BRKPT, (void *)frame->tf_elr);
userret(td, frame);
Index: head/sys/arm64/include/armreg.h
===================================================================
--- head/sys/arm64/include/armreg.h
+++ head/sys/arm64/include/armreg.h
@@ -163,6 +163,7 @@
#define EXCP_SP_ALIGN 0x26 /* SP slignment fault */
#define EXCP_TRAP_FP 0x2c /* Trapped FP exception */
#define EXCP_SERROR 0x2f /* SError interrupt */
+#define EXCP_BRKPT_EL0 0x30 /* Hardware breakpoint, from same EL */
#define EXCP_SOFTSTP_EL0 0x32 /* Software Step, from lower EL */
#define EXCP_SOFTSTP_EL1 0x33 /* Software Step, from same EL */
#define EXCP_WATCHPT_EL1 0x35 /* Watchpoint, from same EL */
Index: head/sys/arm64/include/pcb.h
===================================================================
--- head/sys/arm64/include/pcb.h
+++ head/sys/arm64/include/pcb.h
@@ -31,6 +31,7 @@
#ifndef LOCORE
+#include <machine/debug_monitor.h>
#include <machine/vfp.h>
struct trapframe;
@@ -66,6 +67,8 @@
* Place last to simplify the asm to access the rest if the struct.
*/
struct vfpstate pcb_fpustate;
+
+ struct debug_monitor_state pcb_dbg_regs;
};
#ifdef _KERNEL
Index: head/sys/arm64/include/reg.h
===================================================================
--- head/sys/arm64/include/reg.h
+++ head/sys/arm64/include/reg.h
@@ -60,7 +60,14 @@
};
struct dbreg {
- int dummy;
+ uint32_t db_info;
+ uint32_t db_pad;
+
+ struct {
+ uint64_t dbr_addr;
+ uint32_t dbr_ctrl;
+ uint32_t dbr_pad;
+ } db_regs[16];
};
struct dbreg32 {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 23, 11:55 PM (7 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27891866
Default Alt Text
D22195.diff (7 KB)
Attached To
Mode
D22195: Add support for setting hardware breakpoints from ptrace on arm64
Attached
Detach File
Event Timeline
Log In to Comment