[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [xen][hvm][tracing] Refine hvm tracing
# HG changeset patch # User George Dunlap <gdunlap@xxxxxxxxxxxxx> # Date 1190385217 -3600 # Node ID 305a8dbc264c45f76505182913877a2b9856d5d1 # Parent 7ed576909132407b0c98c8374c38179cda4cfd39 [xen][hvm][tracing] Refine hvm tracing This patch does two things: * Allows hvm traces to take advantage of the variable-size traces * Adds some hvm functionality This includes tracing actions like clts and lmsw, values of {p,mm}io reads and writes, and making different trace records for hvm domains running in 64-bit mode if the trace record includes a virtual address. --- xen/arch/x86/hvm/io.c | 4 + xen/arch/x86/hvm/svm/svm.c | 12 +-- xen/arch/x86/hvm/vmx/vmx.c | 16 ++-- xen/include/asm-x86/hvm/trace.h | 158 ++++++++++++++++++++++++++++++++++++---- xen/include/public/trace.h | 6 + 5 files changed, 173 insertions(+), 23 deletions(-) diff -r 7ed576909132 -r 305a8dbc264c xen/arch/x86/hvm/io.c --- a/xen/arch/x86/hvm/io.c Fri Sep 21 15:26:07 2007 +0100 +++ b/xen/arch/x86/hvm/io.c Fri Sep 21 15:33:37 2007 +0100 @@ -40,6 +40,7 @@ #include <asm/hvm/vpt.h> #include <asm/hvm/vpic.h> #include <asm/hvm/vlapic.h> +#include <asm/hvm/trace.h> #include <public/sched.h> #include <xen/iocap.h> @@ -476,6 +477,7 @@ static void hvm_pio_assist(struct cpu_us printk("Error: %s unknown port size\n", __FUNCTION__); domain_crash_synchronous(); } + HVMTRACE_1D(IO_ASSIST, current, p->data); } } @@ -491,6 +493,8 @@ static void hvm_mmio_assist(struct cpu_u dst = mmio_opp->operand[1]; size = operand_size(src); + HVMTRACE_1D(MMIO_ASSIST, current, p->data); + switch (mmio_opp->instr) { case INSTR_MOV: if (dst & REGISTER) { diff -r 7ed576909132 -r 305a8dbc264c xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Fri Sep 21 15:26:07 2007 +0100 +++ b/xen/arch/x86/hvm/svm/svm.c Fri Sep 21 15:33:37 2007 +0100 @@ -1482,7 +1482,7 @@ static void svm_io_instruction(struct vc if (dir==IOREQ_READ) HVMTRACE_2D(IO_READ, v, port, size); else - HVMTRACE_2D(IO_WRITE, v, port, size); + HVMTRACE_3D(IO_WRITE, v, port, size, regs->eax); HVM_DBG_LOG(DBG_LEVEL_IO, "svm_io_instruction: port 0x%x eip=%x:%"PRIx64", " @@ -1759,6 +1759,7 @@ static void svm_cr_access( vmcb->exception_intercepts &= ~(1U << TRAP_no_device); vmcb->cr0 &= ~X86_CR0_TS; /* clear TS */ v->arch.hvm_vcpu.guest_cr[0] &= ~X86_CR0_TS; /* clear TS */ + HVMTRACE_0D(CLTS, current); break; case INSTR_LMSW: @@ -1766,6 +1767,7 @@ static void svm_cr_access( value = get_reg(gpreg, regs, vmcb) & 0xF; value = (v->arch.hvm_vcpu.guest_cr[0] & ~0xF) | value; result = svm_set_cr0(value); + HVMTRACE_1D(LMSW, current, value); break; case INSTR_SMSW: @@ -1912,7 +1914,7 @@ static void svm_do_msr_access( regs->edx = msr_content >> 32; done: - HVMTRACE_2D(MSR_READ, v, ecx, msr_content); + hvmtrace_msr_read(v, ecx, msr_content); HVM_DBG_LOG(DBG_LEVEL_1, "returns: ecx=%x, eax=%lx, edx=%lx", ecx, (unsigned long)regs->eax, (unsigned long)regs->edx); @@ -1922,7 +1924,7 @@ static void svm_do_msr_access( { msr_content = (u32)regs->eax | ((u64)regs->edx << 32); - HVMTRACE_2D(MSR_WRITE, v, ecx, msr_content); + hvmtrace_msr_write(v, ecx, msr_content); switch (ecx) { @@ -2158,7 +2160,7 @@ asmlinkage void svm_vmexit_handler(struc exit_reason = vmcb->exitcode; - HVMTRACE_2D(VMEXIT, v, regs->eip, exit_reason); + hvmtrace_vmexit(v, regs->eip, exit_reason); if ( unlikely(exit_reason == VMEXIT_INVALID) ) { @@ -2378,7 +2380,7 @@ asmlinkage void svm_trace_vmentry(void) struct vcpu *v = current; /* This is the last C code before the VMRUN instruction. */ - HVMTRACE_0D(VMENTRY, v); + hvmtrace_vmentry(v); } /* diff -r 7ed576909132 -r 305a8dbc264c xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Fri Sep 21 15:26:07 2007 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Sep 21 15:33:37 2007 +0100 @@ -1825,7 +1825,7 @@ static void vmx_io_instruction(unsigned if ( dir == IOREQ_READ ) HVMTRACE_2D(IO_READ, current, port, size); else - HVMTRACE_2D(IO_WRITE, current, port, size); + HVMTRACE_3D(IO_WRITE, current, port, size, regs->eax); if ( port == 0xe9 && dir == IOREQ_WRITE && size == 1 ) hvm_print_line(current, regs->eax); /* guest debug output */ @@ -2249,11 +2249,13 @@ static int vmx_cr_access(unsigned long e v->arch.hvm_vcpu.guest_cr[0] &= ~X86_CR0_TS; /* clear TS */ __vmwrite(CR0_READ_SHADOW, v->arch.hvm_vcpu.guest_cr[0]); + HVMTRACE_0D(CLTS, current); break; case TYPE_LMSW: value = v->arch.hvm_vcpu.guest_cr[0]; value = (value & ~0xF) | (((exit_qualification & LMSW_SOURCE_DATA) >> 16) & 0xF); + HVMTRACE_1D(LMSW, current, value); return vmx_set_cr0(value); default: BUG(); @@ -2326,7 +2328,7 @@ static int vmx_do_msr_read(struct cpu_us regs->edx = msr_content >> 32; done: - HVMTRACE_2D(MSR_READ, v, ecx, msr_content); + hvmtrace_msr_read(v, ecx, msr_content); HVM_DBG_LOG(DBG_LEVEL_1, "returns: ecx=%x, eax=%lx, edx=%lx", ecx, (unsigned long)regs->eax, (unsigned long)regs->edx); @@ -2407,7 +2409,8 @@ static int vmx_do_msr_write(struct cpu_u ecx, (u32)regs->eax, (u32)regs->edx); msr_content = (u32)regs->eax | ((u64)regs->edx << 32); - HVMTRACE_2D(MSR_WRITE, v, ecx, msr_content); + + hvmtrace_msr_write(v, ecx, msr_content); switch ( ecx ) { @@ -2550,7 +2553,7 @@ asmlinkage void vmx_vmexit_handler(struc exit_reason = __vmread(VM_EXIT_REASON); - HVMTRACE_2D(VMEXIT, v, regs->eip, exit_reason); + hvmtrace_vmexit(VMEXIT, v, regs->eip, exit_reason); perfc_incra(vmexits, exit_reason); @@ -2637,7 +2640,7 @@ asmlinkage void vmx_vmexit_handler(struc if ( paging_fault(exit_qualification, regs) ) { - HVMTRACE_2D(PF_XEN, v, exit_qualification, regs->error_code); + hvmtrace_pf_xen(v, exit_qualification, regs->error_code); break; } @@ -2791,7 +2794,8 @@ asmlinkage void vmx_trace_vmentry(void) asmlinkage void vmx_trace_vmentry(void) { struct vcpu *v = current; - HVMTRACE_0D(VMENTRY, v); + + hvmtrace_vmentry(v); } /* diff -r 7ed576909132 -r 305a8dbc264c xen/include/asm-x86/hvm/trace.h --- a/xen/include/asm-x86/hvm/trace.h Fri Sep 21 15:26:07 2007 +0100 +++ b/xen/include/asm-x86/hvm/trace.h Fri Sep 21 15:33:37 2007 +0100 @@ -26,20 +26,154 @@ #define DO_TRC_HVM_VMMCALL 1 #define DO_TRC_HVM_HLT 1 #define DO_TRC_HVM_INVLPG 1 +#define DO_TRC_HVM_IO_ASSIST 1 +#define DO_TRC_HVM_MMIO_ASSIST 1 +#define DO_TRC_HVM_CLTS 1 +#define DO_TRC_HVM_LMSW 1 -#define HVMTRACE_4D(evt, vcpu, d1, d2, d3, d4) \ - do { \ - if (DO_TRC_HVM_ ## evt) \ - TRACE_5D( \ - TRC_HVM_ ## evt, \ - ((vcpu)->domain->domain_id<<16) + (vcpu)->vcpu_id, \ - d1, d2, d3, d4 \ - ); \ + + +static inline void hvmtrace_vmexit(struct vcpu *v, + unsigned long rip, + unsigned long exit_reason) +{ +#ifdef __x86_64__ + if(hvm_long_mode_enabled(v)) + { + struct { + unsigned did:16, vid:16; + unsigned exit_reason:32; + u64 rip; + } d; + + d.did = v->domain->domain_id; + d.vid = v->vcpu_id; + d.exit_reason = exit_reason; + d.rip = rip; + trace_var(TRC_HVM_VMEXIT64, 1/*cycles*/, sizeof(d), (unsigned char *)&d); + } else { +#endif + struct { + unsigned did:16, vid:16; + unsigned exit_reason:32; + u32 eip; + } d; + + d.did = v->domain->domain_id; + d.vid = v->vcpu_id; + d.exit_reason = exit_reason; + d.eip = rip; + trace_var(TRC_HVM_VMEXIT, 1/*cycles*/, sizeof(d), (unsigned char *)&d); +#ifdef __x86_64__ + } +#endif +} + + +static inline void hvmtrace_vmentry(struct vcpu *v) +{ + struct { + unsigned did:16, vid:16; + } d; + d.did = v->domain->domain_id; + d.vid = v->vcpu_id; + trace_var(TRC_HVM_VMENTRY, 1/*cycles*/, sizeof(d), (unsigned char *)&d); +} + +static inline void hvmtrace_msr_read(struct vcpu *v, u32 ecx, u64 msr_content) +{ + struct { + unsigned did:16, vid:16; + u32 ecx; + u64 msr_content; + } d; + d.did = v->domain->domain_id; + d.vid = v->vcpu_id; + d.ecx = ecx; + d.msr_content = msr_content; + trace_var(TRC_HVM_MSR_READ, 0/*!cycles*/, sizeof(d), (unsigned char *)&d); +} + +static inline void hvmtrace_msr_write(struct vcpu *v, u32 ecx, u64 msr_content) +{ + struct { + unsigned did:16, vid:16; + u32 ecx; + u64 msr_content; + } d; + d.did = v->domain->domain_id; + d.vid = v->vcpu_id; + d.ecx = ecx; + d.msr_content = msr_content; + trace_var(TRC_HVM_MSR_WRITE, 0/*!cycles*/,sizeof(d), (unsigned char *)&d); +} + +static inline void hvmtrace_pf_xen(struct vcpu *v, unsigned long va, + u32 error_code) +{ +#ifdef __x86_64__ + if(hvm_long_mode_enabled(v)) + { + struct { + unsigned did:16, vid:16; + u32 error_code; + u64 va; + } d; + d.did = v->domain->domain_id; + d.vid = v->vcpu_id; + d.error_code = error_code; + d.va = va; + trace_var(TRC_HVM_PF_XEN64, 0/*!cycles*/,sizeof(d), + (unsigned char *)&d); + } else { +#endif + struct { + unsigned did:16, vid:16; + u32 error_code; + u32 va; + } d; + d.did = v->domain->domain_id; + d.vid = v->vcpu_id; + d.error_code = error_code; + d.va = va; + trace_var(TRC_HVM_PF_XEN, 0/*!cycles*/,sizeof(d), (unsigned char *)&d); +#ifdef __x86_64__ + } +#endif +} + +#define HVMTRACE_ND(evt, vcpu, count, d1, d2, d3, d4) \ + do { \ + if (DO_TRC_HVM_ ## evt) \ + { \ + struct { \ + unsigned did:16, vid:16; \ + u32 d[4]; \ + } _d; \ + _d.did=(vcpu)->domain->domain_id; \ + _d.vid=(vcpu)->vcpu_id; \ + _d.d[0]=(d1); \ + _d.d[1]=(d2); \ + _d.d[2]=(d3); \ + _d.d[3]=(d4); \ + trace_var(TRC_HVM_ ## evt, 0/*!cycles*/, \ + sizeof(u32)*count+1, (unsigned char *)&_d); \ + } \ } while(0) -#define HVMTRACE_3D(evt, vcpu, d1, d2, d3) HVMTRACE_4D(evt, vcpu, d1, d2, d3, 0) -#define HVMTRACE_2D(evt, vcpu, d1, d2) HVMTRACE_4D(evt, vcpu, d1, d2, 0, 0) -#define HVMTRACE_1D(evt, vcpu, d1) HVMTRACE_4D(evt, vcpu, d1, 0, 0, 0) -#define HVMTRACE_0D(evt, vcpu) HVMTRACE_4D(evt, vcpu, 0, 0, 0, 0) +#define HVMTRACE_4D(evt, vcpu, d1, d2, d3, d4) HVMTRACE_ND(evt, vcpu, 4, d1, d2, d3, d4) +#define HVMTRACE_3D(evt, vcpu, d1, d2, d3) HVMTRACE_ND(evt, vcpu, 3, d1, d2, d3, 0) +#define HVMTRACE_2D(evt, vcpu, d1, d2) HVMTRACE_ND(evt, vcpu, 2, d1, d2, 0, 0) +#define HVMTRACE_1D(evt, vcpu, d1) HVMTRACE_ND(evt, vcpu, 1, d1, 0, 0, 0) +#define HVMTRACE_0D(evt, vcpu) HVMTRACE_ND(evt, vcpu, 0, 0, 0, 0, 0) #endif //__ASM_X86_HVM_TRACE_H__ +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r 7ed576909132 -r 305a8dbc264c xen/include/public/trace.h --- a/xen/include/public/trace.h Fri Sep 21 15:26:07 2007 +0100 +++ b/xen/include/public/trace.h Fri Sep 21 15:33:37 2007 +0100 @@ -77,6 +77,7 @@ /* trace events per subclass */ #define TRC_HVM_VMENTRY (TRC_HVM_ENTRYEXIT + 0x01) #define TRC_HVM_VMEXIT (TRC_HVM_ENTRYEXIT + 0x02) +#define TRC_HVM_VMEXIT64 (TRC_HVM_ENTRYEXIT + 0x03) #define TRC_HVM_PF_XEN (TRC_HVM_HANDLER + 0x01) #define TRC_HVM_PF_INJECT (TRC_HVM_HANDLER + 0x02) #define TRC_HVM_INJ_EXC (TRC_HVM_HANDLER + 0x03) @@ -98,6 +99,11 @@ #define TRC_HVM_HLT (TRC_HVM_HANDLER + 0x13) #define TRC_HVM_INVLPG (TRC_HVM_HANDLER + 0x14) #define TRC_HVM_MCE (TRC_HVM_HANDLER + 0x15) +#define TRC_HVM_IO_ASSIST (TRC_HVM_HANDLER + 0x16) +#define TRC_HVM_MMIO_ASSIST (TRC_HVM_HANDLER + 0x17) +#define TRC_HVM_CLTS (TRC_HVM_HANDLER + 0x18) +#define TRC_HVM_LMSW (TRC_HVM_HANDLER + 0x19) +#define TRC_HVM_PF_XEN64 (TRC_HVM_HANDLER + 0x20) /* This structure represents a single trace buffer record. */ struct t_rec { _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |