Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150425825
D44739.id136866.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D44739.id136866.diff
View Options
diff --git a/sys/arm64/include/vmm.h b/sys/arm64/include/vmm.h
--- a/sys/arm64/include/vmm.h
+++ b/sys/arm64/include/vmm.h
@@ -295,9 +295,10 @@
*/
enum vm_cap_type {
VM_CAP_HALT_EXIT,
- VM_CAP_MTRAP_EXIT,
VM_CAP_PAUSE_EXIT,
VM_CAP_UNRESTRICTED_GUEST,
+ VM_CAP_BRK_EXIT,
+ VM_CAP_SS_EXIT,
VM_CAP_MAX
};
@@ -312,6 +313,8 @@
VM_EXITCODE_PAGING,
VM_EXITCODE_SMCCC,
VM_EXITCODE_DEBUG,
+ VM_EXITCODE_BRK,
+ VM_EXITCODE_SS,
VM_EXITCODE_MAX
};
diff --git a/sys/arm64/vmm/arm64.h b/sys/arm64/vmm/arm64.h
--- a/sys/arm64/vmm/arm64.h
+++ b/sys/arm64/vmm/arm64.h
@@ -39,6 +39,9 @@
struct vgic_v3;
struct vgic_v3_cpu;
+/*
+ * Per-vCPU hypervisor state.
+ */
struct hypctx {
struct trapframe tf;
@@ -104,6 +107,12 @@
struct vtimer_cpu vtimer_cpu;
+ /* vCPU state used to handle guest debugging. */
+ uint64_t debug_spsr; /* Saved guest SPSR */
+ uint64_t debug_mdscr; /* Saved guest MDSCR */
+ bool debug_ss_enabled; /* Is CAP_SS_EXIT configured? */
+ bool debug_brk_enabled; /* Is CAP_BRK_EXIT configured? */
+
struct vgic_v3_regs vgic_v3_regs;
struct vgic_v3_cpu *vgic_cpu;
bool has_exception;
diff --git a/sys/arm64/vmm/vmm_arm64.c b/sys/arm64/vmm/vmm_arm64.c
--- a/sys/arm64/vmm/vmm_arm64.c
+++ b/sys/arm64/vmm/vmm_arm64.c
@@ -539,6 +539,8 @@
vtimer_cpuinit(hypctx);
vgic_cpuinit(hypctx);
+ hypctx->debug_brk_enabled = hypctx->debug_ss_enabled = false;
+
hypctx->el2_addr = el2_map_enter((vm_offset_t)hypctx, size,
VM_PROT_READ | VM_PROT_WRITE);
@@ -700,7 +702,14 @@
arm64_gen_reg_emul_data(esr_iss, vme_ret);
vme_ret->exitcode = VM_EXITCODE_REG_EMUL;
break;
-
+ case EXCP_BRK:
+ vmm_stat_incr(hypctx->vcpu, VMEXIT_BRK, 1);
+ vme_ret->exitcode = VM_EXITCODE_BRK;
+ break;
+ case EXCP_SOFTSTP_EL0:
+ vmm_stat_incr(hypctx->vcpu, VMEXIT_SS, 1);
+ vme_ret->exitcode = VM_EXITCODE_SS;
+ break;
case EXCP_INSN_ABORT_L:
case EXCP_DATA_ABORT_L:
vmm_stat_incr(hypctx->vcpu, esr_ec == EXCP_DATA_ABORT_L ?
@@ -1313,6 +1322,7 @@
int
vmmops_getcap(void *vcpui, int num, int *retval)
{
+ struct hypctx *hypctx = vcpui;
int ret;
ret = ENOENT;
@@ -1322,6 +1332,13 @@
*retval = 1;
ret = 0;
break;
+ case VM_CAP_BRK_EXIT:
+ *retval = hypctx->debug_brk_enabled ? 1 : 0;
+ ret = 0;
+ break;
+ case VM_CAP_SS_EXIT:
+ *retval = hypctx->debug_ss_enabled ? 1 : 0;
+ break;
default:
break;
}
@@ -1332,6 +1349,45 @@
int
vmmops_setcap(void *vcpui, int num, int val)
{
+ struct hypctx *hypctx = vcpui;
+ int ret;
- return (ENOENT);
+ ret = 0;
+
+ switch (num) {
+ case VM_CAP_BRK_EXIT:
+ if (val != 0)
+ hypctx->mdcr_el2 |= MDCR_EL2_TDE;
+ else if (!hypctx->debug_ss_enabled)
+ hypctx->mdcr_el2 &= ~MDCR_EL2_TDE;
+ hypctx->debug_brk_enabled = (val != 0);
+ break;
+ case VM_CAP_SS_EXIT:
+ if (val != 0)
+ hypctx->mdcr_el2 |= MDCR_EL2_TDE;
+ else if (!hypctx->debug_brk_enabled)
+ hypctx->mdcr_el2 &= ~MDCR_EL2_TDE;
+
+ if (val != 0) {
+ hypctx->debug_spsr = hypctx->spsr_el1 & PSR_SS;
+ hypctx->debug_mdscr = hypctx->mdscr_el1 &
+ (MDSCR_SS | MDSCR_KDE);
+
+ hypctx->spsr_el1 |= PSR_SS;
+ hypctx->mdscr_el1 |= MDSCR_SS | MDSCR_KDE;
+ } else if (hypctx->debug_ss_enabled) {
+ hypctx->spsr_el1 &= ~PSR_SS;
+ hypctx->spsr_el1 |= hypctx->debug_spsr & PSR_SS;
+ hypctx->mdscr_el1 &= ~(MDSCR_SS | MDSCR_KDE);
+ hypctx->mdscr_el1 |= hypctx->debug_mdscr &
+ (MDSCR_SS | MDSCR_KDE);
+ }
+ hypctx->debug_ss_enabled = (val != 0);
+ break;
+ default:
+ ret = ENOENT;
+ break;
+ }
+
+ return (ret);
}
diff --git a/sys/arm64/vmm/vmm_stat.h b/sys/arm64/vmm/vmm_stat.h
--- a/sys/arm64/vmm/vmm_stat.h
+++ b/sys/arm64/vmm/vmm_stat.h
@@ -140,6 +140,8 @@
VMM_STAT_DECLARE(VMEXIT_UNHANDLED_SYNC);
VMM_STAT_DECLARE(VMEXIT_IRQ);
VMM_STAT_DECLARE(VMEXIT_FIQ);
+VMM_STAT_DECLARE(VMEXIT_BRK);
+VMM_STAT_DECLARE(VMEXIT_SS);
VMM_STAT_DECLARE(VMEXIT_UNHANDLED_EL2);
VMM_STAT_DECLARE(VMEXIT_UNHANDLED);
#endif
diff --git a/sys/arm64/vmm/vmm_stat.c b/sys/arm64/vmm/vmm_stat.c
--- a/sys/arm64/vmm/vmm_stat.c
+++ b/sys/arm64/vmm/vmm_stat.c
@@ -161,5 +161,7 @@
VMM_STAT(VMEXIT_UNHANDLED_SYNC, "number of vmexits for an unhandled synchronous exception");
VMM_STAT(VMEXIT_IRQ, "number of vmexits for an irq");
VMM_STAT(VMEXIT_FIQ, "number of vmexits for an interrupt");
+VMM_STAT(VMEXIT_BRK, "number of vmexits for a breakpoint exception");
+VMM_STAT(VMEXIT_SS, "number of vmexits for a single-step exception");
VMM_STAT(VMEXIT_UNHANDLED_EL2, "number of vmexits for an unhandled EL2 exception");
VMM_STAT(VMEXIT_UNHANDLED, "number of vmexits for an unhandled exception");
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 2, 3:32 AM (15 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30701675
Default Alt Text
D44739.id136866.diff (4 KB)
Attached To
Mode
D44739: arm64/vmm: Add breakpoint and single-stepping support
Attached
Detach File
Event Timeline
Log In to Comment