@@ -1328,6 +1328,15 @@ static void cf_check svm_inject_event(const struct x86_event *event)
switch ( _event.vector | -(_event.type == X86_EVENTTYPE_SW_INTERRUPT) )
{
case X86_EXC_DB:
+ /*
+ * On AMD hardware, a #DB exception:
+ * 1) Merges new status bits into %dr6
+ * 2) Clears %dr7.gd and MSR_DEBUGCTL.{LBR,BTF}
+ *
+ * Item 1 is done by hardware before a #DB intercepted vmexit, but we
+ * may end up here from monitor so have to repeat it ourselves.
+ * Item 2 is done by hardware when injecting a #DB exception.
+ */
__restore_debug_registers(vmcb, curr);
vmcb_set_dr6(vmcb, vmcb_get_dr6(vmcb) | _event.pending_dbg);
@@ -2022,6 +2022,13 @@ static void cf_check vmx_inject_event(const struct x86_event *event)
switch ( _event.vector | -(_event.type == X86_EVENTTYPE_SW_INTERRUPT) )
{
case X86_EXC_DB:
+ /*
+ * On Intel hardware, a #DB exception:
+ * 1) Merges new status bits into %dr6
+ * 2) Clears %dr7.gd and MSR_DEBUGCTL.LBR
+ *
+ * All actions are left up to the hypervisor to perform.
+ */
__restore_debug_registers(curr);
write_debugreg(6, read_debugreg(6) | event->pending_dbg);