# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 47718a3d011e09178e093dd78e72851972f17ef6
# Parent b2e71d5740452c0c8fb5043a6a7f73fdeb7bcdfb
[HVM] XenTrace enhancement for HVM SMP guests.
Signed-off-by: Yunfeng Zhao <yunfeng.zhao@xxxxxxxxx>
Signed-off-by: Xin Li <xin.b.li@xxxxxxxxx>
---
tools/xentrace/formats | 29 +++++++++--
xen/arch/x86/hvm/svm/intr.c | 2
xen/arch/x86/hvm/svm/svm.c | 2
xen/arch/x86/hvm/vmx/io.c | 2
xen/arch/x86/hvm/vmx/vmx.c | 107 ++++++++++++++++++++++----------------------
xen/include/public/trace.h | 13 ++---
6 files changed, 86 insertions(+), 69 deletions(-)
diff -r b2e71d574045 -r 47718a3d011e tools/xentrace/formats
--- a/tools/xentrace/formats Wed Oct 18 19:14:34 2006 +0100
+++ b/tools/xentrace/formats Wed Oct 18 19:20:36 2006 +0100
@@ -12,10 +12,29 @@ 0x0002f00c CPU%(cpu)d %(tsc)d t_timer_f
0x0002f00c CPU%(cpu)d %(tsc)d t_timer_fn
0x0002f00d CPU%(cpu)d %(tsc)d dom_timer_fn
-0x00080001 CPU%(cpu)d %(tsc)d VMX_VMEXIT [ domid
= 0x%(1)08x, eip = 0x%(2)08x, reason = 0x%(3)08x ]
-0x00080002 CPU%(cpu)d %(tsc)d VMX_VECTOR [ domid
= 0x%(1)08x, eip = 0x%(2)08x, vector = 0x%(3)08x ]
-0x00080003 CPU%(cpu)d %(tsc)d VMX_INT [ domid
= 0x%(1)08x, trap = 0x%(2)08x, va = 0x%(3)08x ]
+0x00080001 CPU%(cpu)d %(tsc)d VMX_VMEXIT [ domid
= 0x%(1)08x, eip = 0x%(2)08x, reason = 0x%(3)08x ]
+0x00084001 CPU%(cpu)d %(tsc)d VMX_INTR [ domid
= 0x%(1)08x, trap = 0x%(2)08x, va = 0x%(3)08x ]
-0x00081001 CPU%(cpu)d %(tsc)d VMEXIT
0x%(1)08x 0x%(2)08x 0x%(3)08x
-0x00081002 CPU%(cpu)d %(tsc)d VMENTRY
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
+0x00081001 CPU%(cpu)d %(tsc)d VMEXIT_0
0x%(1)08x 0x%(2)08x 0x%(3)08x
+0x00082001 CPU%(cpu)d %(tsc)d VMENTRY_0
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
+0x00081002 CPU%(cpu)d %(tsc)d VMEXIT_1
0x%(1)08x 0x%(2)08x 0x%(3)08x
+0x00082002 CPU%(cpu)d %(tsc)d VMENTRY_1
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
+
+0x00081003 CPU%(cpu)d %(tsc)d VMEXIT_2
0x%(1)08x 0x%(2)08x 0x%(3)08x
+0x00082003 CPU%(cpu)d %(tsc)d VMENTRY_2
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
+
+0x00081004 CPU%(cpu)d %(tsc)d VMEXIT_3
0x%(1)08x 0x%(2)08x 0x%(3)08x
+0x00082004 CPU%(cpu)d %(tsc)d VMENTRY_3
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
+
+0x00081005 CPU%(cpu)d %(tsc)d VMEXIT_4
0x%(1)08x 0x%(2)08x 0x%(3)08x
+0x00082005 CPU%(cpu)d %(tsc)d VMENTRY_4
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
+
+0x00081006 CPU%(cpu)d %(tsc)d VMEXIT_5
0x%(1)08x 0x%(2)08x 0x%(3)08x
+0x00082006 CPU%(cpu)d %(tsc)d VMENTRY_5
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
+
+0x00081007 CPU%(cpu)d %(tsc)d VMEXIT_6
0x%(1)08x 0x%(2)08x 0x%(3)08x
+0x00082007 CPU%(cpu)d %(tsc)d VMENTRY_6
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
+
+0x00081008 CPU%(cpu)d %(tsc)d VMEXIT_7
0x%(1)08x 0x%(2)08x 0x%(3)08x
+0x00082008 CPU%(cpu)d %(tsc)d VMENTRY_7
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
diff -r b2e71d574045 -r 47718a3d011e xen/arch/x86/hvm/svm/intr.c
--- a/xen/arch/x86/hvm/svm/intr.c Wed Oct 18 19:14:34 2006 +0100
+++ b/xen/arch/x86/hvm/svm/intr.c Wed Oct 18 19:20:36 2006 +0100
@@ -145,7 +145,7 @@ asmlinkage void svm_intr_assist(void)
++pt->pending_intr_nr;
}
/* let's inject this interrupt */
- TRACE_3D(TRC_VMX_INT, v->domain->domain_id, intr_vector, 0);
+ TRACE_3D(TRC_VMX_INTR, v->domain->domain_id, intr_vector, 0);
svm_inject_extint(v, intr_vector, VMX_DELIVER_NO_ERROR_CODE);
hvm_interrupt_post(v, intr_vector, intr_type);
break;
diff -r b2e71d574045 -r 47718a3d011e xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Wed Oct 18 19:14:34 2006 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c Wed Oct 18 19:20:36 2006 +0100
@@ -2797,7 +2797,7 @@ asmlinkage void svm_vmexit_handler(struc
v->arch.hvm_svm.cpu_cr2 = va;
vmcb->cr2 = va;
- TRACE_3D(TRC_VMX_INT, v->domain->domain_id,
+ TRACE_3D(TRC_VMX_INTR, v->domain->domain_id,
VMEXIT_EXCEPTION_PF, va);
}
break;
diff -r b2e71d574045 -r 47718a3d011e xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Wed Oct 18 19:14:34 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/io.c Wed Oct 18 19:20:36 2006 +0100
@@ -153,7 +153,7 @@ asmlinkage void vmx_intr_assist(void)
case APIC_DM_FIXED:
case APIC_DM_LOWEST:
vmx_inject_extint(v, highest_vector, VMX_DELIVER_NO_ERROR_CODE);
- TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0);
+ TRACE_3D(TRC_VMX_INTR, v->domain->domain_id, highest_vector, 0);
break;
case APIC_DM_SMI:
diff -r b2e71d574045 -r 47718a3d011e xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Wed Oct 18 19:14:34 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Oct 18 19:20:36 2006 +0100
@@ -871,7 +871,7 @@ static int vmx_do_page_fault(unsigned lo
result = shadow_fault(va, regs);
- TRACE_VMEXIT (2,result);
+ TRACE_VMEXIT(2, result);
#if 0
if ( !result )
{
@@ -902,7 +902,7 @@ static void vmx_do_no_device_fault(void)
}
#define bitmaskof(idx) (1U << ((idx)&31))
-static void vmx_vmexit_do_cpuid(struct cpu_user_regs *regs)
+static void vmx_do_cpuid(struct cpu_user_regs *regs)
{
unsigned int input = (unsigned int)regs->eax;
unsigned int count = (unsigned int)regs->ecx;
@@ -1027,14 +1027,14 @@ static void vmx_dr_access(unsigned long
* Invalidate the TLB for va. Invalidate the shadow page corresponding
* the address va.
*/
-static void vmx_vmexit_do_invlpg(unsigned long va)
+static void vmx_do_invlpg(unsigned long va)
{
unsigned long eip;
struct vcpu *v = current;
__vmread(GUEST_RIP, &eip);
- HVM_DBG_LOG(DBG_LEVEL_VMMU, "vmx_vmexit_do_invlpg: eip=%lx, va=%lx",
+ HVM_DBG_LOG(DBG_LEVEL_VMMU, "eip=%lx, va=%lx",
eip, va);
/*
@@ -1646,6 +1646,10 @@ static int mov_to_cr(int gp, int cr, str
printk("invalid gp: %d\n", gp);
__hvm_bug(regs);
}
+
+ TRACE_VMEXIT(1, TYPE_MOV_TO_CR);
+ TRACE_VMEXIT(2, cr);
+ TRACE_VMEXIT(3, value);
HVM_DBG_LOG(DBG_LEVEL_1, "CR%d, value = %lx", cr, value);
@@ -1828,6 +1832,10 @@ static void mov_from_cr(int cr, int gp,
__hvm_bug(regs);
}
+ TRACE_VMEXIT(1, TYPE_MOV_FROM_CR);
+ TRACE_VMEXIT(2, cr);
+ TRACE_VMEXIT(3, value);
+
HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR%d, value = %lx", cr, value);
}
@@ -1842,20 +1850,14 @@ static int vmx_cr_access(unsigned long e
case TYPE_MOV_TO_CR:
gp = exit_qualification & CONTROL_REG_ACCESS_REG;
cr = exit_qualification & CONTROL_REG_ACCESS_NUM;
- TRACE_VMEXIT(1,TYPE_MOV_TO_CR);
- TRACE_VMEXIT(2,cr);
- TRACE_VMEXIT(3,gp);
return mov_to_cr(gp, cr, regs);
case TYPE_MOV_FROM_CR:
gp = exit_qualification & CONTROL_REG_ACCESS_REG;
cr = exit_qualification & CONTROL_REG_ACCESS_NUM;
- TRACE_VMEXIT(1,TYPE_MOV_FROM_CR);
- TRACE_VMEXIT(2,cr);
- TRACE_VMEXIT(3,gp);
mov_from_cr(cr, gp, regs);
break;
case TYPE_CLTS:
- TRACE_VMEXIT(1,TYPE_CLTS);
+ TRACE_VMEXIT(1, TYPE_CLTS);
/* We initialise the FPU now, to avoid needing another vmexit. */
setup_fpu(v);
@@ -1870,10 +1872,11 @@ static int vmx_cr_access(unsigned long e
__vmwrite(CR0_READ_SHADOW, value);
break;
case TYPE_LMSW:
- TRACE_VMEXIT(1,TYPE_LMSW);
__vmread_vcpu(v, CR0_READ_SHADOW, &value);
value = (value & ~0xF) |
(((exit_qualification & LMSW_SOURCE_DATA) >> 16) & 0xF);
+ TRACE_VMEXIT(1, TYPE_LMSW);
+ TRACE_VMEXIT(2, value);
return vmx_set_cr0(value);
break;
default:
@@ -1889,7 +1892,7 @@ static inline void vmx_do_msr_read(struc
u32 eax, edx;
struct vcpu *v = current;
- HVM_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_read: ecx=%lx, eax=%lx, edx=%lx",
+ HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%lx, eax=%lx, edx=%lx",
(unsigned long)regs->ecx, (unsigned long)regs->eax,
(unsigned long)regs->edx);
switch (regs->ecx) {
@@ -1926,8 +1929,7 @@ static inline void vmx_do_msr_read(struc
regs->eax = msr_content & 0xFFFFFFFF;
regs->edx = msr_content >> 32;
- HVM_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_read returns: "
- "ecx=%lx, eax=%lx, edx=%lx",
+ HVM_DBG_LOG(DBG_LEVEL_1, "returns: ecx=%lx, eax=%lx, edx=%lx",
(unsigned long)regs->ecx, (unsigned long)regs->eax,
(unsigned long)regs->edx);
}
@@ -1937,7 +1939,7 @@ static inline void vmx_do_msr_write(stru
u64 msr_content;
struct vcpu *v = current;
- HVM_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_write: ecx=%lx, eax=%lx, edx=%lx",
+ HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%lx, eax=%lx, edx=%lx",
(unsigned long)regs->ecx, (unsigned long)regs->eax,
(unsigned long)regs->edx);
@@ -1965,20 +1967,19 @@ static inline void vmx_do_msr_write(stru
break;
}
- HVM_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_write returns: "
- "ecx=%lx, eax=%lx, edx=%lx",
+ HVM_DBG_LOG(DBG_LEVEL_1, "returns: ecx=%lx, eax=%lx, edx=%lx",
(unsigned long)regs->ecx, (unsigned long)regs->eax,
(unsigned long)regs->edx);
}
-void vmx_vmexit_do_hlt(void)
+static void vmx_do_hlt(void)
{
unsigned long rflags;
__vmread(GUEST_RFLAGS, &rflags);
hvm_hlt(rflags);
}
-static inline void vmx_vmexit_do_extint(struct cpu_user_regs *regs)
+static inline void vmx_do_extint(struct cpu_user_regs *regs)
{
unsigned int vector;
int error;
@@ -1999,7 +2000,7 @@ static inline void vmx_vmexit_do_extint(
__hvm_bug(regs);
vector &= INTR_INFO_VECTOR_MASK;
- TRACE_VMEXIT(1,vector);
+ TRACE_VMEXIT(1, vector);
switch(vector) {
case LOCAL_TIMER_VECTOR:
@@ -2130,7 +2131,7 @@ asmlinkage void vmx_vmexit_handler(struc
asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
{
unsigned int exit_reason;
- unsigned long exit_qualification, rip, inst_len = 0;
+ unsigned long exit_qualification, inst_len = 0;
struct vcpu *v = current;
__vmread(VM_EXIT_REASON, &exit_reason);
@@ -2172,7 +2173,7 @@ asmlinkage void vmx_vmexit_handler(struc
domain_crash_synchronous();
}
- TRACE_VMEXIT(0,exit_reason);
+ TRACE_VMEXIT(0, exit_reason);
switch ( exit_reason )
{
@@ -2184,14 +2185,13 @@ asmlinkage void vmx_vmexit_handler(struc
* (2) NMI
*/
unsigned int vector;
- unsigned long va;
if ( __vmread(VM_EXIT_INTR_INFO, &vector) ||
!(vector & INTR_INFO_VALID_MASK) )
domain_crash_synchronous();
vector &= INTR_INFO_VECTOR_MASK;
- TRACE_VMEXIT(1,vector);
+ TRACE_VMEXIT(1, vector);
perfc_incra(cause_vector, vector);
switch ( vector ) {
@@ -2247,11 +2247,11 @@ asmlinkage void vmx_vmexit_handler(struc
}
case TRAP_page_fault:
{
- __vmread(EXIT_QUALIFICATION, &va);
+ __vmread(EXIT_QUALIFICATION, &exit_qualification);
__vmread(VM_EXIT_INTR_ERROR_CODE, ®s->error_code);
TRACE_VMEXIT(3, regs->error_code);
- TRACE_VMEXIT(4, va);
+ TRACE_VMEXIT(4, exit_qualification);
HVM_DBG_LOG(DBG_LEVEL_VMMU,
"eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
@@ -2259,13 +2259,13 @@ asmlinkage void vmx_vmexit_handler(struc
(unsigned long)regs->ecx, (unsigned long)regs->edx,
(unsigned long)regs->esi, (unsigned long)regs->edi);
- if ( !vmx_do_page_fault(va, regs) )
+ if ( !vmx_do_page_fault(exit_qualification, regs) )
{
/* Inject #PG using Interruption-Information Fields. */
vmx_inject_hw_exception(v, TRAP_page_fault, regs->error_code);
- v->arch.hvm_vmx.cpu_cr2 = va;
- TRACE_3D(TRC_VMX_INT, v->domain->domain_id,
- TRAP_page_fault, va);
+ v->arch.hvm_vmx.cpu_cr2 = exit_qualification;
+ TRACE_3D(TRC_VMX_INTR, v->domain->domain_id,
+ TRAP_page_fault, exit_qualification);
}
break;
}
@@ -2279,7 +2279,7 @@ asmlinkage void vmx_vmexit_handler(struc
break;
}
case EXIT_REASON_EXTERNAL_INTERRUPT:
- vmx_vmexit_do_extint(regs);
+ vmx_do_extint(regs);
break;
case EXIT_REASON_TRIPLE_FAULT:
domain_crash_synchronous();
@@ -2296,39 +2296,35 @@ asmlinkage void vmx_vmexit_handler(struc
case EXIT_REASON_CPUID:
inst_len = __get_instruction_length(); /* Safe: CPUID */
__update_guest_eip(inst_len);
- vmx_vmexit_do_cpuid(regs);
+ vmx_do_cpuid(regs);
break;
case EXIT_REASON_HLT:
inst_len = __get_instruction_length(); /* Safe: HLT */
__update_guest_eip(inst_len);
- vmx_vmexit_do_hlt();
+ vmx_do_hlt();
break;
case EXIT_REASON_INVLPG:
{
- unsigned long va;
inst_len = __get_instruction_length(); /* Safe: INVLPG */
__update_guest_eip(inst_len);
- __vmread(EXIT_QUALIFICATION, &va);
- vmx_vmexit_do_invlpg(va);
+ __vmread(EXIT_QUALIFICATION, &exit_qualification);
+ vmx_do_invlpg(exit_qualification);
+ TRACE_VMEXIT(4, exit_qualification);
break;
}
case EXIT_REASON_VMCALL:
{
inst_len = __get_instruction_length(); /* Safe: VMCALL */
__update_guest_eip(inst_len);
- __vmread(GUEST_RIP, &rip);
- __vmread(EXIT_QUALIFICATION, &exit_qualification);
hvm_do_hypercall(regs);
break;
}
case EXIT_REASON_CR_ACCESS:
{
- __vmread(GUEST_RIP, &rip);
__vmread(EXIT_QUALIFICATION, &exit_qualification);
inst_len = __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */
if ( vmx_cr_access(exit_qualification, regs) )
__update_guest_eip(inst_len);
- TRACE_VMEXIT(3, regs->error_code);
TRACE_VMEXIT(4, exit_qualification);
break;
}
@@ -2340,17 +2336,23 @@ asmlinkage void vmx_vmexit_handler(struc
__vmread(EXIT_QUALIFICATION, &exit_qualification);
inst_len = __get_instruction_length(); /* Safe: IN, INS, OUT, OUTS */
vmx_io_instruction(exit_qualification, inst_len);
- TRACE_VMEXIT(4,exit_qualification);
+ TRACE_VMEXIT(4, exit_qualification);
break;
case EXIT_REASON_MSR_READ:
inst_len = __get_instruction_length(); /* Safe: RDMSR */
__update_guest_eip(inst_len);
vmx_do_msr_read(regs);
+ TRACE_VMEXIT(1, regs->ecx);
+ TRACE_VMEXIT(2, regs->eax);
+ TRACE_VMEXIT(3, regs->edx);
break;
case EXIT_REASON_MSR_WRITE:
inst_len = __get_instruction_length(); /* Safe: WRMSR */
__update_guest_eip(inst_len);
vmx_do_msr_write(regs);
+ TRACE_VMEXIT(1, regs->ecx);
+ TRACE_VMEXIT(2, regs->eax);
+ TRACE_VMEXIT(3, regs->edx);
break;
case EXIT_REASON_MWAIT_INSTRUCTION:
case EXIT_REASON_MONITOR_INSTRUCTION:
@@ -2384,26 +2386,25 @@ asmlinkage void vmx_load_cr2(void)
asm volatile("mov %0,%%cr2": :"r" (v->arch.hvm_vmx.cpu_cr2));
}
-asmlinkage void vmx_trace_vmentry (void)
-{
- TRACE_5D(TRC_VMX_VMENTRY,
+asmlinkage void vmx_trace_vmentry(void)
+{
+ TRACE_5D(TRC_VMX_VMENTRY + current->vcpu_id,
this_cpu(trace_values)[0],
this_cpu(trace_values)[1],
this_cpu(trace_values)[2],
this_cpu(trace_values)[3],
this_cpu(trace_values)[4]);
- TRACE_VMEXIT(0,9);
- TRACE_VMEXIT(1,9);
- TRACE_VMEXIT(2,9);
- TRACE_VMEXIT(3,9);
- TRACE_VMEXIT(4,9);
- return;
+
+ TRACE_VMEXIT(0, 0);
+ TRACE_VMEXIT(1, 0);
+ TRACE_VMEXIT(2, 0);
+ TRACE_VMEXIT(3, 0);
+ TRACE_VMEXIT(4, 0);
}
asmlinkage void vmx_trace_vmexit (void)
{
- TRACE_3D(TRC_VMX_VMEXIT,0,0,0);
- return;
+ TRACE_3D(TRC_VMX_VMEXIT + current->vcpu_id, 0, 0, 0);
}
/*
diff -r b2e71d574045 -r 47718a3d011e xen/include/public/trace.h
--- a/xen/include/public/trace.h Wed Oct 18 19:14:34 2006 +0100
+++ b/xen/include/public/trace.h Wed Oct 18 19:20:36 2006 +0100
@@ -19,11 +19,11 @@
/* Trace subclasses */
#define TRC_SUBCLS_SHIFT 12
+
/* trace subclasses for VMX */
#define TRC_VMXEXIT 0x00081000 /* VMX exit trace */
-#define TRC_VMXTIMER 0x00082000 /* VMX timer trace */
-#define TRC_VMXINT 0x00084000 /* VMX interrupt trace */
-#define TRC_VMXIO 0x00088000 /* VMX io emulation trace */
+#define TRC_VMXENTRY 0x00082000 /* VMX exit trace */
+#define TRC_VMXINTR 0x00084000 /* VMX interrupt trace */
/* Trace events per class */
#define TRC_LOST_RECORDS (TRC_GEN + 1)
@@ -50,11 +50,8 @@
/* trace events per subclass */
#define TRC_VMX_VMEXIT (TRC_VMXEXIT + 1)
-#define TRC_VMX_VMENTRY (TRC_VMXEXIT + 2)
-
-#define TRC_VMX_TIMER_INTR (TRC_VMXTIMER + 1)
-
-#define TRC_VMX_INT (TRC_VMXINT + 1)
+#define TRC_VMX_VMENTRY (TRC_VMXENTRY + 1)
+#define TRC_VMX_INTR (TRC_VMXINTR + 1)
/* This structure represents a single trace buffer record. */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|