aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Horne <mhorne@FreeBSD.org>2021-02-05 21:46:48 +0000
committerMitchell Horne <mhorne@FreeBSD.org>2021-02-17 16:05:00 +0000
commitbd012c71592323d957b409bb5e0cf7940729650e (patch)
tree65829cb67a1b9e2401ec726650e196f557fc7259
parentde2b9422807586d376ec7ffa7b660cd492464bdf (diff)
downloadsrc-bd012c71592323d957b409bb5e0cf7940729650e.tar.gz
src-bd012c71592323d957b409bb5e0cf7940729650e.zip
arm64: handle watchpoint exceptions from EL0
This is a prerequisite to allowing the use of hardware watchpoints for userspace debuggers. This is also a slight departure from the x86 behaviour, since `si_addr` returns the data address that triggered the watchpoint, not the address of the instruction that was executed. Otherwise, there is no straightforward way for the application to determine which watchpoint was triggered. Make a note of this in the siginfo(3) man page. Reviewed by: jhb, markj (earlier version) Tested by: Michał Górny (mgorny@gentoo.org) MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D28561
-rw-r--r--share/man/man3/siginfo.37
-rw-r--r--sys/arm64/arm64/trap.c6
-rw-r--r--sys/arm64/include/armreg.h1
3 files changed, 13 insertions, 1 deletions
diff --git a/share/man/man3/siginfo.3 b/share/man/man3/siginfo.3
index fc4ea2ba1df7..acc8785b2f0d 100644
--- a/share/man/man3/siginfo.3
+++ b/share/man/man3/siginfo.3
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 28, 2020
+.Dd February 17, 2021
.Dt SIGINFO 3
.Os
.Sh NAME
@@ -218,6 +218,11 @@ and
may report the address of the faulting memory access (if available) in
.Va si_addr
instead.
+Additionally
+.Dv SIGTRAP
+raised by a hardware watchpoint exception may report the data address that
+triggered the watchpoint in
+.Va si_addr .
.Pp
Sychronous signals set
.Va si_trapno
diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c
index 0b2d4760cea3..cb3a05ad0163 100644
--- a/sys/arm64/arm64/trap.c
+++ b/sys/arm64/arm64/trap.c
@@ -474,6 +474,7 @@ do_el0_sync(struct thread *td, struct trapframe *frame)
case EXCP_UNKNOWN:
case EXCP_DATA_ABORT_L:
case EXCP_DATA_ABORT:
+ case EXCP_WATCHPT_EL0:
far = READ_SPECIALREG(far_el1);
break;
}
@@ -534,6 +535,11 @@ do_el0_sync(struct thread *td, struct trapframe *frame)
exception);
userret(td, frame);
break;
+ case EXCP_WATCHPT_EL0:
+ call_trapsignal(td, SIGTRAP, TRAP_TRACE, (void *)far,
+ exception);
+ userret(td, frame);
+ break;
case EXCP_MSR:
/*
* The CPU can raise EXCP_MSR when userspace executes an mrs
diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h
index f2bce02782ec..70390d4ebf1e 100644
--- a/sys/arm64/include/armreg.h
+++ b/sys/arm64/include/armreg.h
@@ -230,6 +230,7 @@
#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_EL0 0x34 /* Watchpoint, from lower EL */
#define EXCP_WATCHPT_EL1 0x35 /* Watchpoint, from same EL */
#define EXCP_BRK 0x3c /* Breakpoint */