# HG changeset patch
# User adsharma@xxxxxxxxxxxxxxxxxxxx
# Node ID 27702550261679b71afae8d89ae09f6aff715510
# Parent a9873d384da48ba63a8235eb86c2663e8c08cd15
Tracing hooks for VMX domains
The low level asm instrumentation is needed to get precise TSC counts.
trace=n should have precisely 0 overhead because of this patch.
Signed-off-by: Yunfeng Zhai <yunfeng.zhao@xxxxxxxxx>
Signed-off-by: Arun Sharma <arun.sharma@xxxxxxxxx>
diff -r a9873d384da4 -r 277025502616 tools/xentrace/formats
--- a/tools/xentrace/formats Thu Aug 25 19:24:48 2005
+++ b/tools/xentrace/formats Thu Aug 25 20:27:03 2005
@@ -15,3 +15,7 @@
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 ]
+
+0x00090001 CPU%(cpu)d %(tsc)d VMENTRY
0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x
+0x00090002 CPU%(cpu)d %(tsc)d VMEXIT
0x%(1)08x 0x%(2)08x 0x%(3)08x
+
diff -r a9873d384da4 -r 277025502616 xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c Thu Aug 25 19:24:48 2005
+++ b/xen/arch/x86/vmx.c Thu Aug 25 20:27:03 2005
@@ -49,6 +49,13 @@
int vmcs_size;
unsigned int opt_vmx_debug_level = 0;
integer_param("vmx_debug", opt_vmx_debug_level);
+
+#ifdef TRACE_BUFFER
+static unsigned long trace_values[NR_CPUS][4];
+#define TRACE_VMEXIT(index,value) trace_values[current->processor][index]=value
+#else
+#define TRACE_VMEXIT(index,value) ((void)0)
+#endif
#ifdef __x86_64__
static struct msr_state percpu_msr[NR_CPUS];
@@ -381,6 +388,7 @@
if (!vmx_paging_enabled(current)){
handle_mmio(va, va);
+ TRACE_VMEXIT (2,2);
return 1;
}
gpa = gva_to_gpa(va);
@@ -393,12 +401,13 @@
__update_guest_eip(inst_len);
return 1;
}
+ TRACE_VMEXIT (2,2);
handle_mmio(va, gpa);
return 1;
}
result = shadow_fault(va, regs);
-
+ TRACE_VMEXIT (2,result);
#if 0
if ( !result )
{
@@ -608,6 +617,7 @@
addr = (exit_qualification >> 16) & (0xffff);
else
addr = regs->edx & 0xffff;
+ TRACE_VMEXIT (2,addr);
vio = get_vio(d->domain, d->vcpu_id);
if (vio == 0) {
@@ -1282,13 +1292,20 @@
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);
clts();
setup_fpu(current);
@@ -1301,6 +1318,7 @@
__vmwrite(CR0_READ_SHADOW, value);
break;
case TYPE_LMSW:
+ TRACE_VMEXIT(1,TYPE_LMSW);
__vmread(CR0_READ_SHADOW, &value);
value = (value & ~0xF) |
(((exit_qualification & LMSW_SOURCE_DATA) >> 16) & 0xF);
@@ -1544,6 +1562,7 @@
__vmread(GUEST_RIP, &eip);
TRACE_3D(TRC_VMX_VMEXIT, v->domain->domain_id, eip, exit_reason);
+ TRACE_VMEXIT(0,exit_reason);
switch (exit_reason) {
case EXIT_REASON_EXCEPTION_NMI:
@@ -1562,6 +1581,7 @@
__vmx_bug(®s);
vector &= 0xff;
+ TRACE_VMEXIT(1,vector);
perfc_incra(cause_vector, vector);
TRACE_3D(TRC_VMX_VECTOR, v->domain->domain_id, eip, vector);
@@ -1606,6 +1626,10 @@
{
__vmread(EXIT_QUALIFICATION, &va);
__vmread(VM_EXIT_INTR_ERROR_CODE, ®s.error_code);
+
+ TRACE_VMEXIT(3,regs.error_code);
+ TRACE_VMEXIT(4,va);
+
VMX_DBG_LOG(DBG_LEVEL_VMMU,
"eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
(unsigned long)regs.eax, (unsigned long)regs.ebx,
@@ -1680,6 +1704,8 @@
eip, inst_len, exit_qualification);
if (vmx_cr_access(exit_qualification, ®s))
__update_guest_eip(inst_len);
+ TRACE_VMEXIT(3,regs.error_code);
+ TRACE_VMEXIT(4,exit_qualification);
break;
}
case EXIT_REASON_DR_ACCESS:
@@ -1692,6 +1718,7 @@
__vmread(EXIT_QUALIFICATION, &exit_qualification);
__get_instruction_length(inst_len);
vmx_io_instruction(®s, exit_qualification, inst_len);
+ TRACE_VMEXIT(4,exit_qualification);
break;
case EXIT_REASON_MSR_READ:
__get_instruction_length(inst_len);
@@ -1726,6 +1753,25 @@
#endif
}
+#ifdef TRACE_BUFFER
+asmlinkage void trace_vmentry (void)
+{
+ TRACE_5D(TRC_VMENTRY,trace_values[current->processor][0],
+
trace_values[current->processor][1],trace_values[current->processor][2],
+
trace_values[current->processor][3],trace_values[current->processor][4]);
+ TRACE_VMEXIT(0,9);
+ TRACE_VMEXIT(1,9);
+ TRACE_VMEXIT(2,9);
+ TRACE_VMEXIT(3,9);
+ TRACE_VMEXIT(4,9);
+ return;
+}
+asmlinkage void trace_vmexit (void)
+{
+ TRACE_3D(TRC_VMEXIT,0,0,0);
+ return;
+}
+#endif
#endif /* CONFIG_VMX */
/*
diff -r a9873d384da4 -r 277025502616 xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Thu Aug 25 19:24:48 2005
+++ b/xen/arch/x86/x86_32/entry.S Thu Aug 25 20:27:03 2005
@@ -121,6 +121,9 @@
ENTRY(vmx_asm_vmexit_handler)
/* selectors are restored/saved by VMX */
VMX_SAVE_ALL_NOSEGREGS
+#ifdef TRACE_BUFFER
+ call trace_vmexit
+#endif
call vmx_vmexit_handler
jmp vmx_asm_do_resume
@@ -142,6 +145,9 @@
/* vmx_restore_all_guest */
call vmx_intr_assist
call load_cr2
+#ifdef TRACE_BUFFER
+ call trace_vmentry
+#endif
.endif
VMX_RESTORE_ALL_NOSEGREGS
/*
diff -r a9873d384da4 -r 277025502616 xen/include/public/trace.h
--- a/xen/include/public/trace.h Thu Aug 25 19:24:48 2005
+++ b/xen/include/public/trace.h Thu Aug 25 20:27:03 2005
@@ -23,7 +23,7 @@
#define TRC_VMXTIMER 0x00082000 /* VMX timer trace */
#define TRC_VMXINT 0x00084000 /* VMX interrupt trace */
#define TRC_VMXIO 0x00088000 /* VMX io emulation trace */
-
+#define TRC_VMEXIT_HANDLER 0x00090000 /* VMX handler trace */
/* Trace events per class */
@@ -49,6 +49,10 @@
#define TRC_VMX_INT (TRC_VMXINT + 1)
+#define TRC_VMEXIT (TRC_VMEXIT_HANDLER + 1)
+#define TRC_VMENTRY (TRC_VMEXIT_HANDLER + 2)
+
+
/* This structure represents a single trace buffer record. */
struct t_rec {
u64 cycles; /* cycle counter timestamp */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|