git: 457fa0f69ce0 - main - arm64: Support break and watch points in VHE

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Fri, 17 May 2024 16:12:52 UTC
The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=457fa0f69ce07f24070261376f1ea724324ec621

commit 457fa0f69ce07f24070261376f1ea724324ec621
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2024-03-14 18:01:24 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2024-05-17 16:07:16 +0000

    arm64: Support break and watch points in VHE
    
    When booting the kernel with VHE it will be running at EL2. The current
    config register values only enable the reaces at EL1 when tracing the
    kernel.
    
    Set the HMC flag to also trap from EL2.
    
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D45121
---
 sys/arm64/arm64/debug_monitor.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/sys/arm64/arm64/debug_monitor.c b/sys/arm64/arm64/debug_monitor.c
index 2e1a956ad75c..d92d3fb37ce4 100644
--- a/sys/arm64/arm64/debug_monitor.c
+++ b/sys/arm64/arm64/debug_monitor.c
@@ -40,6 +40,7 @@
 #include <machine/armreg.h>
 #include <machine/cpu.h>
 #include <machine/debug_monitor.h>
+#include <machine/machdep.h>
 #include <machine/kdb.h>
 #include <machine/pcb.h>
 
@@ -86,6 +87,7 @@ void dbg_monitor_exit(struct thread *, struct trapframe *);
 #define DBG_WATCH_CTRL_ACCESS_MASK(x)	((x) & (0x3 << 3))
 
 /* Common for breakpoint and watchpoint */
+#define DBG_WB_CTRL_HMC		(0x1 << 13)
 #define DBG_WB_CTRL_EL1		(0x1 << 1)
 #define DBG_WB_CTRL_EL0		(0x2 << 1)
 #define DBG_WB_CTRL_ELX_MASK(x)	((x) & (0x3 << 1))
@@ -457,6 +459,8 @@ dbg_setup_breakpoint(struct debug_monitor_state *monitor, vm_offset_t addr)
 
 	if ((monitor->dbg_flags & DBGMON_KERNEL) == 0)
 		bcr_priv = DBG_WB_CTRL_EL0;
+	else if (in_vhe())
+		bcr_priv = DBG_WB_CTRL_EL1 | DBG_WB_CTRL_HMC;
 	else
 		bcr_priv = DBG_WB_CTRL_EL1;
 
@@ -530,6 +534,8 @@ dbg_setup_watchpoint(struct debug_monitor_state *monitor, vm_offset_t addr,
 
 	if ((monitor->dbg_flags & DBGMON_KERNEL) == 0)
 		wcr_priv = DBG_WB_CTRL_EL0;
+	else if (in_vhe())
+		wcr_priv = DBG_WB_CTRL_EL1 | DBG_WB_CTRL_HMC;
 	else
 		wcr_priv = DBG_WB_CTRL_EL1;