* [PATCH 0/5] VMX: assorted adjustments
@ 2015-01-20 10:58 Jan Beulich
2015-01-20 11:05 ` [PATCH 1/5] VMX: dump full guest state Jan Beulich
` (4 more replies)
0 siblings, 5 replies; 20+ messages in thread
From: Jan Beulich @ 2015-01-20 10:58 UTC (permalink / raw)
To: xen-devel; +Cc: Kevin Tian, Eddie Dong, Jun Nakajima
1: dump full guest state
2: dump full host state
3: dump further control state
4: drop VMCS *_HIGH enumerators
5: use cached "current" where available
Signed-off-by: Jan Beulich <jbeulich@suse.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 1/5] VMX: dump full guest state
2015-01-20 10:58 [PATCH 0/5] VMX: assorted adjustments Jan Beulich
@ 2015-01-20 11:05 ` Jan Beulich
2015-01-20 17:03 ` Andrew Cooper
2015-01-22 4:40 ` Tian, Kevin
2015-01-20 11:06 ` [PATCH 2/5] VMX: dump full host state Jan Beulich
` (3 subsequent siblings)
4 siblings, 2 replies; 20+ messages in thread
From: Jan Beulich @ 2015-01-20 11:05 UTC (permalink / raw)
To: xen-devel; +Cc: Kevin Tian, Eddie Dong, Jun Nakajima
[-- Attachment #1: Type: text/plain, Size: 13295 bytes --]
Several guest state fields did not get dumped so far. Where suitable
(to reduce the amount of output) make some of the dumping conditional
upon guest settings (this isn't required for correctness as vmr()
already uses __vmread_safe(), i.e. it is fine to access non-existing
fields).
Move CR3_TARGET_* and TSC_OFFSET processing into the control state
section, at once making the upper bound of CR3_TARGET_VALUEn printed
depend on CR3_TARGET_COUNT (which architecturally can be higher than
4).
Also rename GUEST_PDPTRn to GUEST_PDPTEn (matching the SDM naming) and
group them as well as CR3_TARGET_VALUEn similar to EOI_EXIT_BITMAP.
Finally, drop casts - they haven't been needed anymore since the
dropping of 32-bit support (and some of them were not really needed in
the first place). Introduce vmr16() and vmr32() helper macros to avoid
the "l" printk format modifier and at the same time validate that only
16-/32-bit fields get accessed this way.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
Is cpu_has_vmx_pat properly defined? Shouldn't this take into
consideration all three respective flags (VM_EXIT_SAVE_GUEST_PAT,
VM_EXIT_LOAD_HOST_PAT, and VM_ENTRY_LOAD_GUEST_PAT)?
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1395,6 +1395,16 @@ static inline unsigned long vmr(unsigned
return __vmread_safe(field, &val) ? val : 0;
}
+#define vmr16(fld) ({ \
+ BUILD_BUG_ON((fld) & 0x6001); \
+ (uint16_t)vmr(fld); \
+})
+
+#define vmr32(fld) ({ \
+ BUILD_BUG_ON(((fld) & 0x6001) != 0x4000); \
+ (uint16_t)vmr(fld); \
+})
+
static void vmx_dump_sel(char *name, uint32_t selector)
{
uint32_t sel, attr, limit;
@@ -1420,44 +1430,45 @@ static void vmx_dump_sel2(char *name, ui
void vmcs_dump_vcpu(struct vcpu *v)
{
struct cpu_user_regs *regs = &v->arch.user_regs;
- unsigned long long x;
+ uint32_t vmentry_ctl, vmexit_ctl;
+ unsigned long cr4;
+ uint64_t efer;
+ unsigned int i, n;
if ( v == current )
regs = guest_cpu_user_regs();
vmx_vmcs_enter(v);
+ vmentry_ctl = vmr32(VM_ENTRY_CONTROLS),
+ vmexit_ctl = vmr32(VM_EXIT_CONTROLS);
+ cr4 = vmr(GUEST_CR4);
+ efer = vmr(GUEST_EFER);
+
printk("*** Guest State ***\n");
- printk("CR0: actual=0x%016llx, shadow=0x%016llx, gh_mask=%016llx\n",
- (unsigned long long)vmr(GUEST_CR0),
- (unsigned long long)vmr(CR0_READ_SHADOW),
- (unsigned long long)vmr(CR0_GUEST_HOST_MASK));
- printk("CR4: actual=0x%016llx, shadow=0x%016llx, gh_mask=%016llx\n",
- (unsigned long long)vmr(GUEST_CR4),
- (unsigned long long)vmr(CR4_READ_SHADOW),
- (unsigned long long)vmr(CR4_GUEST_HOST_MASK));
- printk("CR3: actual=0x%016llx, target_count=%d\n",
- (unsigned long long)vmr(GUEST_CR3),
- (int)vmr(CR3_TARGET_COUNT));
- printk(" target0=%016llx, target1=%016llx\n",
- (unsigned long long)vmr(CR3_TARGET_VALUE0),
- (unsigned long long)vmr(CR3_TARGET_VALUE1));
- printk(" target2=%016llx, target3=%016llx\n",
- (unsigned long long)vmr(CR3_TARGET_VALUE2),
- (unsigned long long)vmr(CR3_TARGET_VALUE3));
- printk("RSP = 0x%016llx (0x%016llx) RIP = 0x%016llx (0x%016llx)\n",
- (unsigned long long)vmr(GUEST_RSP),
- (unsigned long long)regs->esp,
- (unsigned long long)vmr(GUEST_RIP),
- (unsigned long long)regs->eip);
- printk("RFLAGS=0x%016llx (0x%016llx) DR7 = 0x%016llx\n",
- (unsigned long long)vmr(GUEST_RFLAGS),
- (unsigned long long)regs->eflags,
- (unsigned long long)vmr(GUEST_DR7));
- printk("Sysenter RSP=%016llx CS:RIP=%04x:%016llx\n",
- (unsigned long long)vmr(GUEST_SYSENTER_ESP),
- (int)vmr(GUEST_SYSENTER_CS),
- (unsigned long long)vmr(GUEST_SYSENTER_EIP));
+ printk("CR0: actual=0x%016lx, shadow=0x%016lx, gh_mask=%016lx\n",
+ vmr(GUEST_CR0), vmr(CR0_READ_SHADOW), vmr(CR0_GUEST_HOST_MASK));
+ printk("CR4: actual=0x%016lx, shadow=0x%016lx, gh_mask=%016lx\n",
+ cr4, vmr(CR4_READ_SHADOW), vmr(CR4_GUEST_HOST_MASK));
+ printk("CR3 = 0x%016lx\n", vmr(GUEST_CR3));
+ if ( (v->arch.hvm_vmx.secondary_exec_control &
+ SECONDARY_EXEC_ENABLE_EPT) &&
+ (cr4 & X86_CR4_PAE) && !(efer & EFER_LMA) )
+ {
+ printk("PDPTE0 = 0x%016lx PDPTE1 = 0x%016lx\n",
+ vmr(GUEST_PDPTE(0)), vmr(GUEST_PDPTE(1)));
+ printk("PDPTE2 = 0x%016lx PDPTE3 = 0x%016lx\n",
+ vmr(GUEST_PDPTE(2)), vmr(GUEST_PDPTE(3)));
+ }
+ printk("RSP = 0x%016lx (0x%016lx) RIP = 0x%016lx (0x%016lx)\n",
+ vmr(GUEST_RSP), regs->esp,
+ vmr(GUEST_RIP), regs->eip);
+ printk("RFLAGS=0x%08lx (0x%08lx) DR7 = 0x%016lx\n",
+ vmr(GUEST_RFLAGS), regs->eflags,
+ vmr(GUEST_DR7));
+ printk("Sysenter RSP=%016lx CS:RIP=%04x:%016lx\n",
+ vmr(GUEST_SYSENTER_ESP),
+ vmr32(GUEST_SYSENTER_CS), vmr(GUEST_SYSENTER_EIP));
vmx_dump_sel("CS", GUEST_CS_SELECTOR);
vmx_dump_sel("DS", GUEST_DS_SELECTOR);
vmx_dump_sel("SS", GUEST_SS_SELECTOR);
@@ -1468,18 +1479,21 @@ void vmcs_dump_vcpu(struct vcpu *v)
vmx_dump_sel("LDTR", GUEST_LDTR_SELECTOR);
vmx_dump_sel2("IDTR", GUEST_IDTR_LIMIT);
vmx_dump_sel("TR", GUEST_TR_SELECTOR);
- printk("Guest PAT = 0x%08x%08x\n",
- (uint32_t)vmr(GUEST_PAT_HIGH), (uint32_t)vmr(GUEST_PAT));
- x = (unsigned long long)vmr(TSC_OFFSET_HIGH) << 32;
- x |= (uint32_t)vmr(TSC_OFFSET);
- printk("TSC Offset = %016llx\n", x);
- x = (unsigned long long)vmr(GUEST_IA32_DEBUGCTL_HIGH) << 32;
- x |= (uint32_t)vmr(GUEST_IA32_DEBUGCTL);
- printk("DebugCtl=%016llx DebugExceptions=%016llx\n", x,
- (unsigned long long)vmr(GUEST_PENDING_DBG_EXCEPTIONS));
- printk("Interruptibility=%04x ActivityState=%04x\n",
- (int)vmr(GUEST_INTERRUPTIBILITY_INFO),
- (int)vmr(GUEST_ACTIVITY_STATE));
+ if ( (vmexit_ctl & (VM_EXIT_SAVE_GUEST_PAT | VM_EXIT_SAVE_GUEST_EFER)) ||
+ (vmentry_ctl & (VM_ENTRY_LOAD_GUEST_PAT | VM_ENTRY_LOAD_GUEST_EFER)) )
+ printk("EFER = 0x%016lx PAT = 0x%016lx\n", efer, vmr(GUEST_PAT));
+ printk("PreemptionTimer = 0x%08x SM Base = 0x%08x\n",
+ vmr32(GUEST_PREEMPTION_TIMER), vmr32(GUEST_SMBASE));
+ printk("DebugCtl = 0x%016lx DebugExceptions = 0x%016lx\n",
+ vmr(GUEST_IA32_DEBUGCTL), vmr(GUEST_PENDING_DBG_EXCEPTIONS));
+ if ( vmentry_ctl & (VM_ENTRY_LOAD_PERF_GLOBAL_CTRL | VM_ENTRY_LOAD_BNDCFGS) )
+ printk("PerfGlobCtl = 0x%016lx BndCfgS = 0x%016lx\n",
+ vmr(GUEST_PERF_GLOBAL_CTRL), vmr(GUEST_BNDCFGS));
+ printk("Interruptibility = %08x ActivityState = %08x\n",
+ vmr32(GUEST_INTERRUPTIBILITY_INFO), vmr32(GUEST_ACTIVITY_STATE));
+ if ( v->arch.hvm_vmx.secondary_exec_control &
+ SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY )
+ printk("InterruptStatus = %04x\n", vmr16(GUEST_INTR_STATUS));
printk("*** Host State ***\n");
printk("RSP = 0x%016llx RIP = 0x%016llx\n",
@@ -1516,9 +1530,7 @@ void vmcs_dump_vcpu(struct vcpu *v)
(uint32_t)vmr(PIN_BASED_VM_EXEC_CONTROL),
(uint32_t)vmr(CPU_BASED_VM_EXEC_CONTROL),
(uint32_t)vmr(SECONDARY_VM_EXEC_CONTROL));
- printk("EntryControls=%08x ExitControls=%08x\n",
- (uint32_t)vmr(VM_ENTRY_CONTROLS),
- (uint32_t)vmr(VM_EXIT_CONTROLS));
+ printk("EntryControls=%08x ExitControls=%08x\n", vmentry_ctl, vmexit_ctl);
printk("ExceptionBitmap=%08x\n",
(uint32_t)vmr(EXCEPTION_BITMAP));
printk("VMEntry: intr_info=%08x errcode=%08x ilen=%08x\n",
@@ -1537,8 +1549,16 @@ void vmcs_dump_vcpu(struct vcpu *v)
(uint32_t)vmr(IDT_VECTORING_ERROR_CODE));
printk("TPR Threshold = 0x%02x\n",
(uint32_t)vmr(TPR_THRESHOLD));
+ printk("TSC Offset = 0x%016lx\n", vmr(TSC_OFFSET));
printk("EPT pointer = 0x%08x%08x\n",
(uint32_t)vmr(EPT_POINTER_HIGH), (uint32_t)vmr(EPT_POINTER));
+ n = vmr32(CR3_TARGET_COUNT);
+ for ( i = 0; i + 1 < n; i += 2 )
+ printk("CR3 target%u=%016lx target%u=%016lx\n",
+ i, vmr(CR3_TARGET_VALUE(i)),
+ i + 1, vmr(CR3_TARGET_VALUE(i + 1)));
+ if ( i < n )
+ printk("CR3 target%u=%016lx\n", i, vmr(CR3_TARGET_VALUE(i)));
printk("Virtual processor ID = 0x%04x\n",
(uint32_t)vmr(VIRTUAL_PROCESSOR_ID));
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -1129,7 +1129,7 @@ static void vmx_set_interrupt_shadow(str
static void vmx_load_pdptrs(struct vcpu *v)
{
unsigned long cr3 = v->arch.hvm_vcpu.guest_cr[3];
- uint64_t *guest_pdptrs;
+ uint64_t *guest_pdptes;
struct page_info *page;
p2m_type_t p2mt;
char *p;
@@ -1155,7 +1155,7 @@ static void vmx_load_pdptrs(struct vcpu
p = __map_domain_page(page);
- guest_pdptrs = (uint64_t *)(p + (cr3 & ~PAGE_MASK));
+ guest_pdptes = (uint64_t *)(p + (cr3 & ~PAGE_MASK));
/*
* We do not check the PDPTRs for validity. The CPU will do this during
@@ -1165,10 +1165,10 @@ static void vmx_load_pdptrs(struct vcpu
vmx_vmcs_enter(v);
- __vmwrite(GUEST_PDPTR0, guest_pdptrs[0]);
- __vmwrite(GUEST_PDPTR1, guest_pdptrs[1]);
- __vmwrite(GUEST_PDPTR2, guest_pdptrs[2]);
- __vmwrite(GUEST_PDPTR3, guest_pdptrs[3]);
+ __vmwrite(GUEST_PDPTE(0), guest_pdptes[0]);
+ __vmwrite(GUEST_PDPTE(1), guest_pdptes[1]);
+ __vmwrite(GUEST_PDPTE(2), guest_pdptes[2]);
+ __vmwrite(GUEST_PDPTE(3), guest_pdptes[3]);
vmx_vmcs_exit(v);
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -881,11 +881,11 @@ static const u16 vmcs_gstate_field[] = {
GUEST_SYSENTER_EIP,
};
-static const u16 gpdptr_fields[] = {
- GUEST_PDPTR0,
- GUEST_PDPTR1,
- GUEST_PDPTR2,
- GUEST_PDPTR3,
+static const u16 gpdpte_fields[] = {
+ GUEST_PDPTE(0),
+ GUEST_PDPTE(1),
+ GUEST_PDPTE(2),
+ GUEST_PDPTE(3),
};
/*
@@ -1173,7 +1173,7 @@ static void virtual_vmentry(struct cpu_u
if ( nvmx_ept_enabled(v) && hvm_pae_enabled(v) &&
!(v->arch.hvm_vcpu.guest_efer & EFER_LMA) )
- vvmcs_to_shadow_bulk(v, ARRAY_SIZE(gpdptr_fields), gpdptr_fields);
+ vvmcs_to_shadow_bulk(v, ARRAY_SIZE(gpdpte_fields), gpdpte_fields);
regs->eip = __get_vvmcs(vvmcs, GUEST_RIP);
regs->esp = __get_vvmcs(vvmcs, GUEST_RSP);
@@ -1348,7 +1348,7 @@ static void virtual_vmexit(struct cpu_us
if ( nvmx_ept_enabled(v) && hvm_pae_enabled(v) &&
!(v->arch.hvm_vcpu.guest_efer & EFER_LMA) )
- shadow_to_vvmcs_bulk(v, ARRAY_SIZE(gpdptr_fields), gpdptr_fields);
+ shadow_to_vvmcs_bulk(v, ARRAY_SIZE(gpdpte_fields), gpdpte_fields);
vmx_vmcs_switch(v->arch.hvm_vmx.vmcs, nvcpu->nv_n1vmcx);
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -362,14 +362,8 @@ enum vmcs_field {
GUEST_EFER_HIGH = 0x00002807,
GUEST_PERF_GLOBAL_CTRL = 0x00002808,
GUEST_PERF_GLOBAL_CTRL_HIGH = 0x00002809,
- GUEST_PDPTR0 = 0x0000280a,
- GUEST_PDPTR0_HIGH = 0x0000280b,
- GUEST_PDPTR1 = 0x0000280c,
- GUEST_PDPTR1_HIGH = 0x0000280d,
- GUEST_PDPTR2 = 0x0000280e,
- GUEST_PDPTR2_HIGH = 0x0000280f,
- GUEST_PDPTR3 = 0x00002810,
- GUEST_PDPTR3_HIGH = 0x00002811,
+ GUEST_PDPTE0 = 0x0000280a,
+#define GUEST_PDPTE(n) (GUEST_PDPTE0 + (n) * 2) /* n = 0...3 */
GUEST_BNDCFGS = 0x00002812,
GUEST_BNDCFGS_HIGH = 0x00002813,
HOST_PAT = 0x00002c00,
@@ -424,7 +418,8 @@ enum vmcs_field {
GUEST_TR_AR_BYTES = 0x00004822,
GUEST_INTERRUPTIBILITY_INFO = 0x00004824,
GUEST_ACTIVITY_STATE = 0x00004826,
- GUEST_SYSENTER_CS = 0x0000482A,
+ GUEST_SMBASE = 0x00004828,
+ GUEST_SYSENTER_CS = 0x0000482a,
GUEST_PREEMPTION_TIMER = 0x0000482e,
HOST_SYSENTER_CS = 0x00004c00,
CR0_GUEST_HOST_MASK = 0x00006000,
@@ -432,9 +427,7 @@ enum vmcs_field {
CR0_READ_SHADOW = 0x00006004,
CR4_READ_SHADOW = 0x00006006,
CR3_TARGET_VALUE0 = 0x00006008,
- CR3_TARGET_VALUE1 = 0x0000600a,
- CR3_TARGET_VALUE2 = 0x0000600c,
- CR3_TARGET_VALUE3 = 0x0000600e,
+#define CR3_TARGET_VALUE(n) (CR3_TARGET_VALUE0 + (n) * 2) /* n < CR3_TARGET_COUNT */
EXIT_QUALIFICATION = 0x00006400,
GUEST_LINEAR_ADDRESS = 0x0000640a,
GUEST_CR0 = 0x00006800,
[-- Attachment #2: VMX-dump-guest-state.patch --]
[-- Type: text/plain, Size: 13321 bytes --]
VMX: dump full guest state
Several guest state fields did not get dumped so far. Where suitable
(to reduce the amount of output) make some of the dumping conditional
upon guest settings (this isn't required for correctness as vmr()
already uses __vmread_safe(), i.e. it is fine to access non-existing
fields).
Move CR3_TARGET_* and TSC_OFFSET processing into the control state
section, at once making the upper bound of CR3_TARGET_VALUEn printed
depend on CR3_TARGET_COUNT (which architecturally can be higher than
4).
Also rename GUEST_PDPTRn to GUEST_PDPTEn (matching the SDM naming) and
group them as well as CR3_TARGET_VALUEn similar to EOI_EXIT_BITMAP.
Finally, drop casts - they haven't been needed anymore since the
dropping of 32-bit support (and some of them were not really needed in
the first place). Introduce vmr16() and vmr32() helper macros to avoid
the "l" printk format modifier and at the same time validate that only
16-/32-bit fields get accessed this way.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
Is cpu_has_vmx_pat properly defined? Shouldn't this take into
consideration all three respective flags (VM_EXIT_SAVE_GUEST_PAT,
VM_EXIT_LOAD_HOST_PAT, and VM_ENTRY_LOAD_GUEST_PAT)?
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1395,6 +1395,16 @@ static inline unsigned long vmr(unsigned
return __vmread_safe(field, &val) ? val : 0;
}
+#define vmr16(fld) ({ \
+ BUILD_BUG_ON((fld) & 0x6001); \
+ (uint16_t)vmr(fld); \
+})
+
+#define vmr32(fld) ({ \
+ BUILD_BUG_ON(((fld) & 0x6001) != 0x4000); \
+ (uint16_t)vmr(fld); \
+})
+
static void vmx_dump_sel(char *name, uint32_t selector)
{
uint32_t sel, attr, limit;
@@ -1420,44 +1430,45 @@ static void vmx_dump_sel2(char *name, ui
void vmcs_dump_vcpu(struct vcpu *v)
{
struct cpu_user_regs *regs = &v->arch.user_regs;
- unsigned long long x;
+ uint32_t vmentry_ctl, vmexit_ctl;
+ unsigned long cr4;
+ uint64_t efer;
+ unsigned int i, n;
if ( v == current )
regs = guest_cpu_user_regs();
vmx_vmcs_enter(v);
+ vmentry_ctl = vmr32(VM_ENTRY_CONTROLS),
+ vmexit_ctl = vmr32(VM_EXIT_CONTROLS);
+ cr4 = vmr(GUEST_CR4);
+ efer = vmr(GUEST_EFER);
+
printk("*** Guest State ***\n");
- printk("CR0: actual=0x%016llx, shadow=0x%016llx, gh_mask=%016llx\n",
- (unsigned long long)vmr(GUEST_CR0),
- (unsigned long long)vmr(CR0_READ_SHADOW),
- (unsigned long long)vmr(CR0_GUEST_HOST_MASK));
- printk("CR4: actual=0x%016llx, shadow=0x%016llx, gh_mask=%016llx\n",
- (unsigned long long)vmr(GUEST_CR4),
- (unsigned long long)vmr(CR4_READ_SHADOW),
- (unsigned long long)vmr(CR4_GUEST_HOST_MASK));
- printk("CR3: actual=0x%016llx, target_count=%d\n",
- (unsigned long long)vmr(GUEST_CR3),
- (int)vmr(CR3_TARGET_COUNT));
- printk(" target0=%016llx, target1=%016llx\n",
- (unsigned long long)vmr(CR3_TARGET_VALUE0),
- (unsigned long long)vmr(CR3_TARGET_VALUE1));
- printk(" target2=%016llx, target3=%016llx\n",
- (unsigned long long)vmr(CR3_TARGET_VALUE2),
- (unsigned long long)vmr(CR3_TARGET_VALUE3));
- printk("RSP = 0x%016llx (0x%016llx) RIP = 0x%016llx (0x%016llx)\n",
- (unsigned long long)vmr(GUEST_RSP),
- (unsigned long long)regs->esp,
- (unsigned long long)vmr(GUEST_RIP),
- (unsigned long long)regs->eip);
- printk("RFLAGS=0x%016llx (0x%016llx) DR7 = 0x%016llx\n",
- (unsigned long long)vmr(GUEST_RFLAGS),
- (unsigned long long)regs->eflags,
- (unsigned long long)vmr(GUEST_DR7));
- printk("Sysenter RSP=%016llx CS:RIP=%04x:%016llx\n",
- (unsigned long long)vmr(GUEST_SYSENTER_ESP),
- (int)vmr(GUEST_SYSENTER_CS),
- (unsigned long long)vmr(GUEST_SYSENTER_EIP));
+ printk("CR0: actual=0x%016lx, shadow=0x%016lx, gh_mask=%016lx\n",
+ vmr(GUEST_CR0), vmr(CR0_READ_SHADOW), vmr(CR0_GUEST_HOST_MASK));
+ printk("CR4: actual=0x%016lx, shadow=0x%016lx, gh_mask=%016lx\n",
+ cr4, vmr(CR4_READ_SHADOW), vmr(CR4_GUEST_HOST_MASK));
+ printk("CR3 = 0x%016lx\n", vmr(GUEST_CR3));
+ if ( (v->arch.hvm_vmx.secondary_exec_control &
+ SECONDARY_EXEC_ENABLE_EPT) &&
+ (cr4 & X86_CR4_PAE) && !(efer & EFER_LMA) )
+ {
+ printk("PDPTE0 = 0x%016lx PDPTE1 = 0x%016lx\n",
+ vmr(GUEST_PDPTE(0)), vmr(GUEST_PDPTE(1)));
+ printk("PDPTE2 = 0x%016lx PDPTE3 = 0x%016lx\n",
+ vmr(GUEST_PDPTE(2)), vmr(GUEST_PDPTE(3)));
+ }
+ printk("RSP = 0x%016lx (0x%016lx) RIP = 0x%016lx (0x%016lx)\n",
+ vmr(GUEST_RSP), regs->esp,
+ vmr(GUEST_RIP), regs->eip);
+ printk("RFLAGS=0x%08lx (0x%08lx) DR7 = 0x%016lx\n",
+ vmr(GUEST_RFLAGS), regs->eflags,
+ vmr(GUEST_DR7));
+ printk("Sysenter RSP=%016lx CS:RIP=%04x:%016lx\n",
+ vmr(GUEST_SYSENTER_ESP),
+ vmr32(GUEST_SYSENTER_CS), vmr(GUEST_SYSENTER_EIP));
vmx_dump_sel("CS", GUEST_CS_SELECTOR);
vmx_dump_sel("DS", GUEST_DS_SELECTOR);
vmx_dump_sel("SS", GUEST_SS_SELECTOR);
@@ -1468,18 +1479,21 @@ void vmcs_dump_vcpu(struct vcpu *v)
vmx_dump_sel("LDTR", GUEST_LDTR_SELECTOR);
vmx_dump_sel2("IDTR", GUEST_IDTR_LIMIT);
vmx_dump_sel("TR", GUEST_TR_SELECTOR);
- printk("Guest PAT = 0x%08x%08x\n",
- (uint32_t)vmr(GUEST_PAT_HIGH), (uint32_t)vmr(GUEST_PAT));
- x = (unsigned long long)vmr(TSC_OFFSET_HIGH) << 32;
- x |= (uint32_t)vmr(TSC_OFFSET);
- printk("TSC Offset = %016llx\n", x);
- x = (unsigned long long)vmr(GUEST_IA32_DEBUGCTL_HIGH) << 32;
- x |= (uint32_t)vmr(GUEST_IA32_DEBUGCTL);
- printk("DebugCtl=%016llx DebugExceptions=%016llx\n", x,
- (unsigned long long)vmr(GUEST_PENDING_DBG_EXCEPTIONS));
- printk("Interruptibility=%04x ActivityState=%04x\n",
- (int)vmr(GUEST_INTERRUPTIBILITY_INFO),
- (int)vmr(GUEST_ACTIVITY_STATE));
+ if ( (vmexit_ctl & (VM_EXIT_SAVE_GUEST_PAT | VM_EXIT_SAVE_GUEST_EFER)) ||
+ (vmentry_ctl & (VM_ENTRY_LOAD_GUEST_PAT | VM_ENTRY_LOAD_GUEST_EFER)) )
+ printk("EFER = 0x%016lx PAT = 0x%016lx\n", efer, vmr(GUEST_PAT));
+ printk("PreemptionTimer = 0x%08x SM Base = 0x%08x\n",
+ vmr32(GUEST_PREEMPTION_TIMER), vmr32(GUEST_SMBASE));
+ printk("DebugCtl = 0x%016lx DebugExceptions = 0x%016lx\n",
+ vmr(GUEST_IA32_DEBUGCTL), vmr(GUEST_PENDING_DBG_EXCEPTIONS));
+ if ( vmentry_ctl & (VM_ENTRY_LOAD_PERF_GLOBAL_CTRL | VM_ENTRY_LOAD_BNDCFGS) )
+ printk("PerfGlobCtl = 0x%016lx BndCfgS = 0x%016lx\n",
+ vmr(GUEST_PERF_GLOBAL_CTRL), vmr(GUEST_BNDCFGS));
+ printk("Interruptibility = %08x ActivityState = %08x\n",
+ vmr32(GUEST_INTERRUPTIBILITY_INFO), vmr32(GUEST_ACTIVITY_STATE));
+ if ( v->arch.hvm_vmx.secondary_exec_control &
+ SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY )
+ printk("InterruptStatus = %04x\n", vmr16(GUEST_INTR_STATUS));
printk("*** Host State ***\n");
printk("RSP = 0x%016llx RIP = 0x%016llx\n",
@@ -1516,9 +1530,7 @@ void vmcs_dump_vcpu(struct vcpu *v)
(uint32_t)vmr(PIN_BASED_VM_EXEC_CONTROL),
(uint32_t)vmr(CPU_BASED_VM_EXEC_CONTROL),
(uint32_t)vmr(SECONDARY_VM_EXEC_CONTROL));
- printk("EntryControls=%08x ExitControls=%08x\n",
- (uint32_t)vmr(VM_ENTRY_CONTROLS),
- (uint32_t)vmr(VM_EXIT_CONTROLS));
+ printk("EntryControls=%08x ExitControls=%08x\n", vmentry_ctl, vmexit_ctl);
printk("ExceptionBitmap=%08x\n",
(uint32_t)vmr(EXCEPTION_BITMAP));
printk("VMEntry: intr_info=%08x errcode=%08x ilen=%08x\n",
@@ -1537,8 +1549,16 @@ void vmcs_dump_vcpu(struct vcpu *v)
(uint32_t)vmr(IDT_VECTORING_ERROR_CODE));
printk("TPR Threshold = 0x%02x\n",
(uint32_t)vmr(TPR_THRESHOLD));
+ printk("TSC Offset = 0x%016lx\n", vmr(TSC_OFFSET));
printk("EPT pointer = 0x%08x%08x\n",
(uint32_t)vmr(EPT_POINTER_HIGH), (uint32_t)vmr(EPT_POINTER));
+ n = vmr32(CR3_TARGET_COUNT);
+ for ( i = 0; i + 1 < n; i += 2 )
+ printk("CR3 target%u=%016lx target%u=%016lx\n",
+ i, vmr(CR3_TARGET_VALUE(i)),
+ i + 1, vmr(CR3_TARGET_VALUE(i + 1)));
+ if ( i < n )
+ printk("CR3 target%u=%016lx\n", i, vmr(CR3_TARGET_VALUE(i)));
printk("Virtual processor ID = 0x%04x\n",
(uint32_t)vmr(VIRTUAL_PROCESSOR_ID));
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -1129,7 +1129,7 @@ static void vmx_set_interrupt_shadow(str
static void vmx_load_pdptrs(struct vcpu *v)
{
unsigned long cr3 = v->arch.hvm_vcpu.guest_cr[3];
- uint64_t *guest_pdptrs;
+ uint64_t *guest_pdptes;
struct page_info *page;
p2m_type_t p2mt;
char *p;
@@ -1155,7 +1155,7 @@ static void vmx_load_pdptrs(struct vcpu
p = __map_domain_page(page);
- guest_pdptrs = (uint64_t *)(p + (cr3 & ~PAGE_MASK));
+ guest_pdptes = (uint64_t *)(p + (cr3 & ~PAGE_MASK));
/*
* We do not check the PDPTRs for validity. The CPU will do this during
@@ -1165,10 +1165,10 @@ static void vmx_load_pdptrs(struct vcpu
vmx_vmcs_enter(v);
- __vmwrite(GUEST_PDPTR0, guest_pdptrs[0]);
- __vmwrite(GUEST_PDPTR1, guest_pdptrs[1]);
- __vmwrite(GUEST_PDPTR2, guest_pdptrs[2]);
- __vmwrite(GUEST_PDPTR3, guest_pdptrs[3]);
+ __vmwrite(GUEST_PDPTE(0), guest_pdptes[0]);
+ __vmwrite(GUEST_PDPTE(1), guest_pdptes[1]);
+ __vmwrite(GUEST_PDPTE(2), guest_pdptes[2]);
+ __vmwrite(GUEST_PDPTE(3), guest_pdptes[3]);
vmx_vmcs_exit(v);
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -881,11 +881,11 @@ static const u16 vmcs_gstate_field[] = {
GUEST_SYSENTER_EIP,
};
-static const u16 gpdptr_fields[] = {
- GUEST_PDPTR0,
- GUEST_PDPTR1,
- GUEST_PDPTR2,
- GUEST_PDPTR3,
+static const u16 gpdpte_fields[] = {
+ GUEST_PDPTE(0),
+ GUEST_PDPTE(1),
+ GUEST_PDPTE(2),
+ GUEST_PDPTE(3),
};
/*
@@ -1173,7 +1173,7 @@ static void virtual_vmentry(struct cpu_u
if ( nvmx_ept_enabled(v) && hvm_pae_enabled(v) &&
!(v->arch.hvm_vcpu.guest_efer & EFER_LMA) )
- vvmcs_to_shadow_bulk(v, ARRAY_SIZE(gpdptr_fields), gpdptr_fields);
+ vvmcs_to_shadow_bulk(v, ARRAY_SIZE(gpdpte_fields), gpdpte_fields);
regs->eip = __get_vvmcs(vvmcs, GUEST_RIP);
regs->esp = __get_vvmcs(vvmcs, GUEST_RSP);
@@ -1348,7 +1348,7 @@ static void virtual_vmexit(struct cpu_us
if ( nvmx_ept_enabled(v) && hvm_pae_enabled(v) &&
!(v->arch.hvm_vcpu.guest_efer & EFER_LMA) )
- shadow_to_vvmcs_bulk(v, ARRAY_SIZE(gpdptr_fields), gpdptr_fields);
+ shadow_to_vvmcs_bulk(v, ARRAY_SIZE(gpdpte_fields), gpdpte_fields);
vmx_vmcs_switch(v->arch.hvm_vmx.vmcs, nvcpu->nv_n1vmcx);
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -362,14 +362,8 @@ enum vmcs_field {
GUEST_EFER_HIGH = 0x00002807,
GUEST_PERF_GLOBAL_CTRL = 0x00002808,
GUEST_PERF_GLOBAL_CTRL_HIGH = 0x00002809,
- GUEST_PDPTR0 = 0x0000280a,
- GUEST_PDPTR0_HIGH = 0x0000280b,
- GUEST_PDPTR1 = 0x0000280c,
- GUEST_PDPTR1_HIGH = 0x0000280d,
- GUEST_PDPTR2 = 0x0000280e,
- GUEST_PDPTR2_HIGH = 0x0000280f,
- GUEST_PDPTR3 = 0x00002810,
- GUEST_PDPTR3_HIGH = 0x00002811,
+ GUEST_PDPTE0 = 0x0000280a,
+#define GUEST_PDPTE(n) (GUEST_PDPTE0 + (n) * 2) /* n = 0...3 */
GUEST_BNDCFGS = 0x00002812,
GUEST_BNDCFGS_HIGH = 0x00002813,
HOST_PAT = 0x00002c00,
@@ -424,7 +418,8 @@ enum vmcs_field {
GUEST_TR_AR_BYTES = 0x00004822,
GUEST_INTERRUPTIBILITY_INFO = 0x00004824,
GUEST_ACTIVITY_STATE = 0x00004826,
- GUEST_SYSENTER_CS = 0x0000482A,
+ GUEST_SMBASE = 0x00004828,
+ GUEST_SYSENTER_CS = 0x0000482a,
GUEST_PREEMPTION_TIMER = 0x0000482e,
HOST_SYSENTER_CS = 0x00004c00,
CR0_GUEST_HOST_MASK = 0x00006000,
@@ -432,9 +427,7 @@ enum vmcs_field {
CR0_READ_SHADOW = 0x00006004,
CR4_READ_SHADOW = 0x00006006,
CR3_TARGET_VALUE0 = 0x00006008,
- CR3_TARGET_VALUE1 = 0x0000600a,
- CR3_TARGET_VALUE2 = 0x0000600c,
- CR3_TARGET_VALUE3 = 0x0000600e,
+#define CR3_TARGET_VALUE(n) (CR3_TARGET_VALUE0 + (n) * 2) /* n < CR3_TARGET_COUNT */
EXIT_QUALIFICATION = 0x00006400,
GUEST_LINEAR_ADDRESS = 0x0000640a,
GUEST_CR0 = 0x00006800,
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 2/5] VMX: dump full host state
2015-01-20 10:58 [PATCH 0/5] VMX: assorted adjustments Jan Beulich
2015-01-20 11:05 ` [PATCH 1/5] VMX: dump full guest state Jan Beulich
@ 2015-01-20 11:06 ` Jan Beulich
2015-01-20 17:19 ` Andrew Cooper
2015-01-22 4:40 ` Tian, Kevin
2015-01-20 11:06 ` [PATCH 3/5] VMX: dump further control state Jan Beulich
` (2 subsequent siblings)
4 siblings, 2 replies; 20+ messages in thread
From: Jan Beulich @ 2015-01-20 11:06 UTC (permalink / raw)
To: xen-devel; +Cc: Kevin Tian, Eddie Dong, Jun Nakajima
[-- Attachment #1: Type: text/plain, Size: 3478 bytes --]
A few host state fields did not get dumped so far. Where suitable (to
reduce the amount of output) make some of the dumping conditional upon
guest settings (this isn't required for correctness as vmr() already
uses __vmread_safe(), i.e. it is fine to access non-existing fields).
Also drop casts - many of them haven't been needed anymore since the
dropping of 32-bit support.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1496,34 +1496,27 @@ void vmcs_dump_vcpu(struct vcpu *v)
printk("InterruptStatus = %04x\n", vmr16(GUEST_INTR_STATUS));
printk("*** Host State ***\n");
- printk("RSP = 0x%016llx RIP = 0x%016llx\n",
- (unsigned long long)vmr(HOST_RSP),
- (unsigned long long)vmr(HOST_RIP));
- printk("CS=%04x DS=%04x ES=%04x FS=%04x GS=%04x SS=%04x TR=%04x\n",
- (uint16_t)vmr(HOST_CS_SELECTOR),
- (uint16_t)vmr(HOST_DS_SELECTOR),
- (uint16_t)vmr(HOST_ES_SELECTOR),
- (uint16_t)vmr(HOST_FS_SELECTOR),
- (uint16_t)vmr(HOST_GS_SELECTOR),
- (uint16_t)vmr(HOST_SS_SELECTOR),
- (uint16_t)vmr(HOST_TR_SELECTOR));
- printk("FSBase=%016llx GSBase=%016llx TRBase=%016llx\n",
- (unsigned long long)vmr(HOST_FS_BASE),
- (unsigned long long)vmr(HOST_GS_BASE),
- (unsigned long long)vmr(HOST_TR_BASE));
- printk("GDTBase=%016llx IDTBase=%016llx\n",
- (unsigned long long)vmr(HOST_GDTR_BASE),
- (unsigned long long)vmr(HOST_IDTR_BASE));
- printk("CR0=%016llx CR3=%016llx CR4=%016llx\n",
- (unsigned long long)vmr(HOST_CR0),
- (unsigned long long)vmr(HOST_CR3),
- (unsigned long long)vmr(HOST_CR4));
- printk("Sysenter RSP=%016llx CS:RIP=%04x:%016llx\n",
- (unsigned long long)vmr(HOST_SYSENTER_ESP),
- (int)vmr(HOST_SYSENTER_CS),
- (unsigned long long)vmr(HOST_SYSENTER_EIP));
- printk("Host PAT = 0x%08x%08x\n",
- (uint32_t)vmr(HOST_PAT_HIGH), (uint32_t)vmr(HOST_PAT));
+ printk("RIP = 0x%016lx (%ps) RSP = 0x%016lx\n",
+ vmr(HOST_RIP), (void *)vmr(HOST_RIP), vmr(HOST_RSP));
+ printk("CS=%04x SS=%04x DS=%04x ES=%04x FS=%04x GS=%04x TR=%04x\n",
+ vmr16(HOST_CS_SELECTOR), vmr16(HOST_SS_SELECTOR),
+ vmr16(HOST_DS_SELECTOR), vmr16(HOST_ES_SELECTOR),
+ vmr16(HOST_FS_SELECTOR), vmr16(HOST_GS_SELECTOR),
+ vmr16(HOST_TR_SELECTOR));
+ printk("FSBase=%016lx GSBase=%016lx TRBase=%016lx\n",
+ vmr(HOST_FS_BASE), vmr(HOST_GS_BASE), vmr(HOST_TR_BASE));
+ printk("GDTBase=%016lx IDTBase=%016lx\n",
+ vmr(HOST_GDTR_BASE), vmr(HOST_IDTR_BASE));
+ printk("CR0=%016lx CR3=%016lx CR4=%016lx\n",
+ vmr(HOST_CR0), vmr(HOST_CR3), vmr(HOST_CR4));
+ printk("Sysenter RSP=%016lx CS:RIP=%04x:%016lx\n",
+ vmr(HOST_SYSENTER_ESP),
+ vmr32(HOST_SYSENTER_CS), vmr(HOST_SYSENTER_EIP));
+ if ( vmexit_ctl & (VM_EXIT_LOAD_HOST_PAT | VM_EXIT_LOAD_HOST_EFER) )
+ printk("EFER = 0x%016lx PAT = 0x%016lx\n", vmr(HOST_EFER), vmr(HOST_PAT));
+ if ( vmexit_ctl & VM_EXIT_LOAD_PERF_GLOBAL_CTRL )
+ printk("PerfGlobCtl = 0x%016lx\n",
+ vmr(HOST_PERF_GLOBAL_CTRL));
printk("*** Control State ***\n");
printk("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n",
[-- Attachment #2: VMX-dump-host-state.patch --]
[-- Type: text/plain, Size: 3501 bytes --]
VMX: dump full host state
A few host state fields did not get dumped so far. Where suitable (to
reduce the amount of output) make some of the dumping conditional upon
guest settings (this isn't required for correctness as vmr() already
uses __vmread_safe(), i.e. it is fine to access non-existing fields).
Also drop casts - many of them haven't been needed anymore since the
dropping of 32-bit support.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1496,34 +1496,27 @@ void vmcs_dump_vcpu(struct vcpu *v)
printk("InterruptStatus = %04x\n", vmr16(GUEST_INTR_STATUS));
printk("*** Host State ***\n");
- printk("RSP = 0x%016llx RIP = 0x%016llx\n",
- (unsigned long long)vmr(HOST_RSP),
- (unsigned long long)vmr(HOST_RIP));
- printk("CS=%04x DS=%04x ES=%04x FS=%04x GS=%04x SS=%04x TR=%04x\n",
- (uint16_t)vmr(HOST_CS_SELECTOR),
- (uint16_t)vmr(HOST_DS_SELECTOR),
- (uint16_t)vmr(HOST_ES_SELECTOR),
- (uint16_t)vmr(HOST_FS_SELECTOR),
- (uint16_t)vmr(HOST_GS_SELECTOR),
- (uint16_t)vmr(HOST_SS_SELECTOR),
- (uint16_t)vmr(HOST_TR_SELECTOR));
- printk("FSBase=%016llx GSBase=%016llx TRBase=%016llx\n",
- (unsigned long long)vmr(HOST_FS_BASE),
- (unsigned long long)vmr(HOST_GS_BASE),
- (unsigned long long)vmr(HOST_TR_BASE));
- printk("GDTBase=%016llx IDTBase=%016llx\n",
- (unsigned long long)vmr(HOST_GDTR_BASE),
- (unsigned long long)vmr(HOST_IDTR_BASE));
- printk("CR0=%016llx CR3=%016llx CR4=%016llx\n",
- (unsigned long long)vmr(HOST_CR0),
- (unsigned long long)vmr(HOST_CR3),
- (unsigned long long)vmr(HOST_CR4));
- printk("Sysenter RSP=%016llx CS:RIP=%04x:%016llx\n",
- (unsigned long long)vmr(HOST_SYSENTER_ESP),
- (int)vmr(HOST_SYSENTER_CS),
- (unsigned long long)vmr(HOST_SYSENTER_EIP));
- printk("Host PAT = 0x%08x%08x\n",
- (uint32_t)vmr(HOST_PAT_HIGH), (uint32_t)vmr(HOST_PAT));
+ printk("RIP = 0x%016lx (%ps) RSP = 0x%016lx\n",
+ vmr(HOST_RIP), (void *)vmr(HOST_RIP), vmr(HOST_RSP));
+ printk("CS=%04x SS=%04x DS=%04x ES=%04x FS=%04x GS=%04x TR=%04x\n",
+ vmr16(HOST_CS_SELECTOR), vmr16(HOST_SS_SELECTOR),
+ vmr16(HOST_DS_SELECTOR), vmr16(HOST_ES_SELECTOR),
+ vmr16(HOST_FS_SELECTOR), vmr16(HOST_GS_SELECTOR),
+ vmr16(HOST_TR_SELECTOR));
+ printk("FSBase=%016lx GSBase=%016lx TRBase=%016lx\n",
+ vmr(HOST_FS_BASE), vmr(HOST_GS_BASE), vmr(HOST_TR_BASE));
+ printk("GDTBase=%016lx IDTBase=%016lx\n",
+ vmr(HOST_GDTR_BASE), vmr(HOST_IDTR_BASE));
+ printk("CR0=%016lx CR3=%016lx CR4=%016lx\n",
+ vmr(HOST_CR0), vmr(HOST_CR3), vmr(HOST_CR4));
+ printk("Sysenter RSP=%016lx CS:RIP=%04x:%016lx\n",
+ vmr(HOST_SYSENTER_ESP),
+ vmr32(HOST_SYSENTER_CS), vmr(HOST_SYSENTER_EIP));
+ if ( vmexit_ctl & (VM_EXIT_LOAD_HOST_PAT | VM_EXIT_LOAD_HOST_EFER) )
+ printk("EFER = 0x%016lx PAT = 0x%016lx\n", vmr(HOST_EFER), vmr(HOST_PAT));
+ if ( vmexit_ctl & VM_EXIT_LOAD_PERF_GLOBAL_CTRL )
+ printk("PerfGlobCtl = 0x%016lx\n",
+ vmr(HOST_PERF_GLOBAL_CTRL));
printk("*** Control State ***\n");
printk("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n",
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 3/5] VMX: dump further control state
2015-01-20 10:58 [PATCH 0/5] VMX: assorted adjustments Jan Beulich
2015-01-20 11:05 ` [PATCH 1/5] VMX: dump full guest state Jan Beulich
2015-01-20 11:06 ` [PATCH 2/5] VMX: dump full host state Jan Beulich
@ 2015-01-20 11:06 ` Jan Beulich
2015-01-20 17:39 ` Andrew Cooper
2015-01-22 4:41 ` Tian, Kevin
2015-01-20 11:07 ` [PATCH 4/5] VMX: drop VMCS *_HIGH enumerators Jan Beulich
2015-01-20 11:08 ` [PATCH 5/5] VMX: use cached "current" where available Jan Beulich
4 siblings, 2 replies; 20+ messages in thread
From: Jan Beulich @ 2015-01-20 11:06 UTC (permalink / raw)
To: xen-devel; +Cc: Kevin Tian, Eddie Dong, Jun Nakajima
[-- Attachment #1: Type: text/plain, Size: 5589 bytes --]
A few relevant control state fields did not get dumped so far; in
particular, VM_ENTRY_INSTRUCTION_LEN got printed twice (instead of also
printing VM_EXIT_INSTRUCTION_LEN). Where suitable (to reduce the amount
of output) make some of the dumping conditional upon guest settings
(this isn't required for correctness as vmr() already uses
__vmread_safe(), i.e. it is fine to access non-existing fields).
Also drop casts.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1520,31 +1520,35 @@ void vmcs_dump_vcpu(struct vcpu *v)
printk("*** Control State ***\n");
printk("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n",
- (uint32_t)vmr(PIN_BASED_VM_EXEC_CONTROL),
- (uint32_t)vmr(CPU_BASED_VM_EXEC_CONTROL),
- (uint32_t)vmr(SECONDARY_VM_EXEC_CONTROL));
+ vmr32(PIN_BASED_VM_EXEC_CONTROL),
+ vmr32(CPU_BASED_VM_EXEC_CONTROL),
+ vmr32(SECONDARY_VM_EXEC_CONTROL));
printk("EntryControls=%08x ExitControls=%08x\n", vmentry_ctl, vmexit_ctl);
- printk("ExceptionBitmap=%08x\n",
- (uint32_t)vmr(EXCEPTION_BITMAP));
+ printk("ExceptionBitmap=%08x PFECmask=%08x PFECmatch=%08x\n",
+ vmr32(EXCEPTION_BITMAP),
+ vmr32(PAGE_FAULT_ERROR_CODE_MASK),
+ vmr32(PAGE_FAULT_ERROR_CODE_MATCH));
printk("VMEntry: intr_info=%08x errcode=%08x ilen=%08x\n",
- (uint32_t)vmr(VM_ENTRY_INTR_INFO),
- (uint32_t)vmr(VM_ENTRY_EXCEPTION_ERROR_CODE),
- (uint32_t)vmr(VM_ENTRY_INSTRUCTION_LEN));
+ vmr32(VM_ENTRY_INTR_INFO),
+ vmr32(VM_ENTRY_EXCEPTION_ERROR_CODE),
+ vmr32(VM_ENTRY_INSTRUCTION_LEN));
printk("VMExit: intr_info=%08x errcode=%08x ilen=%08x\n",
- (uint32_t)vmr(VM_EXIT_INTR_INFO),
- (uint32_t)vmr(VM_EXIT_INTR_ERROR_CODE),
- (uint32_t)vmr(VM_ENTRY_INSTRUCTION_LEN));
- printk(" reason=%08x qualification=%08x\n",
- (uint32_t)vmr(VM_EXIT_REASON),
- (uint32_t)vmr(EXIT_QUALIFICATION));
+ vmr32(VM_EXIT_INTR_INFO),
+ vmr32(VM_EXIT_INTR_ERROR_CODE),
+ vmr32(VM_EXIT_INSTRUCTION_LEN));
+ printk(" reason=%08x qualification=%016lx\n",
+ vmr32(VM_EXIT_REASON), vmr(EXIT_QUALIFICATION));
printk("IDTVectoring: info=%08x errcode=%08x\n",
- (uint32_t)vmr(IDT_VECTORING_INFO),
- (uint32_t)vmr(IDT_VECTORING_ERROR_CODE));
- printk("TPR Threshold = 0x%02x\n",
- (uint32_t)vmr(TPR_THRESHOLD));
+ vmr32(IDT_VECTORING_INFO), vmr32(IDT_VECTORING_ERROR_CODE));
printk("TSC Offset = 0x%016lx\n", vmr(TSC_OFFSET));
- printk("EPT pointer = 0x%08x%08x\n",
- (uint32_t)vmr(EPT_POINTER_HIGH), (uint32_t)vmr(EPT_POINTER));
+ if ( (v->arch.hvm_vmx.exec_control & CPU_BASED_TPR_SHADOW) ||
+ (vmx_pin_based_exec_control & PIN_BASED_POSTED_INTERRUPT) )
+ printk("TPR Threshold = 0x%02x PostedIntrVec = 0x%02x\n",
+ vmr32(TPR_THRESHOLD), vmr16(POSTED_INTR_NOTIFICATION_VECTOR));
+ if ( (v->arch.hvm_vmx.secondary_exec_control &
+ SECONDARY_EXEC_ENABLE_EPT) )
+ printk("EPT pointer = 0x%016lx EPTP index = 0x%04x\n",
+ vmr(EPT_POINTER), vmr16(EPTP_INDEX));
n = vmr32(CR3_TARGET_COUNT);
for ( i = 0; i + 1 < n; i += 2 )
printk("CR3 target%u=%016lx target%u=%016lx\n",
@@ -1552,8 +1556,14 @@ void vmcs_dump_vcpu(struct vcpu *v)
i + 1, vmr(CR3_TARGET_VALUE(i + 1)));
if ( i < n )
printk("CR3 target%u=%016lx\n", i, vmr(CR3_TARGET_VALUE(i)));
- printk("Virtual processor ID = 0x%04x\n",
- (uint32_t)vmr(VIRTUAL_PROCESSOR_ID));
+ if ( v->arch.hvm_vmx.secondary_exec_control &
+ SECONDARY_EXEC_PAUSE_LOOP_EXITING )
+ printk("PLE Gap=%08x Window=%08x\n",
+ vmr32(PLE_GAP), vmr32(PLE_WINDOW));
+ if ( v->arch.hvm_vmx.secondary_exec_control &
+ (SECONDARY_EXEC_ENABLE_VPID | SECONDARY_EXEC_ENABLE_VMFUNC) )
+ printk("Virtual processor ID = 0x%04x VMfunc controls = %016lx\n",
+ vmr16(VIRTUAL_PROCESSOR_ID), vmr(VMFUNC_CONTROL));
vmx_vmcs_exit(v);
}
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -213,6 +213,7 @@ extern u32 vmx_vmentry_control;
#define SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY 0x00000200
#define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400
#define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000
+#define SECONDARY_EXEC_ENABLE_VMFUNC 0x00002000
#define SECONDARY_EXEC_ENABLE_VMCS_SHADOWING 0x00004000
extern u32 vmx_secondary_exec_control;
@@ -306,6 +307,7 @@ extern u64 vmx_basic_msr;
enum vmcs_field {
VIRTUAL_PROCESSOR_ID = 0x00000000,
POSTED_INTR_NOTIFICATION_VECTOR = 0x00000002,
+ EPTP_INDEX = 0x00000004,
GUEST_ES_SELECTOR = 0x00000800,
GUEST_CS_SELECTOR = 0x00000802,
GUEST_SS_SELECTOR = 0x00000804,
@@ -342,6 +344,7 @@ enum vmcs_field {
APIC_ACCESS_ADDR_HIGH = 0x00002015,
PI_DESC_ADDR = 0x00002016,
PI_DESC_ADDR_HIGH = 0x00002017,
+ VMFUNC_CONTROL = 0x00002018,
EPT_POINTER = 0x0000201a,
EPT_POINTER_HIGH = 0x0000201b,
EOI_EXIT_BITMAP0 = 0x0000201c,
[-- Attachment #2: VMX-dump-control-state.patch --]
[-- Type: text/plain, Size: 5620 bytes --]
VMX: dump further control state
A few relevant control state fields did not get dumped so far; in
particular, VM_ENTRY_INSTRUCTION_LEN got printed twice (instead of also
printing VM_EXIT_INSTRUCTION_LEN). Where suitable (to reduce the amount
of output) make some of the dumping conditional upon guest settings
(this isn't required for correctness as vmr() already uses
__vmread_safe(), i.e. it is fine to access non-existing fields).
Also drop casts.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -1520,31 +1520,35 @@ void vmcs_dump_vcpu(struct vcpu *v)
printk("*** Control State ***\n");
printk("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n",
- (uint32_t)vmr(PIN_BASED_VM_EXEC_CONTROL),
- (uint32_t)vmr(CPU_BASED_VM_EXEC_CONTROL),
- (uint32_t)vmr(SECONDARY_VM_EXEC_CONTROL));
+ vmr32(PIN_BASED_VM_EXEC_CONTROL),
+ vmr32(CPU_BASED_VM_EXEC_CONTROL),
+ vmr32(SECONDARY_VM_EXEC_CONTROL));
printk("EntryControls=%08x ExitControls=%08x\n", vmentry_ctl, vmexit_ctl);
- printk("ExceptionBitmap=%08x\n",
- (uint32_t)vmr(EXCEPTION_BITMAP));
+ printk("ExceptionBitmap=%08x PFECmask=%08x PFECmatch=%08x\n",
+ vmr32(EXCEPTION_BITMAP),
+ vmr32(PAGE_FAULT_ERROR_CODE_MASK),
+ vmr32(PAGE_FAULT_ERROR_CODE_MATCH));
printk("VMEntry: intr_info=%08x errcode=%08x ilen=%08x\n",
- (uint32_t)vmr(VM_ENTRY_INTR_INFO),
- (uint32_t)vmr(VM_ENTRY_EXCEPTION_ERROR_CODE),
- (uint32_t)vmr(VM_ENTRY_INSTRUCTION_LEN));
+ vmr32(VM_ENTRY_INTR_INFO),
+ vmr32(VM_ENTRY_EXCEPTION_ERROR_CODE),
+ vmr32(VM_ENTRY_INSTRUCTION_LEN));
printk("VMExit: intr_info=%08x errcode=%08x ilen=%08x\n",
- (uint32_t)vmr(VM_EXIT_INTR_INFO),
- (uint32_t)vmr(VM_EXIT_INTR_ERROR_CODE),
- (uint32_t)vmr(VM_ENTRY_INSTRUCTION_LEN));
- printk(" reason=%08x qualification=%08x\n",
- (uint32_t)vmr(VM_EXIT_REASON),
- (uint32_t)vmr(EXIT_QUALIFICATION));
+ vmr32(VM_EXIT_INTR_INFO),
+ vmr32(VM_EXIT_INTR_ERROR_CODE),
+ vmr32(VM_EXIT_INSTRUCTION_LEN));
+ printk(" reason=%08x qualification=%016lx\n",
+ vmr32(VM_EXIT_REASON), vmr(EXIT_QUALIFICATION));
printk("IDTVectoring: info=%08x errcode=%08x\n",
- (uint32_t)vmr(IDT_VECTORING_INFO),
- (uint32_t)vmr(IDT_VECTORING_ERROR_CODE));
- printk("TPR Threshold = 0x%02x\n",
- (uint32_t)vmr(TPR_THRESHOLD));
+ vmr32(IDT_VECTORING_INFO), vmr32(IDT_VECTORING_ERROR_CODE));
printk("TSC Offset = 0x%016lx\n", vmr(TSC_OFFSET));
- printk("EPT pointer = 0x%08x%08x\n",
- (uint32_t)vmr(EPT_POINTER_HIGH), (uint32_t)vmr(EPT_POINTER));
+ if ( (v->arch.hvm_vmx.exec_control & CPU_BASED_TPR_SHADOW) ||
+ (vmx_pin_based_exec_control & PIN_BASED_POSTED_INTERRUPT) )
+ printk("TPR Threshold = 0x%02x PostedIntrVec = 0x%02x\n",
+ vmr32(TPR_THRESHOLD), vmr16(POSTED_INTR_NOTIFICATION_VECTOR));
+ if ( (v->arch.hvm_vmx.secondary_exec_control &
+ SECONDARY_EXEC_ENABLE_EPT) )
+ printk("EPT pointer = 0x%016lx EPTP index = 0x%04x\n",
+ vmr(EPT_POINTER), vmr16(EPTP_INDEX));
n = vmr32(CR3_TARGET_COUNT);
for ( i = 0; i + 1 < n; i += 2 )
printk("CR3 target%u=%016lx target%u=%016lx\n",
@@ -1552,8 +1556,14 @@ void vmcs_dump_vcpu(struct vcpu *v)
i + 1, vmr(CR3_TARGET_VALUE(i + 1)));
if ( i < n )
printk("CR3 target%u=%016lx\n", i, vmr(CR3_TARGET_VALUE(i)));
- printk("Virtual processor ID = 0x%04x\n",
- (uint32_t)vmr(VIRTUAL_PROCESSOR_ID));
+ if ( v->arch.hvm_vmx.secondary_exec_control &
+ SECONDARY_EXEC_PAUSE_LOOP_EXITING )
+ printk("PLE Gap=%08x Window=%08x\n",
+ vmr32(PLE_GAP), vmr32(PLE_WINDOW));
+ if ( v->arch.hvm_vmx.secondary_exec_control &
+ (SECONDARY_EXEC_ENABLE_VPID | SECONDARY_EXEC_ENABLE_VMFUNC) )
+ printk("Virtual processor ID = 0x%04x VMfunc controls = %016lx\n",
+ vmr16(VIRTUAL_PROCESSOR_ID), vmr(VMFUNC_CONTROL));
vmx_vmcs_exit(v);
}
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -213,6 +213,7 @@ extern u32 vmx_vmentry_control;
#define SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY 0x00000200
#define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400
#define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000
+#define SECONDARY_EXEC_ENABLE_VMFUNC 0x00002000
#define SECONDARY_EXEC_ENABLE_VMCS_SHADOWING 0x00004000
extern u32 vmx_secondary_exec_control;
@@ -306,6 +307,7 @@ extern u64 vmx_basic_msr;
enum vmcs_field {
VIRTUAL_PROCESSOR_ID = 0x00000000,
POSTED_INTR_NOTIFICATION_VECTOR = 0x00000002,
+ EPTP_INDEX = 0x00000004,
GUEST_ES_SELECTOR = 0x00000800,
GUEST_CS_SELECTOR = 0x00000802,
GUEST_SS_SELECTOR = 0x00000804,
@@ -342,6 +344,7 @@ enum vmcs_field {
APIC_ACCESS_ADDR_HIGH = 0x00002015,
PI_DESC_ADDR = 0x00002016,
PI_DESC_ADDR_HIGH = 0x00002017,
+ VMFUNC_CONTROL = 0x00002018,
EPT_POINTER = 0x0000201a,
EPT_POINTER_HIGH = 0x0000201b,
EOI_EXIT_BITMAP0 = 0x0000201c,
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 4/5] VMX: drop VMCS *_HIGH enumerators
2015-01-20 10:58 [PATCH 0/5] VMX: assorted adjustments Jan Beulich
` (2 preceding siblings ...)
2015-01-20 11:06 ` [PATCH 3/5] VMX: dump further control state Jan Beulich
@ 2015-01-20 11:07 ` Jan Beulich
2015-01-20 17:57 ` Andrew Cooper
2015-01-22 4:41 ` Tian, Kevin
2015-01-20 11:08 ` [PATCH 5/5] VMX: use cached "current" where available Jan Beulich
4 siblings, 2 replies; 20+ messages in thread
From: Jan Beulich @ 2015-01-20 11:07 UTC (permalink / raw)
To: xen-devel; +Cc: Kevin Tian, Eddie Dong, Jun Nakajima
[-- Attachment #1: Type: text/plain, Size: 5096 bytes --]
Most of them have been unused since the dropping of 32-bit support, and
the few remaining cases are more efficiently dealt with using a generic
macro (and probably things should have been done that way from the
beginning).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
As already mentioned in
http://lists.xenproject.org/archives/html/xen-devel/2014-10/msg01580.html,
looking at the changes to vvmx.c here emphasizes the question about the
inconsistency between nvmx_vcpu_initialise() and nvmx_handle_vmwrite()
wrt the MSR bitmap handling.
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -98,9 +98,9 @@ int nvmx_vcpu_initialise(struct vcpu *v)
* Let them vmexit as usual.
*/
set_bit(IO_BITMAP_A, vw);
- set_bit(IO_BITMAP_A_HIGH, vw);
+ set_bit(VMCS_HIGH(IO_BITMAP_A), vw);
set_bit(IO_BITMAP_B, vw);
- set_bit(IO_BITMAP_B_HIGH, vw);
+ set_bit(VMCS_HIGH(IO_BITMAP_B), vw);
unmap_domain_page(vr);
unmap_domain_page(vw);
@@ -1761,15 +1761,15 @@ int nvmx_handle_vmwrite(struct cpu_user_
vmcs_encoding = reg_read(regs, decode.reg2);
__set_vvmcs(nvcpu->nv_vvmcx, vmcs_encoding, operand);
- switch ( vmcs_encoding )
+ switch ( vmcs_encoding & ~VMCS_HIGH(0) )
{
- case IO_BITMAP_A: case IO_BITMAP_A_HIGH:
+ case IO_BITMAP_A:
okay = _map_io_bitmap(v, IO_BITMAP_A);
break;
- case IO_BITMAP_B: case IO_BITMAP_B_HIGH:
+ case IO_BITMAP_B:
okay = _map_io_bitmap(v, IO_BITMAP_B);
break;
- case MSR_BITMAP: case MSR_BITMAP_HIGH:
+ case MSR_BITMAP:
okay = _map_msr_bitmap(v);
break;
}
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -304,6 +304,7 @@ extern u64 vmx_basic_msr;
#define VMX_GUEST_INTR_STATUS_SVI_OFFSET 8
/* VMCS field encodings. */
+#define VMCS_HIGH(x) ((x) | 1)
enum vmcs_field {
VIRTUAL_PROCESSOR_ID = 0x00000000,
POSTED_INTR_NOTIFICATION_VECTOR = 0x00000002,
@@ -325,56 +326,33 @@ enum vmcs_field {
HOST_GS_SELECTOR = 0x00000c0a,
HOST_TR_SELECTOR = 0x00000c0c,
IO_BITMAP_A = 0x00002000,
- IO_BITMAP_A_HIGH = 0x00002001,
IO_BITMAP_B = 0x00002002,
- IO_BITMAP_B_HIGH = 0x00002003,
MSR_BITMAP = 0x00002004,
- MSR_BITMAP_HIGH = 0x00002005,
VM_EXIT_MSR_STORE_ADDR = 0x00002006,
- VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007,
VM_EXIT_MSR_LOAD_ADDR = 0x00002008,
- VM_EXIT_MSR_LOAD_ADDR_HIGH = 0x00002009,
VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a,
- VM_ENTRY_MSR_LOAD_ADDR_HIGH = 0x0000200b,
TSC_OFFSET = 0x00002010,
- TSC_OFFSET_HIGH = 0x00002011,
VIRTUAL_APIC_PAGE_ADDR = 0x00002012,
- VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013,
APIC_ACCESS_ADDR = 0x00002014,
- APIC_ACCESS_ADDR_HIGH = 0x00002015,
PI_DESC_ADDR = 0x00002016,
- PI_DESC_ADDR_HIGH = 0x00002017,
VMFUNC_CONTROL = 0x00002018,
EPT_POINTER = 0x0000201a,
- EPT_POINTER_HIGH = 0x0000201b,
EOI_EXIT_BITMAP0 = 0x0000201c,
#define EOI_EXIT_BITMAP(n) (EOI_EXIT_BITMAP0 + (n) * 2) /* n = 0...3 */
VMREAD_BITMAP = 0x00002026,
- VMREAD_BITMAP_HIGH = 0x00002027,
VMWRITE_BITMAP = 0x00002028,
- VMWRITE_BITMAP_HIGH = 0x00002029,
GUEST_PHYSICAL_ADDRESS = 0x00002400,
- GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401,
VMCS_LINK_POINTER = 0x00002800,
- VMCS_LINK_POINTER_HIGH = 0x00002801,
GUEST_IA32_DEBUGCTL = 0x00002802,
- GUEST_IA32_DEBUGCTL_HIGH = 0x00002803,
GUEST_PAT = 0x00002804,
- GUEST_PAT_HIGH = 0x00002805,
GUEST_EFER = 0x00002806,
- GUEST_EFER_HIGH = 0x00002807,
GUEST_PERF_GLOBAL_CTRL = 0x00002808,
- GUEST_PERF_GLOBAL_CTRL_HIGH = 0x00002809,
GUEST_PDPTE0 = 0x0000280a,
#define GUEST_PDPTE(n) (GUEST_PDPTE0 + (n) * 2) /* n = 0...3 */
GUEST_BNDCFGS = 0x00002812,
- GUEST_BNDCFGS_HIGH = 0x00002813,
HOST_PAT = 0x00002c00,
- HOST_PAT_HIGH = 0x00002c01,
HOST_EFER = 0x00002c02,
- HOST_EFER_HIGH = 0x00002c03,
HOST_PERF_GLOBAL_CTRL = 0x00002c04,
- HOST_PERF_GLOBAL_CTRL_HIGH = 0x00002c05,
PIN_BASED_VM_EXEC_CONTROL = 0x00004000,
CPU_BASED_VM_EXEC_CONTROL = 0x00004002,
EXCEPTION_BITMAP = 0x00004004,
[-- Attachment #2: VMX-drop-VMCS-high-enums.patch --]
[-- Type: text/plain, Size: 5129 bytes --]
VMX: drop VMCS *_HIGH enumerators
Most of them have been unused since the dropping of 32-bit support, and
the few remaining cases are more efficiently dealt with using a generic
macro (and probably things should have been done that way from the
beginning).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
As already mentioned in
http://lists.xenproject.org/archives/html/xen-devel/2014-10/msg01580.html,
looking at the changes to vvmx.c here emphasizes the question about the
inconsistency between nvmx_vcpu_initialise() and nvmx_handle_vmwrite()
wrt the MSR bitmap handling.
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -98,9 +98,9 @@ int nvmx_vcpu_initialise(struct vcpu *v)
* Let them vmexit as usual.
*/
set_bit(IO_BITMAP_A, vw);
- set_bit(IO_BITMAP_A_HIGH, vw);
+ set_bit(VMCS_HIGH(IO_BITMAP_A), vw);
set_bit(IO_BITMAP_B, vw);
- set_bit(IO_BITMAP_B_HIGH, vw);
+ set_bit(VMCS_HIGH(IO_BITMAP_B), vw);
unmap_domain_page(vr);
unmap_domain_page(vw);
@@ -1761,15 +1761,15 @@ int nvmx_handle_vmwrite(struct cpu_user_
vmcs_encoding = reg_read(regs, decode.reg2);
__set_vvmcs(nvcpu->nv_vvmcx, vmcs_encoding, operand);
- switch ( vmcs_encoding )
+ switch ( vmcs_encoding & ~VMCS_HIGH(0) )
{
- case IO_BITMAP_A: case IO_BITMAP_A_HIGH:
+ case IO_BITMAP_A:
okay = _map_io_bitmap(v, IO_BITMAP_A);
break;
- case IO_BITMAP_B: case IO_BITMAP_B_HIGH:
+ case IO_BITMAP_B:
okay = _map_io_bitmap(v, IO_BITMAP_B);
break;
- case MSR_BITMAP: case MSR_BITMAP_HIGH:
+ case MSR_BITMAP:
okay = _map_msr_bitmap(v);
break;
}
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -304,6 +304,7 @@ extern u64 vmx_basic_msr;
#define VMX_GUEST_INTR_STATUS_SVI_OFFSET 8
/* VMCS field encodings. */
+#define VMCS_HIGH(x) ((x) | 1)
enum vmcs_field {
VIRTUAL_PROCESSOR_ID = 0x00000000,
POSTED_INTR_NOTIFICATION_VECTOR = 0x00000002,
@@ -325,56 +326,33 @@ enum vmcs_field {
HOST_GS_SELECTOR = 0x00000c0a,
HOST_TR_SELECTOR = 0x00000c0c,
IO_BITMAP_A = 0x00002000,
- IO_BITMAP_A_HIGH = 0x00002001,
IO_BITMAP_B = 0x00002002,
- IO_BITMAP_B_HIGH = 0x00002003,
MSR_BITMAP = 0x00002004,
- MSR_BITMAP_HIGH = 0x00002005,
VM_EXIT_MSR_STORE_ADDR = 0x00002006,
- VM_EXIT_MSR_STORE_ADDR_HIGH = 0x00002007,
VM_EXIT_MSR_LOAD_ADDR = 0x00002008,
- VM_EXIT_MSR_LOAD_ADDR_HIGH = 0x00002009,
VM_ENTRY_MSR_LOAD_ADDR = 0x0000200a,
- VM_ENTRY_MSR_LOAD_ADDR_HIGH = 0x0000200b,
TSC_OFFSET = 0x00002010,
- TSC_OFFSET_HIGH = 0x00002011,
VIRTUAL_APIC_PAGE_ADDR = 0x00002012,
- VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013,
APIC_ACCESS_ADDR = 0x00002014,
- APIC_ACCESS_ADDR_HIGH = 0x00002015,
PI_DESC_ADDR = 0x00002016,
- PI_DESC_ADDR_HIGH = 0x00002017,
VMFUNC_CONTROL = 0x00002018,
EPT_POINTER = 0x0000201a,
- EPT_POINTER_HIGH = 0x0000201b,
EOI_EXIT_BITMAP0 = 0x0000201c,
#define EOI_EXIT_BITMAP(n) (EOI_EXIT_BITMAP0 + (n) * 2) /* n = 0...3 */
VMREAD_BITMAP = 0x00002026,
- VMREAD_BITMAP_HIGH = 0x00002027,
VMWRITE_BITMAP = 0x00002028,
- VMWRITE_BITMAP_HIGH = 0x00002029,
GUEST_PHYSICAL_ADDRESS = 0x00002400,
- GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401,
VMCS_LINK_POINTER = 0x00002800,
- VMCS_LINK_POINTER_HIGH = 0x00002801,
GUEST_IA32_DEBUGCTL = 0x00002802,
- GUEST_IA32_DEBUGCTL_HIGH = 0x00002803,
GUEST_PAT = 0x00002804,
- GUEST_PAT_HIGH = 0x00002805,
GUEST_EFER = 0x00002806,
- GUEST_EFER_HIGH = 0x00002807,
GUEST_PERF_GLOBAL_CTRL = 0x00002808,
- GUEST_PERF_GLOBAL_CTRL_HIGH = 0x00002809,
GUEST_PDPTE0 = 0x0000280a,
#define GUEST_PDPTE(n) (GUEST_PDPTE0 + (n) * 2) /* n = 0...3 */
GUEST_BNDCFGS = 0x00002812,
- GUEST_BNDCFGS_HIGH = 0x00002813,
HOST_PAT = 0x00002c00,
- HOST_PAT_HIGH = 0x00002c01,
HOST_EFER = 0x00002c02,
- HOST_EFER_HIGH = 0x00002c03,
HOST_PERF_GLOBAL_CTRL = 0x00002c04,
- HOST_PERF_GLOBAL_CTRL_HIGH = 0x00002c05,
PIN_BASED_VM_EXEC_CONTROL = 0x00004000,
CPU_BASED_VM_EXEC_CONTROL = 0x00004002,
EXCEPTION_BITMAP = 0x00004004,
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 5/5] VMX: use cached "current" where available
2015-01-20 10:58 [PATCH 0/5] VMX: assorted adjustments Jan Beulich
` (3 preceding siblings ...)
2015-01-20 11:07 ` [PATCH 4/5] VMX: drop VMCS *_HIGH enumerators Jan Beulich
@ 2015-01-20 11:08 ` Jan Beulich
2015-01-20 18:03 ` Andrew Cooper
2015-01-22 4:44 ` Tian, Kevin
4 siblings, 2 replies; 20+ messages in thread
From: Jan Beulich @ 2015-01-20 11:08 UTC (permalink / raw)
To: xen-devel; +Cc: Kevin Tian, Eddie Dong, Jun Nakajima
[-- Attachment #1: Type: text/plain, Size: 1737 bytes --]
..., yielding better code.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -1474,7 +1474,7 @@ static void vmx_inject_trap(struct hvm_t
if ( (_trap.vector == TRAP_page_fault) &&
(_trap.type == X86_EVENTTYPE_HW_EXCEPTION) )
- current->arch.hvm_vcpu.guest_cr[2] = _trap.cr2;
+ curr->arch.hvm_vcpu.guest_cr[2] = _trap.cr2;
if ( nestedhvm_vcpu_in_guestmode(curr) )
intr_info = vcpu_2_nvmx(curr).intr.intr_info;
@@ -1527,7 +1527,7 @@ static void vmx_inject_trap(struct hvm_t
if ( (_trap.vector == TRAP_page_fault) &&
(_trap.type == X86_EVENTTYPE_HW_EXCEPTION) )
HVMTRACE_LONG_2D(PF_INJECT, _trap.error_code,
- TRC_PAR_LONG(current->arch.hvm_vcpu.guest_cr[2]));
+ TRC_PAR_LONG(curr->arch.hvm_vcpu.guest_cr[2]));
else
HVMTRACE_2D(INJ_EXC, _trap.vector, _trap.error_code);
}
@@ -2814,7 +2814,7 @@ void vmx_vmexit_handler(struct cpu_user_
if ( v->domain->debugger_attached )
{
update_guest_eip(); /* Safe: INT3 */
- current->arch.gdbsx_vcpu_event = TRAP_int3;
+ v->arch.gdbsx_vcpu_event = TRAP_int3;
domain_pause_for_debugger();
break;
}
@@ -3080,7 +3080,7 @@ void vmx_vmexit_handler(struct cpu_user_
__vmread(EXIT_QUALIFICATION, &exit_qualification);
vector = exit_qualification & 0xff;
- vmx_handle_EOI_induced_exit(vcpu_vlapic(current), vector);
+ vmx_handle_EOI_induced_exit(vcpu_vlapic(v), vector);
break;
}
[-- Attachment #2: VMX-use-cached-current.patch --]
[-- Type: text/plain, Size: 1776 bytes --]
VMX: use cached "current" where available
..., yielding better code.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -1474,7 +1474,7 @@ static void vmx_inject_trap(struct hvm_t
if ( (_trap.vector == TRAP_page_fault) &&
(_trap.type == X86_EVENTTYPE_HW_EXCEPTION) )
- current->arch.hvm_vcpu.guest_cr[2] = _trap.cr2;
+ curr->arch.hvm_vcpu.guest_cr[2] = _trap.cr2;
if ( nestedhvm_vcpu_in_guestmode(curr) )
intr_info = vcpu_2_nvmx(curr).intr.intr_info;
@@ -1527,7 +1527,7 @@ static void vmx_inject_trap(struct hvm_t
if ( (_trap.vector == TRAP_page_fault) &&
(_trap.type == X86_EVENTTYPE_HW_EXCEPTION) )
HVMTRACE_LONG_2D(PF_INJECT, _trap.error_code,
- TRC_PAR_LONG(current->arch.hvm_vcpu.guest_cr[2]));
+ TRC_PAR_LONG(curr->arch.hvm_vcpu.guest_cr[2]));
else
HVMTRACE_2D(INJ_EXC, _trap.vector, _trap.error_code);
}
@@ -2814,7 +2814,7 @@ void vmx_vmexit_handler(struct cpu_user_
if ( v->domain->debugger_attached )
{
update_guest_eip(); /* Safe: INT3 */
- current->arch.gdbsx_vcpu_event = TRAP_int3;
+ v->arch.gdbsx_vcpu_event = TRAP_int3;
domain_pause_for_debugger();
break;
}
@@ -3080,7 +3080,7 @@ void vmx_vmexit_handler(struct cpu_user_
__vmread(EXIT_QUALIFICATION, &exit_qualification);
vector = exit_qualification & 0xff;
- vmx_handle_EOI_induced_exit(vcpu_vlapic(current), vector);
+ vmx_handle_EOI_induced_exit(vcpu_vlapic(v), vector);
break;
}
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/5] VMX: dump full guest state
2015-01-20 11:05 ` [PATCH 1/5] VMX: dump full guest state Jan Beulich
@ 2015-01-20 17:03 ` Andrew Cooper
2015-01-21 10:33 ` Jan Beulich
2015-01-22 4:40 ` Tian, Kevin
1 sibling, 1 reply; 20+ messages in thread
From: Andrew Cooper @ 2015-01-20 17:03 UTC (permalink / raw)
To: Jan Beulich, xen-devel; +Cc: Kevin Tian, Eddie Dong, Jun Nakajima
On 20/01/15 11:05, Jan Beulich wrote:
> Several guest state fields did not get dumped so far. Where suitable
> (to reduce the amount of output) make some of the dumping conditional
> upon guest settings (this isn't required for correctness as vmr()
> already uses __vmread_safe(), i.e. it is fine to access non-existing
> fields).
>
> Move CR3_TARGET_* and TSC_OFFSET processing into the control state
> section, at once making the upper bound of CR3_TARGET_VALUEn printed
> depend on CR3_TARGET_COUNT (which architecturally can be higher than
> 4).
>
> Also rename GUEST_PDPTRn to GUEST_PDPTEn (matching the SDM naming) and
> group them as well as CR3_TARGET_VALUEn similar to EOI_EXIT_BITMAP.
>
> Finally, drop casts - they haven't been needed anymore since the
> dropping of 32-bit support (and some of them were not really needed in
> the first place). Introduce vmr16() and vmr32() helper macros to avoid
> the "l" printk format modifier and at the same time validate that only
> 16-/32-bit fields get accessed this way.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> ---
> Is cpu_has_vmx_pat properly defined? Shouldn't this take into
> consideration all three respective flags (VM_EXIT_SAVE_GUEST_PAT,
> VM_EXIT_LOAD_HOST_PAT, and VM_ENTRY_LOAD_GUEST_PAT)?
>
> --- a/xen/arch/x86/hvm/vmx/vmcs.c
> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
> @@ -1395,6 +1395,16 @@ static inline unsigned long vmr(unsigned
> return __vmread_safe(field, &val) ? val : 0;
> }
>
> +#define vmr16(fld) ({ \
> + BUILD_BUG_ON((fld) & 0x6001); \
> + (uint16_t)vmr(fld); \
> +})
> +
> +#define vmr32(fld) ({ \
> + BUILD_BUG_ON(((fld) & 0x6001) != 0x4000); \
> + (uint16_t)vmr(fld); \
uint32_t ?
Otherwise, Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 2/5] VMX: dump full host state
2015-01-20 11:06 ` [PATCH 2/5] VMX: dump full host state Jan Beulich
@ 2015-01-20 17:19 ` Andrew Cooper
2015-01-21 10:39 ` Jan Beulich
2015-01-22 4:40 ` Tian, Kevin
1 sibling, 1 reply; 20+ messages in thread
From: Andrew Cooper @ 2015-01-20 17:19 UTC (permalink / raw)
To: Jan Beulich, xen-devel; +Cc: Kevin Tian, Eddie Dong, Jun Nakajima
[-- Attachment #1.1: Type: text/plain, Size: 4079 bytes --]
On 20/01/15 11:06, Jan Beulich wrote:
> A few host state fields did not get dumped so far. Where suitable (to
> reduce the amount of output) make some of the dumping conditional upon
> guest settings (this isn't required for correctness as vmr() already
> uses __vmread_safe(), i.e. it is fine to access non-existing fields).
>
> Also drop casts - many of them haven't been needed anymore since the
> dropping of 32-bit support.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
>
> --- a/xen/arch/x86/hvm/vmx/vmcs.c
> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
> @@ -1496,34 +1496,27 @@ void vmcs_dump_vcpu(struct vcpu *v)
> printk("InterruptStatus = %04x\n", vmr16(GUEST_INTR_STATUS));
>
> printk("*** Host State ***\n");
> - printk("RSP = 0x%016llx RIP = 0x%016llx\n",
> - (unsigned long long)vmr(HOST_RSP),
> - (unsigned long long)vmr(HOST_RIP));
> - printk("CS=%04x DS=%04x ES=%04x FS=%04x GS=%04x SS=%04x TR=%04x\n",
> - (uint16_t)vmr(HOST_CS_SELECTOR),
> - (uint16_t)vmr(HOST_DS_SELECTOR),
> - (uint16_t)vmr(HOST_ES_SELECTOR),
> - (uint16_t)vmr(HOST_FS_SELECTOR),
> - (uint16_t)vmr(HOST_GS_SELECTOR),
> - (uint16_t)vmr(HOST_SS_SELECTOR),
> - (uint16_t)vmr(HOST_TR_SELECTOR));
> - printk("FSBase=%016llx GSBase=%016llx TRBase=%016llx\n",
> - (unsigned long long)vmr(HOST_FS_BASE),
> - (unsigned long long)vmr(HOST_GS_BASE),
> - (unsigned long long)vmr(HOST_TR_BASE));
> - printk("GDTBase=%016llx IDTBase=%016llx\n",
> - (unsigned long long)vmr(HOST_GDTR_BASE),
> - (unsigned long long)vmr(HOST_IDTR_BASE));
> - printk("CR0=%016llx CR3=%016llx CR4=%016llx\n",
> - (unsigned long long)vmr(HOST_CR0),
> - (unsigned long long)vmr(HOST_CR3),
> - (unsigned long long)vmr(HOST_CR4));
> - printk("Sysenter RSP=%016llx CS:RIP=%04x:%016llx\n",
> - (unsigned long long)vmr(HOST_SYSENTER_ESP),
> - (int)vmr(HOST_SYSENTER_CS),
> - (unsigned long long)vmr(HOST_SYSENTER_EIP));
> - printk("Host PAT = 0x%08x%08x\n",
> - (uint32_t)vmr(HOST_PAT_HIGH), (uint32_t)vmr(HOST_PAT));
> + printk("RIP = 0x%016lx (%ps) RSP = 0x%016lx\n",
> + vmr(HOST_RIP), (void *)vmr(HOST_RIP), vmr(HOST_RSP));
Given the asm volatile, the compiler is unlikely to elide the second
read of HOST_RIP. I suppose that this is debug code and it really
doesn't matter too much, but if it is used anywhere else it might be
worth pulling out into a local variable.
> + printk("CS=%04x SS=%04x DS=%04x ES=%04x FS=%04x GS=%04x TR=%04x\n",
> + vmr16(HOST_CS_SELECTOR), vmr16(HOST_SS_SELECTOR),
> + vmr16(HOST_DS_SELECTOR), vmr16(HOST_ES_SELECTOR),
> + vmr16(HOST_FS_SELECTOR), vmr16(HOST_GS_SELECTOR),
> + vmr16(HOST_TR_SELECTOR));
> + printk("FSBase=%016lx GSBase=%016lx TRBase=%016lx\n",
> + vmr(HOST_FS_BASE), vmr(HOST_GS_BASE), vmr(HOST_TR_BASE));
> + printk("GDTBase=%016lx IDTBase=%016lx\n",
> + vmr(HOST_GDTR_BASE), vmr(HOST_IDTR_BASE));
> + printk("CR0=%016lx CR3=%016lx CR4=%016lx\n",
> + vmr(HOST_CR0), vmr(HOST_CR3), vmr(HOST_CR4));
> + printk("Sysenter RSP=%016lx CS:RIP=%04x:%016lx\n",
> + vmr(HOST_SYSENTER_ESP),
> + vmr32(HOST_SYSENTER_CS), vmr(HOST_SYSENTER_EIP));
vmr16() ?
~Andrew
> + if ( vmexit_ctl & (VM_EXIT_LOAD_HOST_PAT | VM_EXIT_LOAD_HOST_EFER) )
> + printk("EFER = 0x%016lx PAT = 0x%016lx\n", vmr(HOST_EFER), vmr(HOST_PAT));
> + if ( vmexit_ctl & VM_EXIT_LOAD_PERF_GLOBAL_CTRL )
> + printk("PerfGlobCtl = 0x%016lx\n",
> + vmr(HOST_PERF_GLOBAL_CTRL));
>
> printk("*** Control State ***\n");
> printk("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n",
>
>
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
[-- Attachment #1.2: Type: text/html, Size: 5003 bytes --]
[-- Attachment #2: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 3/5] VMX: dump further control state
2015-01-20 11:06 ` [PATCH 3/5] VMX: dump further control state Jan Beulich
@ 2015-01-20 17:39 ` Andrew Cooper
2015-01-22 4:41 ` Tian, Kevin
1 sibling, 0 replies; 20+ messages in thread
From: Andrew Cooper @ 2015-01-20 17:39 UTC (permalink / raw)
To: Jan Beulich, xen-devel; +Cc: Kevin Tian, Eddie Dong, Jun Nakajima
[-- Attachment #1.1: Type: text/plain, Size: 5932 bytes --]
On 20/01/15 11:06, Jan Beulich wrote:
> A few relevant control state fields did not get dumped so far; in
> particular, VM_ENTRY_INSTRUCTION_LEN got printed twice (instead of also
> printing VM_EXIT_INSTRUCTION_LEN). Where suitable (to reduce the amount
> of output) make some of the dumping conditional upon guest settings
> (this isn't required for correctness as vmr() already uses
> __vmread_safe(), i.e. it is fine to access non-existing fields).
>
> Also drop casts.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
>
> --- a/xen/arch/x86/hvm/vmx/vmcs.c
> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
> @@ -1520,31 +1520,35 @@ void vmcs_dump_vcpu(struct vcpu *v)
>
> printk("*** Control State ***\n");
> printk("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n",
> - (uint32_t)vmr(PIN_BASED_VM_EXEC_CONTROL),
> - (uint32_t)vmr(CPU_BASED_VM_EXEC_CONTROL),
> - (uint32_t)vmr(SECONDARY_VM_EXEC_CONTROL));
> + vmr32(PIN_BASED_VM_EXEC_CONTROL),
> + vmr32(CPU_BASED_VM_EXEC_CONTROL),
> + vmr32(SECONDARY_VM_EXEC_CONTROL));
> printk("EntryControls=%08x ExitControls=%08x\n", vmentry_ctl, vmexit_ctl);
> - printk("ExceptionBitmap=%08x\n",
> - (uint32_t)vmr(EXCEPTION_BITMAP));
> + printk("ExceptionBitmap=%08x PFECmask=%08x PFECmatch=%08x\n",
> + vmr32(EXCEPTION_BITMAP),
> + vmr32(PAGE_FAULT_ERROR_CODE_MASK),
> + vmr32(PAGE_FAULT_ERROR_CODE_MATCH));
> printk("VMEntry: intr_info=%08x errcode=%08x ilen=%08x\n",
> - (uint32_t)vmr(VM_ENTRY_INTR_INFO),
> - (uint32_t)vmr(VM_ENTRY_EXCEPTION_ERROR_CODE),
> - (uint32_t)vmr(VM_ENTRY_INSTRUCTION_LEN));
> + vmr32(VM_ENTRY_INTR_INFO),
> + vmr32(VM_ENTRY_EXCEPTION_ERROR_CODE),
> + vmr32(VM_ENTRY_INSTRUCTION_LEN));
> printk("VMExit: intr_info=%08x errcode=%08x ilen=%08x\n",
> - (uint32_t)vmr(VM_EXIT_INTR_INFO),
> - (uint32_t)vmr(VM_EXIT_INTR_ERROR_CODE),
> - (uint32_t)vmr(VM_ENTRY_INSTRUCTION_LEN));
> - printk(" reason=%08x qualification=%08x\n",
> - (uint32_t)vmr(VM_EXIT_REASON),
> - (uint32_t)vmr(EXIT_QUALIFICATION));
> + vmr32(VM_EXIT_INTR_INFO),
> + vmr32(VM_EXIT_INTR_ERROR_CODE),
> + vmr32(VM_EXIT_INSTRUCTION_LEN));
> + printk(" reason=%08x qualification=%016lx\n",
> + vmr32(VM_EXIT_REASON), vmr(EXIT_QUALIFICATION));
> printk("IDTVectoring: info=%08x errcode=%08x\n",
> - (uint32_t)vmr(IDT_VECTORING_INFO),
> - (uint32_t)vmr(IDT_VECTORING_ERROR_CODE));
> - printk("TPR Threshold = 0x%02x\n",
> - (uint32_t)vmr(TPR_THRESHOLD));
> + vmr32(IDT_VECTORING_INFO), vmr32(IDT_VECTORING_ERROR_CODE));
> printk("TSC Offset = 0x%016lx\n", vmr(TSC_OFFSET));
> - printk("EPT pointer = 0x%08x%08x\n",
> - (uint32_t)vmr(EPT_POINTER_HIGH), (uint32_t)vmr(EPT_POINTER));
> + if ( (v->arch.hvm_vmx.exec_control & CPU_BASED_TPR_SHADOW) ||
> + (vmx_pin_based_exec_control & PIN_BASED_POSTED_INTERRUPT) )
> + printk("TPR Threshold = 0x%02x PostedIntrVec = 0x%02x\n",
> + vmr32(TPR_THRESHOLD), vmr16(POSTED_INTR_NOTIFICATION_VECTOR));
> + if ( (v->arch.hvm_vmx.secondary_exec_control &
> + SECONDARY_EXEC_ENABLE_EPT) )
> + printk("EPT pointer = 0x%016lx EPTP index = 0x%04x\n",
> + vmr(EPT_POINTER), vmr16(EPTP_INDEX));
> n = vmr32(CR3_TARGET_COUNT);
> for ( i = 0; i + 1 < n; i += 2 )
> printk("CR3 target%u=%016lx target%u=%016lx\n",
> @@ -1552,8 +1556,14 @@ void vmcs_dump_vcpu(struct vcpu *v)
> i + 1, vmr(CR3_TARGET_VALUE(i + 1)));
> if ( i < n )
> printk("CR3 target%u=%016lx\n", i, vmr(CR3_TARGET_VALUE(i)));
> - printk("Virtual processor ID = 0x%04x\n",
> - (uint32_t)vmr(VIRTUAL_PROCESSOR_ID));
> + if ( v->arch.hvm_vmx.secondary_exec_control &
> + SECONDARY_EXEC_PAUSE_LOOP_EXITING )
> + printk("PLE Gap=%08x Window=%08x\n",
> + vmr32(PLE_GAP), vmr32(PLE_WINDOW));
> + if ( v->arch.hvm_vmx.secondary_exec_control &
> + (SECONDARY_EXEC_ENABLE_VPID | SECONDARY_EXEC_ENABLE_VMFUNC) )
> + printk("Virtual processor ID = 0x%04x VMfunc controls = %016lx\n",
> + vmr16(VIRTUAL_PROCESSOR_ID), vmr(VMFUNC_CONTROL));
>
> vmx_vmcs_exit(v);
> }
> --- a/xen/include/asm-x86/hvm/vmx/vmcs.h
> +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
> @@ -213,6 +213,7 @@ extern u32 vmx_vmentry_control;
> #define SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY 0x00000200
> #define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400
> #define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000
> +#define SECONDARY_EXEC_ENABLE_VMFUNC 0x00002000
> #define SECONDARY_EXEC_ENABLE_VMCS_SHADOWING 0x00004000
> extern u32 vmx_secondary_exec_control;
>
> @@ -306,6 +307,7 @@ extern u64 vmx_basic_msr;
> enum vmcs_field {
> VIRTUAL_PROCESSOR_ID = 0x00000000,
> POSTED_INTR_NOTIFICATION_VECTOR = 0x00000002,
> + EPTP_INDEX = 0x00000004,
> GUEST_ES_SELECTOR = 0x00000800,
> GUEST_CS_SELECTOR = 0x00000802,
> GUEST_SS_SELECTOR = 0x00000804,
> @@ -342,6 +344,7 @@ enum vmcs_field {
> APIC_ACCESS_ADDR_HIGH = 0x00002015,
> PI_DESC_ADDR = 0x00002016,
> PI_DESC_ADDR_HIGH = 0x00002017,
> + VMFUNC_CONTROL = 0x00002018,
> EPT_POINTER = 0x0000201a,
> EPT_POINTER_HIGH = 0x0000201b,
> EOI_EXIT_BITMAP0 = 0x0000201c,
>
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
[-- Attachment #1.2: Type: text/html, Size: 6674 bytes --]
[-- Attachment #2: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/5] VMX: drop VMCS *_HIGH enumerators
2015-01-20 11:07 ` [PATCH 4/5] VMX: drop VMCS *_HIGH enumerators Jan Beulich
@ 2015-01-20 17:57 ` Andrew Cooper
2015-01-21 10:41 ` Jan Beulich
2015-01-22 4:41 ` Tian, Kevin
1 sibling, 1 reply; 20+ messages in thread
From: Andrew Cooper @ 2015-01-20 17:57 UTC (permalink / raw)
To: Jan Beulich, xen-devel; +Cc: Kevin Tian, Eddie Dong, Jun Nakajima
On 20/01/15 11:07, Jan Beulich wrote:
> Most of them have been unused since the dropping of 32-bit support, and
> the few remaining cases are more efficiently dealt with using a generic
> macro (and probably things should have been done that way from the
> beginning).
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> ---
> As already mentioned in
> http://lists.xenproject.org/archives/html/xen-devel/2014-10/msg01580.html,
> looking at the changes to vvmx.c here emphasizes the question about the
> inconsistency between nvmx_vcpu_initialise() and nvmx_handle_vmwrite()
> wrt the MSR bitmap handling.
>
> --- a/xen/arch/x86/hvm/vmx/vvmx.c
> +++ b/xen/arch/x86/hvm/vmx/vvmx.c
> @@ -98,9 +98,9 @@ int nvmx_vcpu_initialise(struct vcpu *v)
> * Let them vmexit as usual.
> */
> set_bit(IO_BITMAP_A, vw);
> - set_bit(IO_BITMAP_A_HIGH, vw);
> + set_bit(VMCS_HIGH(IO_BITMAP_A), vw);
> set_bit(IO_BITMAP_B, vw);
> - set_bit(IO_BITMAP_B_HIGH, vw);
> + set_bit(VMCS_HIGH(IO_BITMAP_B), vw);
>
> unmap_domain_page(vr);
> unmap_domain_page(vw);
> @@ -1761,15 +1761,15 @@ int nvmx_handle_vmwrite(struct cpu_user_
> vmcs_encoding = reg_read(regs, decode.reg2);
> __set_vvmcs(nvcpu->nv_vvmcx, vmcs_encoding, operand);
>
> - switch ( vmcs_encoding )
> + switch ( vmcs_encoding & ~VMCS_HIGH(0) )
While this is functionally fine, it is quite odd to read. One option
would be to use
case IO_BITMAP_A: case VMCS_HIGH(IO_BITMAP_A):
but I am not sure whether a compiler could optimise that as well as
masking the bottom bit out and halfing the number of case statements.
~Andrew
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 5/5] VMX: use cached "current" where available
2015-01-20 11:08 ` [PATCH 5/5] VMX: use cached "current" where available Jan Beulich
@ 2015-01-20 18:03 ` Andrew Cooper
2015-01-22 4:44 ` Tian, Kevin
1 sibling, 0 replies; 20+ messages in thread
From: Andrew Cooper @ 2015-01-20 18:03 UTC (permalink / raw)
To: Jan Beulich, xen-devel; +Cc: Kevin Tian, Eddie Dong, Jun Nakajima
On 20/01/15 11:08, Jan Beulich wrote:
> ..., yielding better code.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/5] VMX: dump full guest state
2015-01-20 17:03 ` Andrew Cooper
@ 2015-01-21 10:33 ` Jan Beulich
0 siblings, 0 replies; 20+ messages in thread
From: Jan Beulich @ 2015-01-21 10:33 UTC (permalink / raw)
To: Andrew Cooper; +Cc: xen-devel, Kevin Tian, Eddie Dong, JunNakajima
>>> On 20.01.15 at 18:03, <andrew.cooper3@citrix.com> wrote:
> On 20/01/15 11:05, Jan Beulich wrote:
>> --- a/xen/arch/x86/hvm/vmx/vmcs.c
>> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
>> @@ -1395,6 +1395,16 @@ static inline unsigned long vmr(unsigned
>> return __vmread_safe(field, &val) ? val : 0;
>> }
>>
>> +#define vmr16(fld) ({ \
>> + BUILD_BUG_ON((fld) & 0x6001); \
>> + (uint16_t)vmr(fld); \
>> +})
>> +
>> +#define vmr32(fld) ({ \
>> + BUILD_BUG_ON(((fld) & 0x6001) != 0x4000); \
>> + (uint16_t)vmr(fld); \
>
> uint32_t ?
Oops - yes of course! Thanks for spotting.
Jan
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 2/5] VMX: dump full host state
2015-01-20 17:19 ` Andrew Cooper
@ 2015-01-21 10:39 ` Jan Beulich
0 siblings, 0 replies; 20+ messages in thread
From: Jan Beulich @ 2015-01-21 10:39 UTC (permalink / raw)
To: Andrew Cooper; +Cc: xen-devel, Kevin Tian, Eddie Dong, JunNakajima
>>> On 20.01.15 at 18:19, <andrew.cooper3@citrix.com> wrote:
> On 20/01/15 11:06, Jan Beulich wrote:
>> + printk("RIP = 0x%016lx (%ps) RSP = 0x%016lx\n",
>> + vmr(HOST_RIP), (void *)vmr(HOST_RIP), vmr(HOST_RSP));
>
> Given the asm volatile, the compiler is unlikely to elide the second
> read of HOST_RIP. I suppose that this is debug code and it really
> doesn't matter too much, but if it is used anywhere else it might be
> worth pulling out into a local variable.
Indeed I didn't latch this into a local variable simply because this is
debugging code.
>> + printk("Sysenter RSP=%016lx CS:RIP=%04x:%016lx\n",
>> + vmr(HOST_SYSENTER_ESP),
>> + vmr32(HOST_SYSENTER_CS), vmr(HOST_SYSENTER_EIP));
>
> vmr16() ?
The BUILD_BUG_ON() in vmr32() not triggering already proves that
this is the right accessor - {HOST,GUEST}_SYSENTER_CS both are
32-bit fields.
Jan
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/5] VMX: drop VMCS *_HIGH enumerators
2015-01-20 17:57 ` Andrew Cooper
@ 2015-01-21 10:41 ` Jan Beulich
0 siblings, 0 replies; 20+ messages in thread
From: Jan Beulich @ 2015-01-21 10:41 UTC (permalink / raw)
To: Andrew Cooper; +Cc: xen-devel, Kevin Tian, Eddie Dong, JunNakajima
>>> On 20.01.15 at 18:57, <andrew.cooper3@citrix.com> wrote:
> On 20/01/15 11:07, Jan Beulich wrote:
>> @@ -1761,15 +1761,15 @@ int nvmx_handle_vmwrite(struct cpu_user_
>> vmcs_encoding = reg_read(regs, decode.reg2);
>> __set_vvmcs(nvcpu->nv_vvmcx, vmcs_encoding, operand);
>>
>> - switch ( vmcs_encoding )
>> + switch ( vmcs_encoding & ~VMCS_HIGH(0) )
>
> While this is functionally fine, it is quite odd to read. One option
> would be to use
>
> case IO_BITMAP_A: case VMCS_HIGH(IO_BITMAP_A):
>
> but I am not sure whether a compiler could optimise that as well as
> masking the bottom bit out and halfing the number of case statements.
A good compiler certainly could, but I prefer to make such
optimizations explicit (and hence compiler independent) in the
source code.
Jan
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/5] VMX: dump full guest state
2015-01-20 11:05 ` [PATCH 1/5] VMX: dump full guest state Jan Beulich
2015-01-20 17:03 ` Andrew Cooper
@ 2015-01-22 4:40 ` Tian, Kevin
2015-01-22 11:56 ` Jan Beulich
1 sibling, 1 reply; 20+ messages in thread
From: Tian, Kevin @ 2015-01-22 4:40 UTC (permalink / raw)
To: Jan Beulich, xen-devel; +Cc: Dong, Eddie, Nakajima, Jun
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: Tuesday, January 20, 2015 7:06 PM
>
> Several guest state fields did not get dumped so far. Where suitable
> (to reduce the amount of output) make some of the dumping conditional
> upon guest settings (this isn't required for correctness as vmr()
> already uses __vmread_safe(), i.e. it is fine to access non-existing
> fields).
>
> Move CR3_TARGET_* and TSC_OFFSET processing into the control state
> section, at once making the upper bound of CR3_TARGET_VALUEn printed
> depend on CR3_TARGET_COUNT (which architecturally can be higher than
> 4).
>
> Also rename GUEST_PDPTRn to GUEST_PDPTEn (matching the SDM naming)
> and
> group them as well as CR3_TARGET_VALUEn similar to EOI_EXIT_BITMAP.
>
> Finally, drop casts - they haven't been needed anymore since the
> dropping of 32-bit support (and some of them were not really needed in
> the first place). Introduce vmr16() and vmr32() helper macros to avoid
> the "l" printk format modifier and at the same time validate that only
> 16-/32-bit fields get accessed this way.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>, given that vmr32 typo is fixed.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 2/5] VMX: dump full host state
2015-01-20 11:06 ` [PATCH 2/5] VMX: dump full host state Jan Beulich
2015-01-20 17:19 ` Andrew Cooper
@ 2015-01-22 4:40 ` Tian, Kevin
1 sibling, 0 replies; 20+ messages in thread
From: Tian, Kevin @ 2015-01-22 4:40 UTC (permalink / raw)
To: Jan Beulich, xen-devel; +Cc: Dong, Eddie, Nakajima, Jun
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: Tuesday, January 20, 2015 7:06 PM
>
> A few host state fields did not get dumped so far. Where suitable (to
> reduce the amount of output) make some of the dumping conditional upon
> guest settings (this isn't required for correctness as vmr() already
> uses __vmread_safe(), i.e. it is fine to access non-existing fields).
>
> Also drop casts - many of them haven't been needed anymore since the
> dropping of 32-bit support.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
>
Acked-by: Kevin Tian <kevin.tian@intel.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 3/5] VMX: dump further control state
2015-01-20 11:06 ` [PATCH 3/5] VMX: dump further control state Jan Beulich
2015-01-20 17:39 ` Andrew Cooper
@ 2015-01-22 4:41 ` Tian, Kevin
1 sibling, 0 replies; 20+ messages in thread
From: Tian, Kevin @ 2015-01-22 4:41 UTC (permalink / raw)
To: Jan Beulich, xen-devel; +Cc: Dong, Eddie, Nakajima, Jun
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: Tuesday, January 20, 2015 7:07 PM
>
> A few relevant control state fields did not get dumped so far; in
> particular, VM_ENTRY_INSTRUCTION_LEN got printed twice (instead of also
> printing VM_EXIT_INSTRUCTION_LEN). Where suitable (to reduce the amount
> of output) make some of the dumping conditional upon guest settings
> (this isn't required for correctness as vmr() already uses
> __vmread_safe(), i.e. it is fine to access non-existing fields).
>
> Also drop casts.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
>
Acked-by: Kevin Tian <kevin.tian@intel.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 4/5] VMX: drop VMCS *_HIGH enumerators
2015-01-20 11:07 ` [PATCH 4/5] VMX: drop VMCS *_HIGH enumerators Jan Beulich
2015-01-20 17:57 ` Andrew Cooper
@ 2015-01-22 4:41 ` Tian, Kevin
1 sibling, 0 replies; 20+ messages in thread
From: Tian, Kevin @ 2015-01-22 4:41 UTC (permalink / raw)
To: Jan Beulich, xen-devel; +Cc: Dong, Eddie, Nakajima, Jun
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: Tuesday, January 20, 2015 7:08 PM
>
> Most of them have been unused since the dropping of 32-bit support, and
> the few remaining cases are more efficiently dealt with using a generic
> macro (and probably things should have been done that way from the
> beginning).
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 5/5] VMX: use cached "current" where available
2015-01-20 11:08 ` [PATCH 5/5] VMX: use cached "current" where available Jan Beulich
2015-01-20 18:03 ` Andrew Cooper
@ 2015-01-22 4:44 ` Tian, Kevin
1 sibling, 0 replies; 20+ messages in thread
From: Tian, Kevin @ 2015-01-22 4:44 UTC (permalink / raw)
To: Jan Beulich, xen-devel; +Cc: Dong, Eddie, Nakajima, Jun
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: Tuesday, January 20, 2015 7:08 PM
>
> ..., yielding better code.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 1/5] VMX: dump full guest state
2015-01-22 4:40 ` Tian, Kevin
@ 2015-01-22 11:56 ` Jan Beulich
0 siblings, 0 replies; 20+ messages in thread
From: Jan Beulich @ 2015-01-22 11:56 UTC (permalink / raw)
To: Kevin Tian; +Cc: xen-devel, Eddie Dong, Jun Nakajima
>>> On 22.01.15 at 05:40, <kevin.tian@intel.com> wrote:
>> From: Jan Beulich [mailto:JBeulich@suse.com]
>> Sent: Tuesday, January 20, 2015 7:06 PM
>>
>> Several guest state fields did not get dumped so far. Where suitable
>> (to reduce the amount of output) make some of the dumping conditional
>> upon guest settings (this isn't required for correctness as vmr()
>> already uses __vmread_safe(), i.e. it is fine to access non-existing
>> fields).
>>
>> Move CR3_TARGET_* and TSC_OFFSET processing into the control state
>> section, at once making the upper bound of CR3_TARGET_VALUEn printed
>> depend on CR3_TARGET_COUNT (which architecturally can be higher than
>> 4).
>>
>> Also rename GUEST_PDPTRn to GUEST_PDPTEn (matching the SDM naming)
>> and
>> group them as well as CR3_TARGET_VALUEn similar to EOI_EXIT_BITMAP.
>>
>> Finally, drop casts - they haven't been needed anymore since the
>> dropping of 32-bit support (and some of them were not really needed in
>> the first place). Introduce vmr16() and vmr32() helper macros to avoid
>> the "l" printk format modifier and at the same time validate that only
>> 16-/32-bit fields get accessed this way.
>>
>> Signed-off-by: Jan Beulich <jbeulich@suse.com>
>
> Acked-by: Kevin Tian <kevin.tian@intel.com>, given that vmr32 typo is fixed.
Sure. Any word on the question raised outside of the commit
message:
Is cpu_has_vmx_pat properly defined? Shouldn't this take into
consideration all three respective flags (VM_EXIT_SAVE_GUEST_PAT,
VM_EXIT_LOAD_HOST_PAT, and VM_ENTRY_LOAD_GUEST_PAT)?
Jan
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2015-01-22 11:56 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-20 10:58 [PATCH 0/5] VMX: assorted adjustments Jan Beulich
2015-01-20 11:05 ` [PATCH 1/5] VMX: dump full guest state Jan Beulich
2015-01-20 17:03 ` Andrew Cooper
2015-01-21 10:33 ` Jan Beulich
2015-01-22 4:40 ` Tian, Kevin
2015-01-22 11:56 ` Jan Beulich
2015-01-20 11:06 ` [PATCH 2/5] VMX: dump full host state Jan Beulich
2015-01-20 17:19 ` Andrew Cooper
2015-01-21 10:39 ` Jan Beulich
2015-01-22 4:40 ` Tian, Kevin
2015-01-20 11:06 ` [PATCH 3/5] VMX: dump further control state Jan Beulich
2015-01-20 17:39 ` Andrew Cooper
2015-01-22 4:41 ` Tian, Kevin
2015-01-20 11:07 ` [PATCH 4/5] VMX: drop VMCS *_HIGH enumerators Jan Beulich
2015-01-20 17:57 ` Andrew Cooper
2015-01-21 10:41 ` Jan Beulich
2015-01-22 4:41 ` Tian, Kevin
2015-01-20 11:08 ` [PATCH 5/5] VMX: use cached "current" where available Jan Beulich
2015-01-20 18:03 ` Andrew Cooper
2015-01-22 4:44 ` Tian, Kevin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.