From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xen.org>
Cc: "Kevin Tian" <kevin.tian@intel.com>,
"Wei Liu" <wei.liu2@citrix.com>,
"Jan Beulich" <JBeulich@suse.com>,
"Andrew Cooper" <andrew.cooper3@citrix.com>,
"Jun Nakajima" <jun.nakajima@intel.com>,
"Boris Ostrovsky" <boris.ostrovsky@oracle.com>,
"Brian Woods" <brian.woods@amd.com>,
"Suravee Suthikulpanit" <suravee.suthikulpanit@amd.com>,
"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [PATCH 06/11] x86: Reorganise and rename debug register fields in struct vcpu
Date: Mon, 4 Jun 2018 14:59:10 +0100 [thread overview]
Message-ID: <1528120755-17455-7-git-send-email-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <1528120755-17455-1-git-send-email-andrew.cooper3@citrix.com>
Reusing debugreg[5] for the PV emulated IO breakpoint information is confusing
to read. Instead, introduce a dr7_emul field in pv_vcpu for the pupose.
With the PV emulation out of the way, debugreg[4,5] are entirely unused and
don't need to be stored.
Rename debugreg[0..3] to dr[0..3] to reduce code volume, but keep them as an
array because their behaviour is identical and this helps simplfy some of the
PV handling. Introduce dr6 and dr7 fields to replace debugreg[6,7] which
removes the storage for debugreg[4,5].
Two minor alterations on the PV side is that merging of the emulated state
happens along with the other dr handling, rather than much later, and
arch_set_info_guest() now checks the return value from set_debugreg() fails
the hypercall rather than silently discarding the values.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Wei Liu <wei.liu2@citrix.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
CC: Jun Nakajima <jun.nakajima@intel.com>
CC: Kevin Tian <kevin.tian@intel.com>
CC: Boris Ostrovsky <boris.ostrovsky@oracle.com>
CC: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
CC: Brian Woods <brian.woods@amd.com>
---
xen/arch/x86/acpi/suspend.c | 14 +++++++-------
xen/arch/x86/domain.c | 27 ++++++++++++++++-----------
xen/arch/x86/domctl.c | 15 +++++----------
xen/arch/x86/hvm/hvm.c | 30 +++++++++++++++---------------
xen/arch/x86/hvm/svm/svm.c | 27 ++++++++++++++-------------
xen/arch/x86/hvm/vmx/vmx.c | 26 +++++++++++++-------------
xen/arch/x86/pv/emul-priv-op.c | 14 +++++++-------
xen/arch/x86/pv/emulate.c | 2 +-
xen/arch/x86/traps.c | 30 +++++++++++++++---------------
xen/arch/x86/vm_event.c | 2 +-
xen/arch/x86/x86_emulate.c | 7 +++----
xen/include/asm-x86/domain.h | 11 ++++++++++-
12 files changed, 107 insertions(+), 98 deletions(-)
diff --git a/xen/arch/x86/acpi/suspend.c b/xen/arch/x86/acpi/suspend.c
index 044bd81..1a129b4 100644
--- a/xen/arch/x86/acpi/suspend.c
+++ b/xen/arch/x86/acpi/suspend.c
@@ -82,14 +82,14 @@ void restore_rest_processor_state(void)
/* Maybe load the debug registers. */
BUG_ON(!is_pv_vcpu(curr));
- if ( !is_idle_vcpu(curr) && curr->arch.debugreg[7] )
+ if ( !is_idle_vcpu(curr) && curr->arch.dr7 )
{
- write_debugreg(0, curr->arch.debugreg[0]);
- write_debugreg(1, curr->arch.debugreg[1]);
- write_debugreg(2, curr->arch.debugreg[2]);
- write_debugreg(3, curr->arch.debugreg[3]);
- write_debugreg(6, curr->arch.debugreg[6]);
- write_debugreg(7, curr->arch.debugreg[7]);
+ write_debugreg(0, curr->arch.dr[0]);
+ write_debugreg(1, curr->arch.dr[1]);
+ write_debugreg(2, curr->arch.dr[2]);
+ write_debugreg(3, curr->arch.dr[3]);
+ write_debugreg(6, curr->arch.dr6);
+ write_debugreg(7, curr->arch.dr7);
}
/* Reload FPU state on next FPU use. */
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index cee57a8..ba8eb05 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -326,8 +326,8 @@ static void initialise_registers(struct vcpu *v)
{
v->arch.user_regs.eflags = X86_EFLAGS_MBS;
- v->arch.debugreg[6] = X86_DR6_DEFAULT;
- v->arch.debugreg[7] = X86_DR7_DEFAULT;
+ v->arch.dr6 = X86_DR6_DEFAULT;
+ v->arch.dr7 = X86_DR7_DEFAULT;
}
int vcpu_initialise(struct vcpu *v)
@@ -895,10 +895,10 @@ int arch_set_info_guest(
if ( is_hvm_domain(d) )
{
- for ( i = 0; i < ARRAY_SIZE(v->arch.debugreg) - 2; ++i )
- v->arch.debugreg[i] = c(debugreg[i]);
- v->arch.debugreg[6] = adjust_dr6_rsvd(c(debugreg[6]), cp->feat.rtm);
- v->arch.debugreg[7] = adjust_dr7_rsvd(c(debugreg[7]), cp->feat.rtm);
+ for ( i = 0; i < ARRAY_SIZE(v->arch.dr); ++i )
+ v->arch.dr[i] = c(debugreg[i]);
+ v->arch.dr6 = adjust_dr6_rsvd(c(debugreg[6]), cp->feat.rtm);
+ v->arch.dr7 = adjust_dr7_rsvd(c(debugreg[7]), cp->feat.rtm);
hvm_set_info_guest(v);
goto out;
@@ -981,9 +981,14 @@ int arch_set_info_guest(
v->arch.pv_vcpu.ctrlreg[4] = cr4 ? pv_guest_cr4_fixup(v, cr4) :
real_cr4_to_pv_guest_cr4(mmu_cr4_features);
- memset(v->arch.debugreg, 0, sizeof(v->arch.debugreg));
- for ( i = 0; i < 8; i++ )
- (void)set_debugreg(v, i, c(debugreg[i]));
+ for ( i = 0; !rc && i < ARRAY_SIZE(v->arch.dr); i++ )
+ rc = set_debugreg(v, i, c(debugreg[i]));
+ if ( !rc )
+ rc = set_debugreg(v, 6, c(debugreg[6]));
+ if ( !rc )
+ rc = set_debugreg(v, 7, c(debugreg[7]));
+ if ( rc )
+ return rc;
if ( v->is_initialised )
goto out;
@@ -1525,7 +1530,7 @@ void paravirt_ctxt_switch_from(struct vcpu *v)
* inside Xen, before we get a chance to reload DR7, and this cannot always
* safely be handled.
*/
- if ( unlikely(v->arch.debugreg[7] & DR7_ACTIVE_MASK) )
+ if ( unlikely(v->arch.dr7 & DR7_ACTIVE_MASK) )
write_debugreg(7, 0);
}
@@ -1538,7 +1543,7 @@ void paravirt_ctxt_switch_to(struct vcpu *v)
l4e_from_page(v->domain->arch.perdomain_l3_pg,
__PAGE_HYPERVISOR_RW);
- if ( unlikely(v->arch.debugreg[7] & DR7_ACTIVE_MASK) )
+ if ( unlikely(v->arch.dr7 & DR7_ACTIVE_MASK) )
activate_debugregs(v);
if ( cpu_has_rdtscp )
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 8fbbf3a..54f9f0e 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -1565,8 +1565,11 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
}
}
- for ( i = 0; i < ARRAY_SIZE(v->arch.debugreg); ++i )
- c(debugreg[i] = v->arch.debugreg[i]);
+ for ( i = 0; i < ARRAY_SIZE(v->arch.dr); ++i )
+ c(debugreg[i] = v->arch.dr[i]);
+ c(debugreg[6] = v->arch.dr6);
+ c(debugreg[7] = v->arch.dr7 |
+ (is_pv_domain(d) ? v->arch.pv_vcpu.dr7_emul : 0));
if ( is_hvm_domain(d) )
{
@@ -1641,10 +1644,6 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
c.nat->ctrlreg[1] =
pagetable_is_null(v->arch.guest_table_user) ? 0
: xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table_user));
-
- /* Merge shadow DR7 bits into real DR7. */
- c.nat->debugreg[7] |= c.nat->debugreg[5];
- c.nat->debugreg[5] = 0;
}
else
{
@@ -1653,10 +1652,6 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
c.cmp->ctrlreg[3] = compat_pfn_to_cr3(l4e_get_pfn(*l4e));
unmap_domain_page(l4e);
-
- /* Merge shadow DR7 bits into real DR7. */
- c.cmp->debugreg[7] |= c.cmp->debugreg[5];
- c.cmp->debugreg[5] = 0;
}
if ( guest_kernel_mode(v, &v->arch.user_regs) )
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 7fddae1..4f825a2 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -883,12 +883,12 @@ static int hvm_save_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
ctxt.r13 = v->arch.user_regs.r13;
ctxt.r14 = v->arch.user_regs.r14;
ctxt.r15 = v->arch.user_regs.r15;
- ctxt.dr0 = v->arch.debugreg[0];
- ctxt.dr1 = v->arch.debugreg[1];
- ctxt.dr2 = v->arch.debugreg[2];
- ctxt.dr3 = v->arch.debugreg[3];
- ctxt.dr6 = v->arch.debugreg[6];
- ctxt.dr7 = v->arch.debugreg[7];
+ ctxt.dr0 = v->arch.dr[0];
+ ctxt.dr1 = v->arch.dr[1];
+ ctxt.dr2 = v->arch.dr[2];
+ ctxt.dr3 = v->arch.dr[3];
+ ctxt.dr6 = v->arch.dr6;
+ ctxt.dr7 = v->arch.dr7;
if ( hvm_save_entry(CPU, v->vcpu_id, h, &ctxt) != 0 )
return 1;
@@ -1151,12 +1151,12 @@ static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
v->arch.user_regs.r13 = ctxt.r13;
v->arch.user_regs.r14 = ctxt.r14;
v->arch.user_regs.r15 = ctxt.r15;
- v->arch.debugreg[0] = ctxt.dr0;
- v->arch.debugreg[1] = ctxt.dr1;
- v->arch.debugreg[2] = ctxt.dr2;
- v->arch.debugreg[3] = ctxt.dr3;
- v->arch.debugreg[6] = adjust_dr6_rsvd(ctxt.dr6, cp->feat.rtm);
- v->arch.debugreg[7] = adjust_dr7_rsvd(ctxt.dr7, cp->feat.rtm);
+ v->arch.dr[0] = ctxt.dr0;
+ v->arch.dr[1] = ctxt.dr1;
+ v->arch.dr[2] = ctxt.dr2;
+ v->arch.dr[3] = ctxt.dr3;
+ v->arch.dr6 = adjust_dr6_rsvd(ctxt.dr6, cp->feat.rtm);
+ v->arch.dr7 = adjust_dr7_rsvd(ctxt.dr7, cp->feat.rtm);
v->arch.vgc_flags = VGCF_online;
@@ -3910,9 +3910,9 @@ void hvm_vcpu_reset_state(struct vcpu *v, uint16_t cs, uint16_t ip)
v->arch.user_regs.rdx = 0x00000f00;
v->arch.user_regs.rip = ip;
- memset(&v->arch.debugreg, 0, sizeof(v->arch.debugreg) - 16);
- v->arch.debugreg[6] = X86_DR6_DEFAULT;
- v->arch.debugreg[7] = X86_DR7_DEFAULT;
+ memset(v->arch.dr, 0, sizeof(v->arch.dr));
+ v->arch.dr6 = X86_DR6_DEFAULT;
+ v->arch.dr7 = X86_DR7_DEFAULT;
v->arch.hvm_vcpu.guest_cr[0] = X86_CR0_ET;
hvm_update_guest_cr(v, 0);
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 49bb722..dabb96f 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -215,12 +215,12 @@ static void svm_save_dr(struct vcpu *v)
rdmsrl(MSR_AMD64_DR3_ADDRESS_MASK, v->arch.hvm_svm.dr_mask[3]);
}
- v->arch.debugreg[0] = read_debugreg(0);
- v->arch.debugreg[1] = read_debugreg(1);
- v->arch.debugreg[2] = read_debugreg(2);
- v->arch.debugreg[3] = read_debugreg(3);
- v->arch.debugreg[6] = vmcb_get_dr6(vmcb);
- v->arch.debugreg[7] = vmcb_get_dr7(vmcb);
+ v->arch.dr[0] = read_debugreg(0);
+ v->arch.dr[1] = read_debugreg(1);
+ v->arch.dr[2] = read_debugreg(2);
+ v->arch.dr[3] = read_debugreg(3);
+ v->arch.dr6 = vmcb_get_dr6(vmcb);
+ v->arch.dr7 = vmcb_get_dr7(vmcb);
}
static void __restore_debug_registers(struct vmcb_struct *vmcb, struct vcpu *v)
@@ -246,12 +246,12 @@ static void __restore_debug_registers(struct vmcb_struct *vmcb, struct vcpu *v)
wrmsrl(MSR_AMD64_DR3_ADDRESS_MASK, v->arch.hvm_svm.dr_mask[3]);
}
- write_debugreg(0, v->arch.debugreg[0]);
- write_debugreg(1, v->arch.debugreg[1]);
- write_debugreg(2, v->arch.debugreg[2]);
- write_debugreg(3, v->arch.debugreg[3]);
- vmcb_set_dr6(vmcb, v->arch.debugreg[6]);
- vmcb_set_dr7(vmcb, v->arch.debugreg[7]);
+ write_debugreg(0, v->arch.dr[0]);
+ write_debugreg(1, v->arch.dr[1]);
+ write_debugreg(2, v->arch.dr[2]);
+ write_debugreg(3, v->arch.dr[3]);
+ vmcb_set_dr6(vmcb, v->arch.dr6);
+ vmcb_set_dr7(vmcb, v->arch.dr7);
}
/*
@@ -263,7 +263,8 @@ static void __restore_debug_registers(struct vmcb_struct *vmcb, struct vcpu *v)
static void svm_restore_dr(struct vcpu *v)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- if ( unlikely(v->arch.debugreg[7] & DR7_ACTIVE_MASK) )
+
+ if ( unlikely(v->arch.dr7 & DR7_ACTIVE_MASK) )
__restore_debug_registers(vmcb, v);
}
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 8dbe838..bfa3a0d 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -610,13 +610,13 @@ static void vmx_save_dr(struct vcpu *v)
v->arch.hvm_vmx.exec_control |= CPU_BASED_MOV_DR_EXITING;
vmx_update_cpu_exec_control(v);
- v->arch.debugreg[0] = read_debugreg(0);
- v->arch.debugreg[1] = read_debugreg(1);
- v->arch.debugreg[2] = read_debugreg(2);
- v->arch.debugreg[3] = read_debugreg(3);
- v->arch.debugreg[6] = read_debugreg(6);
+ v->arch.dr[0] = read_debugreg(0);
+ v->arch.dr[1] = read_debugreg(1);
+ v->arch.dr[2] = read_debugreg(2);
+ v->arch.dr[3] = read_debugreg(3);
+ v->arch.dr6 = read_debugreg(6);
/* DR7 must be saved as it is used by vmx_restore_dr(). */
- __vmread(GUEST_DR7, &v->arch.debugreg[7]);
+ __vmread(GUEST_DR7, &v->arch.dr7);
}
static void __restore_debug_registers(struct vcpu *v)
@@ -626,11 +626,11 @@ static void __restore_debug_registers(struct vcpu *v)
v->arch.hvm_vcpu.flag_dr_dirty = 1;
- write_debugreg(0, v->arch.debugreg[0]);
- write_debugreg(1, v->arch.debugreg[1]);
- write_debugreg(2, v->arch.debugreg[2]);
- write_debugreg(3, v->arch.debugreg[3]);
- write_debugreg(6, v->arch.debugreg[6]);
+ write_debugreg(0, v->arch.dr[0]);
+ write_debugreg(1, v->arch.dr[1]);
+ write_debugreg(2, v->arch.dr[2]);
+ write_debugreg(3, v->arch.dr[3]);
+ write_debugreg(6, v->arch.dr6);
/* DR7 is loaded from the VMCS. */
}
@@ -643,7 +643,7 @@ static void __restore_debug_registers(struct vcpu *v)
static void vmx_restore_dr(struct vcpu *v)
{
/* NB. __vmread() is not usable here, so we cannot read from the VMCS. */
- if ( unlikely(v->arch.debugreg[7] & DR7_ACTIVE_MASK) )
+ if ( unlikely(v->arch.dr7 & DR7_ACTIVE_MASK) )
__restore_debug_registers(v);
}
@@ -1870,7 +1870,7 @@ static void vmx_set_info_guest(struct vcpu *v)
vmx_vmcs_enter(v);
- __vmwrite(GUEST_DR7, v->arch.debugreg[7]);
+ __vmwrite(GUEST_DR7, v->arch.dr7);
/*
* If the interruptibility-state field indicates blocking by STI,
diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c
index ce2ec76..dfde70e 100644
--- a/xen/arch/x86/pv/emul-priv-op.c
+++ b/xen/arch/x86/pv/emul-priv-op.c
@@ -286,20 +286,20 @@ static unsigned int check_guest_io_breakpoint(struct vcpu *v,
unsigned int width, i, match = 0;
unsigned long start;
- if ( !(v->arch.debugreg[5]) ||
+ if ( !v->arch.pv_vcpu.dr7_emul ||
!(v->arch.pv_vcpu.ctrlreg[4] & X86_CR4_DE) )
return 0;
for ( i = 0; i < 4; i++ )
{
- if ( !(v->arch.debugreg[5] &
+ if ( !(v->arch.pv_vcpu.dr7_emul &
(3 << (i * DR_ENABLE_SIZE))) )
continue;
- start = v->arch.debugreg[i];
+ start = v->arch.dr[i];
width = 0;
- switch ( (v->arch.debugreg[7] >>
+ switch ( (v->arch.dr7 >>
(DR_CONTROL_SHIFT + i * DR_CONTROL_SIZE)) & 0xc )
{
case DR_LEN_1: width = 1; break;
@@ -1116,7 +1116,7 @@ static int write_msr(unsigned int reg, uint64_t val,
if ( !boot_cpu_has(X86_FEATURE_DBEXT) || (val >> 32) )
break;
curr->arch.pv_vcpu.dr_mask[0] = val;
- if ( curr->arch.debugreg[7] & DR7_ACTIVE_MASK )
+ if ( curr->arch.dr7 & DR7_ACTIVE_MASK )
wrmsrl(MSR_AMD64_DR0_ADDRESS_MASK, val);
return X86EMUL_OKAY;
@@ -1124,7 +1124,7 @@ static int write_msr(unsigned int reg, uint64_t val,
if ( !boot_cpu_has(X86_FEATURE_DBEXT) || (val >> 32) )
break;
curr->arch.pv_vcpu.dr_mask[reg - MSR_AMD64_DR1_ADDRESS_MASK + 1] = val;
- if ( curr->arch.debugreg[7] & DR7_ACTIVE_MASK )
+ if ( curr->arch.dr7 & DR7_ACTIVE_MASK )
wrmsrl(reg, val);
return X86EMUL_OKAY;
@@ -1368,7 +1368,7 @@ int pv_emulate_privileged_op(struct cpu_user_regs *regs)
ctxt.bpmatch |= DR_STEP;
if ( ctxt.bpmatch )
{
- curr->arch.debugreg[6] |= ctxt.bpmatch | DR_STATUS_RESERVED_ONE;
+ curr->arch.dr6 |= ctxt.bpmatch | DR_STATUS_RESERVED_ONE;
if ( !(curr->arch.pv_vcpu.trap_bounce.flags & TBF_EXCEPTION) )
pv_inject_hw_exception(TRAP_debug, X86_EVENT_NO_EC);
}
diff --git a/xen/arch/x86/pv/emulate.c b/xen/arch/x86/pv/emulate.c
index 1b60911..757ffd1 100644
--- a/xen/arch/x86/pv/emulate.c
+++ b/xen/arch/x86/pv/emulate.c
@@ -78,7 +78,7 @@ void pv_emul_instruction_done(struct cpu_user_regs *regs, unsigned long rip)
regs->eflags &= ~X86_EFLAGS_RF;
if ( regs->eflags & X86_EFLAGS_TF )
{
- current->arch.debugreg[6] |= DR_STEP | DR_STATUS_RESERVED_ONE;
+ current->arch.dr6 |= DR_STEP | DR_STATUS_RESERVED_ONE;
pv_inject_hw_exception(TRAP_debug, X86_EVENT_NO_EC);
}
}
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index e9bfbc7..d0d9011 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -1861,8 +1861,8 @@ void do_debug(struct cpu_user_regs *regs)
}
/* Save debug status register where guest OS can peek at it */
- v->arch.debugreg[6] |= (dr6 & ~X86_DR6_DEFAULT);
- v->arch.debugreg[6] &= (dr6 | ~X86_DR6_DEFAULT);
+ v->arch.dr6 |= (dr6 & ~X86_DR6_DEFAULT);
+ v->arch.dr6 &= (dr6 | ~X86_DR6_DEFAULT);
pv_inject_hw_exception(TRAP_debug, X86_EVENT_NO_EC);
}
@@ -2025,19 +2025,19 @@ void activate_debugregs(const struct vcpu *curr)
{
ASSERT(curr == current);
- write_debugreg(0, curr->arch.debugreg[0]);
- write_debugreg(1, curr->arch.debugreg[1]);
- write_debugreg(2, curr->arch.debugreg[2]);
- write_debugreg(3, curr->arch.debugreg[3]);
- write_debugreg(6, curr->arch.debugreg[6]);
+ write_debugreg(0, curr->arch.dr[0]);
+ write_debugreg(1, curr->arch.dr[1]);
+ write_debugreg(2, curr->arch.dr[2]);
+ write_debugreg(3, curr->arch.dr[3]);
+ write_debugreg(6, curr->arch.dr6);
/*
* Avoid writing the subsequently getting replaced value when getting
* called from set_debugreg() below. Eventual future callers will need
* to take this into account.
*/
- if ( curr->arch.debugreg[7] & DR7_ACTIVE_MASK )
- write_debugreg(7, curr->arch.debugreg[7]);
+ if ( curr->arch.dr7 & DR7_ACTIVE_MASK )
+ write_debugreg(7, curr->arch.dr7);
if ( boot_cpu_has(X86_FEATURE_DBEXT) )
{
@@ -2065,6 +2065,7 @@ long set_debugreg(struct vcpu *v, unsigned int reg, unsigned long value)
if ( !access_ok(value, sizeof(long)) )
return -EPERM;
+ v->arch.dr[reg] = value;
if ( v == curr )
{
switch ( reg )
@@ -2089,6 +2090,7 @@ long set_debugreg(struct vcpu *v, unsigned int reg, unsigned long value)
value = adjust_dr6_rsvd(value, cp->feat.rtm);
+ v->arch.dr6 = value;
if ( v == curr )
write_debugreg(6, value);
break;
@@ -2127,8 +2129,7 @@ long set_debugreg(struct vcpu *v, unsigned int reg, unsigned long value)
}
}
- /* Guest DR5 is a handy stash for I/O intercept information. */
- v->arch.debugreg[5] = io_enable;
+ v->arch.pv_vcpu.dr7_emul = io_enable;
value &= ~io_enable;
/*
@@ -2136,14 +2137,14 @@ long set_debugreg(struct vcpu *v, unsigned int reg, unsigned long value)
* debug registers at this point as they were not restored during
* context switch. Updating DR7 itself happens later.
*/
- if ( (v == curr) &&
- !(v->arch.debugreg[7] & DR7_ACTIVE_MASK) )
+ if ( (v == curr) && !(v->arch.dr7 & DR7_ACTIVE_MASK) )
activate_debugregs(v);
}
else
/* Zero the emulated controls if %dr7 isn't active. */
- v->arch.debugreg[5] = 0;
+ v->arch.pv_vcpu.dr7_emul = 0;
+ v->arch.dr7 = value;
if ( v == curr )
write_debugreg(7, value);
break;
@@ -2152,7 +2153,6 @@ long set_debugreg(struct vcpu *v, unsigned int reg, unsigned long value)
return -ENODEV;
}
- v->arch.debugreg[reg] = value;
return 0;
}
diff --git a/xen/arch/x86/vm_event.c b/xen/arch/x86/vm_event.c
index f91aade..81facb0 100644
--- a/xen/arch/x86/vm_event.c
+++ b/xen/arch/x86/vm_event.c
@@ -155,7 +155,7 @@ void vm_event_fill_regs(vm_event_request_t *req)
req->data.regs.x86.rflags = regs->rflags;
req->data.regs.x86.rip = regs->rip;
- req->data.regs.x86.dr7 = curr->arch.debugreg[7];
+ req->data.regs.x86.dr7 = curr->arch.dr7;
req->data.regs.x86.cr0 = ctxt.cr0;
req->data.regs.x86.cr2 = ctxt.cr2;
req->data.regs.x86.cr3 = ctxt.cr3;
diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c
index 03b364a..9d1942b 100644
--- a/xen/arch/x86/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate.c
@@ -101,7 +101,7 @@ int x86emul_read_dr(unsigned int reg, unsigned long *val,
switch ( reg )
{
case 0 ... 3:
- *val = curr->arch.debugreg[reg];
+ *val = curr->arch.dr[reg];
break;
case 4:
@@ -110,7 +110,7 @@ int x86emul_read_dr(unsigned int reg, unsigned long *val,
/* Fallthrough */
case 6:
- *val = curr->arch.debugreg[6];
+ *val = curr->arch.dr6;
break;
case 5:
@@ -119,8 +119,7 @@ int x86emul_read_dr(unsigned int reg, unsigned long *val,
/* Fallthrough */
case 7:
- *val = (curr->arch.debugreg[7] |
- curr->arch.debugreg[5]);
+ *val = curr->arch.dr7 | curr->arch.pv_vcpu.dr7_emul;
break;
ud_fault:
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 197f8d6..59d5e4a 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -500,6 +500,12 @@ struct pv_vcpu
unsigned long shadow_ldt_mapcnt;
spinlock_t shadow_ldt_lock;
+ /*
+ * %dr7 bits the guest has set, but aren't loaded into hardware, and are
+ * completely emulated.
+ */
+ uint32_t dr7_emul;
+
/* data breakpoint extension MSRs */
uint32_t dr_mask[4];
@@ -518,7 +524,10 @@ struct arch_vcpu
void *fpu_ctxt;
unsigned long vgc_flags;
struct cpu_user_regs user_regs;
- unsigned long debugreg[8];
+
+ /* Debug registers. */
+ unsigned long dr[4];
+ unsigned long dr6, dr7;
/* other state */
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2018-06-04 13:59 UTC|newest]
Thread overview: 62+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-04 13:59 [PATCH 00/11] Fixes to debugging facilities Andrew Cooper
2018-06-04 13:59 ` [PATCH 01/11] x86/svm Fixes and cleanup to svm_inject_event() Andrew Cooper
2018-06-06 13:37 ` Jan Beulich
2018-07-16 13:33 ` Andrew Cooper
2018-07-17 2:01 ` Boris Ostrovsky
2018-06-04 13:59 ` [PATCH 02/11] x86/vmx: Don't clobber %dr6 while debugging state is lazy Andrew Cooper
2018-06-06 10:16 ` Roger Pau Monné
2018-06-06 13:50 ` Jan Beulich
2018-06-06 14:16 ` Andrew Cooper
2018-06-07 11:05 ` Jan Beulich
2018-06-08 15:58 ` Andrew Cooper
2018-06-08 16:10 ` Jan Beulich
2018-07-17 9:28 ` Andrew Cooper
2018-07-19 2:14 ` Tian, Kevin
2018-06-04 13:59 ` [PATCH 03/11] x86: Initialise debug registers correctly Andrew Cooper
2018-06-06 10:34 ` Roger Pau Monné
2018-06-08 15:23 ` Andrew Cooper
2018-06-06 13:56 ` Jan Beulich
2018-06-08 15:42 ` Andrew Cooper
2018-06-08 16:14 ` Jan Beulich
2018-06-04 13:59 ` [PATCH 04/11] x86: Fix calculation of %dr6/7 reserved bits Andrew Cooper
2018-06-06 14:16 ` Jan Beulich
2018-06-06 14:50 ` Andrew Cooper
2018-06-06 14:52 ` Andrew Cooper
2018-06-06 15:11 ` Jan Beulich
2018-06-06 15:49 ` Roger Pau Monné
2018-06-06 15:59 ` Andrew Cooper
2018-06-06 17:36 ` Roger Pau Monné
2018-06-04 13:59 ` [PATCH 05/11] x86/emul: Unfold %cr4.de handling in x86emul_read_dr() Andrew Cooper
2018-06-06 14:20 ` Jan Beulich
2018-06-08 16:03 ` Andrew Cooper
2018-06-08 16:16 ` Jan Beulich
2018-06-06 15:54 ` Roger Pau Monné
2018-06-04 13:59 ` Andrew Cooper [this message]
2018-06-06 15:00 ` [PATCH 06/11] x86: Reorganise and rename debug register fields in struct vcpu Jan Beulich
2018-06-06 15:21 ` Andrew Cooper
2018-06-07 10:59 ` Jan Beulich
2018-06-06 16:22 ` Roger Pau Monné
2018-06-04 13:59 ` [PATCH 07/11] x86/emul: Add pending_dbg field to x86_event Andrew Cooper
2018-06-06 16:46 ` Roger Pau Monné
2018-06-06 16:50 ` Andrew Cooper
2018-06-06 17:03 ` Roger Pau Monné
2018-06-08 12:34 ` Jan Beulich
2018-06-08 12:48 ` Andrew Cooper
2018-06-04 13:59 ` [PATCH 08/11] x86/hvm: RFC - PROBABLY BROKEN - Defer all debugging/monitor actions to {svm, vmx}_inject_event() Andrew Cooper
2018-06-04 14:53 ` Razvan Cojocaru
2018-06-04 15:07 ` Razvan Cojocaru
2018-06-06 17:02 ` Roger Pau Monné
2018-06-08 13:00 ` Jan Beulich
2018-06-08 13:13 ` Andrew Cooper
2018-06-04 13:59 ` [PATCH 09/11] x86: Fix merging of new status bits into %dr6 Andrew Cooper
2018-06-06 17:09 ` Roger Pau Monné
2018-06-08 13:09 ` Jan Beulich
2018-06-04 13:59 ` [PATCH 10/11] x86/vmx: Work around VMEntry failure when Single Stepping in an STI shadow Andrew Cooper
2018-09-03 10:39 ` Ping VT-x: " Andrew Cooper
2018-09-04 5:27 ` Tian, Kevin
2018-06-04 13:59 ` [PATCH 11/11] x86/dbg: Cleanup of legacy dr6 constants Andrew Cooper
2018-06-06 17:10 ` Roger Pau Monné
2018-06-08 13:12 ` Jan Beulich
2018-06-04 15:39 ` [PATCH 00/11] Fixes to debugging facilities Andrew Cooper
2018-06-04 17:09 ` Razvan Cojocaru
2018-06-04 17:18 ` Andrew Cooper
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1528120755-17455-7-git-send-email-andrew.cooper3@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=JBeulich@suse.com \
--cc=boris.ostrovsky@oracle.com \
--cc=brian.woods@amd.com \
--cc=jun.nakajima@intel.com \
--cc=kevin.tian@intel.com \
--cc=roger.pau@citrix.com \
--cc=suravee.suthikulpanit@amd.com \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).