* nested virtualization: tracing capabilities
@ 2011-04-07 14:26 Christoph Egger
2011-04-07 14:49 ` Tim Deegan
0 siblings, 1 reply; 2+ messages in thread
From: Christoph Egger @ 2011-04-07 14:26 UTC (permalink / raw)
To: xen-devel@lists.xensource.com
[-- Attachment #1: Type: text/plain, Size: 404 bytes --]
Hi,
Attached patch allows xentrace to track what happens with l1 and l2 guests.
Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
--
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85689 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo, Andrew Bowd
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632
[-- Attachment #2: xen_nh_tracing.diff --]
[-- Type: text/plain, Size: 9936 bytes --]
# HG changeset patch
# User cegger
# Date 1302180533 -7200
Tracing facility for nested virtualization
Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
diff -r ee39668a7840 -r aef9e2deb9a7 tools/xentrace/formats
--- a/tools/xentrace/formats
+++ b/tools/xentrace/formats
@@ -5,6 +5,7 @@ 0x0001f002 CPU%(cpu)d %(tsc)d (+%(relt
0x0001f003 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) cpu_change 0x%(1)08x
0x0001f004 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) trace_irq [ vector = %(1)d, count = %(2)d, tot_cycles = 0x%(3)08x, max_cycles = 0x%(4)08x ]
+0x00021002 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) continue_running [ dom:vcpu = 0x%(1)08x ]
0x00021011 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) running_to_runnable [ dom:vcpu = 0x%(1)08x ]
0x00021021 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) running_to_blocked [ dom:vcpu = 0x%(1)08x ]
0x00021031 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) running_to_offline [ dom:vcpu = 0x%(1)08x ]
@@ -34,7 +35,10 @@ 0x0002800d CPU%(cpu)d %(tsc)d (+%(relt
0x0002800e CPU%(cpu)d %(tsc)d (+%(reltsc)8d) switch_infprev [ old_domid = 0x%(1)08x, runtime = %(2)d ]
0x0002800f CPU%(cpu)d %(tsc)d (+%(reltsc)8d) switch_infnext [ new_domid = 0x%(1)08x, time = %(2)d, r_time = %(3)d ]
-0x00081001 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) VMENTRY
+0x00081401 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) nVMENTRY [ rIP = 0x%(1)08x ]
+0x00081402 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) nVMEXIT [ exitcode = 0x%(1)08x, rIP = 0x%(2)08x, intercepted = 0x%(5)01x ]
+0x00081502 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) nVMEXIT [ exitcode = 0x%(1)08x, rIP = 0x%(3)08x%(2)08x, intercepted = 0x%(6)01x ]
+0x00081001 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) VMENTRY [ rIP = 0x%(1)08x ]
0x00081002 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) VMEXIT [ exitcode = 0x%(1)08x, rIP = 0x%(2)08x ]
0x00081102 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) VMEXIT [ exitcode = 0x%(1)08x, rIP = 0x%(3)08x%(2)08x ]
0x00082001 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) PF_XEN [ errorcode = 0x%(2)02x, virt = 0x%(1)08x ]
@@ -63,15 +67,19 @@ 0x00082013 CPU%(cpu)d %(tsc)d (+%(relt
0x00082014 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) INVLPG [ is invlpga? = %(1)d, virt = 0x%(2)08x ]
0x00082114 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) INVLPG [ is invlpga? = %(1)d, virt = 0x%(3)08x%(2)08x ]
0x00082015 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) MCE
-0x00082016 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) IOPORT_READ [ data = 0x%(1)04x ]
-0x00082216 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) IOPORT_WRITE [ data = 0x%(1)04x ]
-0x00082017 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) MMIO_READ [ data = 0x%(1)04x ]
-0x00082217 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) MMIO_WRITE [ data = 0x%(1)04x ]
+0x00082016 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) IOPORT_READ [ data = 0x%(1)04x, value = 0x%(2)08x ]
+0x00082216 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) IOPORT_WRITE [ data = 0x%(1)04x, value = 0x%(2)08x ]
+0x00082017 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) MMIO_READ [ data = 0x%(1)04x, ip = 0x%(3)08x ]
+0x00082217 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) MMIO_WRITE [ data = 0x%(1)04x, ip = 0x%(3)08x, value = 0x%(2)08x ]
0x00082018 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) CLTS
0x00082019 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) LMSW [ value = 0x%(1)08x ]
0x00082119 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) LMSW [ value = 0x%(2)08x%(1)08x ]
+0x0008201a CPU%(cpu)d %(tsc)d (+%(reltsc)8d) RDTSC [ value = 0x%(2)08x%(1)08x ]
0x00082020 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) INTR_WINDOW [ value = 0x%(1)08x ]
0x00082021 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) NPF [ gpa = 0x%(2)08x%(1)08x mfn = 0x%(4)08x%(3)08x qual = 0x%(5)04x p2mt = 0x%(6)04x ]
+0x00082022 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) VINTR
+0x00082023 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) INVD
+0x00082024 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) WBINVD
0x0010f001 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) page_grant_map [ domid = %(1)d ]
0x0010f002 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) page_grant_unmap [ domid = %(1)d ]
diff -r ee39668a7840 -r aef9e2deb9a7 xen/arch/x86/hvm/emulate.c
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -45,6 +45,9 @@ static void hvmtrace_io_assist(int is_mm
size += 4;
}
+ *(uint32_t *)&buffer[size] = guest_cpu_user_regs()->eip;
+ size += 4;
+
trace_var(event, 0/*!cycles*/, size, buffer);
}
@@ -153,8 +156,6 @@ static int hvmemul_do_io(
p->df = df;
p->data = value;
- hvmtrace_io_assist(is_mmio, p);
-
if ( is_mmio )
{
rc = hvm_mmio_intercept(p);
@@ -166,6 +167,8 @@ static int hvmemul_do_io(
rc = hvm_portio_intercept(p);
}
+ hvmtrace_io_assist(is_mmio, p);
+
switch ( rc )
{
case X86EMUL_OKAY:
diff -r ee39668a7840 -r aef9e2deb9a7 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -1108,20 +1108,24 @@ void hvm_hlt(unsigned long rflags)
{
struct vcpu *curr = current;
- if ( hvm_event_pending(curr) )
+ if ( hvm_event_pending(curr) ) {
+ HVMTRACE_2D(HLT, /* pending */ 1, /* shutdown */ 0);
return;
+ }
/*
* If we halt with interrupts disabled, that's a pretty sure sign that we
* want to shut down. In a real processor, NMIs are the only way to break
* out of this.
*/
- if ( unlikely(!(rflags & X86_EFLAGS_IF)) )
+ if ( unlikely(!(rflags & X86_EFLAGS_IF)) ) {
+ HVMTRACE_2D(HLT, /* pending */ 0, /* shutdown */ 1);
return hvm_vcpu_down(curr);
+ }
do_sched_op_compat(SCHEDOP_block, 0);
- HVMTRACE_1D(HLT, /* pending = */ vcpu_runnable(curr));
+ HVMTRACE_2D(HLT, /* pending = */ vcpu_runnable(curr), /* shutdown */ 0);
}
void hvm_triple_fault(void)
diff -r ee39668a7840 -r aef9e2deb9a7 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1679,6 +1679,25 @@ asmlinkage void svm_vmexit_handler(struc
exit_reason = vmcb->exitcode;
+ if ( tb_init_done ) {
+ bool_t intercepted = 0;
+ if (vcpu_guestmode)
+ intercepted = nsvm_vmcb_guest_intercepts_exitcode(v, regs,
+ exit_reason);
+
+ if ( hvm_long_mode_enabled(v) ) {
+ HVMTRACE_ND(VMEXIT64 | (TRC_HVM_NESTEDFLAG * vcpu_guestmode),
+ 1/*cycles*/, 6, exit_reason,
+ (uint32_t)regs->eip, (uint32_t)((uint64_t)regs->eip >> 32),
+ intercepted, 0, 0);
+ } else {
+ HVMTRACE_ND(VMEXIT | (TRC_HVM_NESTEDFLAG * vcpu_guestmode),
+ 1/*cycles*/, 5, exit_reason,
+ (uint32_t)regs->eip,
+ intercepted, 0, 0, 0);
+ }
+ }
+
if ( vcpu_guestmode ) {
enum nestedhvm_vmexits nsret;
struct nestedvcpu *nv = &vcpu_nestedhvm(v);
@@ -1739,15 +1758,6 @@ asmlinkage void svm_vmexit_handler(struc
}
}
- if ( hvm_long_mode_enabled(v) )
- HVMTRACE_ND(VMEXIT64, 1/*cycles*/, 3, exit_reason,
- (uint32_t)regs->eip, (uint32_t)((uint64_t)regs->eip >> 32),
- 0, 0, 0);
- else
- HVMTRACE_ND(VMEXIT, 1/*cycles*/, 2, exit_reason,
- (uint32_t)regs->eip,
- 0, 0, 0, 0);
-
if ( unlikely(exit_reason == VMEXIT_INVALID) )
{
svm_vmcb_dump(__func__, vmcb);
@@ -1841,7 +1851,10 @@ asmlinkage void svm_vmexit_handler(struc
break;
case VMEXIT_VINTR: {
- u32 general1_intercepts = vmcb_get_general1_intercepts(vmcb);
+ uint32_t general1_intercepts;
+
+ HVMTRACE_0D(VINTR);
+ general1_intercepts = vmcb_get_general1_intercepts(vmcb);
intr = vmcb_get_vintr(vmcb);
intr.fields.irq = 0;
@@ -1853,7 +1866,12 @@ asmlinkage void svm_vmexit_handler(struc
}
case VMEXIT_INVD:
+ HVMTRACE_0D(INVD);
+ svm_vmexit_do_invalidate_cache(regs);
+ break;
+
case VMEXIT_WBINVD:
+ HVMTRACE_0D(WBINVD);
svm_vmexit_do_invalidate_cache(regs);
break;
@@ -2027,7 +2045,10 @@ asmlinkage void svm_vmexit_handler(struc
asmlinkage void svm_trace_vmentry(void)
{
- HVMTRACE_ND (VMENTRY, 1/*cycles*/, 0, 0, 0, 0, 0, 0, 0);
+ struct vcpu *v = current;
+ HVMTRACE_ND(VMENTRY | (TRC_HVM_NESTEDFLAG * !!(nestedhvm_vcpu_in_guestmode(v))),
+ 1/*cycles*/, 1, v->arch.hvm_svm.vmcb->rip,
+ 0, 0, 0, 0, 0);
}
/*
diff -r ee39668a7840 -r aef9e2deb9a7 xen/include/asm-x86/hvm/trace.h
--- a/xen/include/asm-x86/hvm/trace.h
+++ b/xen/include/asm-x86/hvm/trace.h
@@ -50,7 +50,9 @@
#define DO_TRC_HVM_CLTS DEFAULT_HVM_MISC
#define DO_TRC_HVM_LMSW DEFAULT_HVM_MISC
#define DO_TRC_HVM_LMSW64 DEFAULT_HVM_MISC
-
+#define DO_TRC_HVM_VINTR DEFAULT_HVM_MISC
+#define DO_TRC_HVM_INVD DEFAULT_HVM_MISC
+#define DO_TRC_HVM_WBINVD DEFAULT_HVM_MISC
#ifdef __x86_64__
#define TRC_PAR_LONG(par) ((par)&0xFFFFFFFF),((par)>>32)
diff -r ee39668a7840 -r aef9e2deb9a7 xen/include/public/trace.h
--- a/xen/include/public/trace.h
+++ b/xen/include/public/trace.h
@@ -123,6 +123,7 @@
#define TRC_SHADOW_RESYNC_ONLY (TRC_SHADOW + 15)
/* trace events per subclass */
+#define TRC_HVM_NESTEDFLAG (0x400)
#define TRC_HVM_VMENTRY (TRC_HVM_ENTRYEXIT + 0x01)
#define TRC_HVM_VMEXIT (TRC_HVM_ENTRYEXIT + 0x02)
#define TRC_HVM_VMEXIT64 (TRC_HVM_ENTRYEXIT + TRC_64_FLAG + 0x02)
@@ -160,6 +161,9 @@
#define TRC_HVM_RDTSC (TRC_HVM_HANDLER + 0x1a)
#define TRC_HVM_INTR_WINDOW (TRC_HVM_HANDLER + 0x20)
#define TRC_HVM_NPF (TRC_HVM_HANDLER + 0x21)
+#define TRC_HVM_VINTR (TRC_HVM_HANDLER + 0x22)
+#define TRC_HVM_INVD (TRC_HVM_HANDLER + 0x23)
+#define TRC_HVM_WBINVD (TRC_HVM_HANDLER + 0x24)
#define TRC_HVM_IOPORT_WRITE (TRC_HVM_HANDLER + 0x216)
#define TRC_HVM_IOMEM_WRITE (TRC_HVM_HANDLER + 0x217)
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: nested virtualization: tracing capabilities
2011-04-07 14:26 nested virtualization: tracing capabilities Christoph Egger
@ 2011-04-07 14:49 ` Tim Deegan
0 siblings, 0 replies; 2+ messages in thread
From: Tim Deegan @ 2011-04-07 14:49 UTC (permalink / raw)
To: Christoph Egger; +Cc: xen-devel@lists.xensource.com
At 15:26 +0100 on 07 Apr (1302189962), Christoph Egger wrote:
> # HG changeset patch
> # User cegger
> # Date 1302180533 -7200
> Tracing facility for nested virtualization
>
> Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
>
> diff -r ee39668a7840 -r aef9e2deb9a7 tools/xentrace/formats
> --- a/tools/xentrace/formats
> +++ b/tools/xentrace/formats
> @@ -5,6 +5,7 @@ 0x0001f002 CPU%(cpu)d %(tsc)d (+%(relt
> 0x0001f003 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) cpu_change 0x%(1)08x
> 0x0001f004 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) trace_irq [ vector = %(1)d, count = %(2)d, tot_cycles = 0x%(3)08x, max_cycles = 0x%(4)08x ]
>
> +0x00021002 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) continue_running [ dom:vcpu = 0x%(1)08x ]
> 0x00021011 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) running_to_runnable [ dom:vcpu = 0x%(1)08x ]
> 0x00021021 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) running_to_blocked [ dom:vcpu = 0x%(1)08x ]
> 0x00021031 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) running_to_offline [ dom:vcpu = 0x%(1)08x ]
> @@ -34,7 +35,10 @@ 0x0002800d CPU%(cpu)d %(tsc)d (+%(relt
> 0x0002800e CPU%(cpu)d %(tsc)d (+%(reltsc)8d) switch_infprev [ old_domid = 0x%(1)08x, runtime = %(2)d ]
> 0x0002800f CPU%(cpu)d %(tsc)d (+%(reltsc)8d) switch_infnext [ new_domid = 0x%(1)08x, time = %(2)d, r_time = %(3)d ]
>
> -0x00081001 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) VMENTRY
> +0x00081401 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) nVMENTRY [ rIP = 0x%(1)08x ]
> +0x00081402 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) nVMEXIT [ exitcode = 0x%(1)08x, rIP = 0x%(2)08x, intercepted = 0x%(5)01x ]
> +0x00081502 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) nVMEXIT [ exitcode = 0x%(1)08x, rIP = 0x%(3)08x%(2)08x, intercepted = 0x%(6)01x ]
> +0x00081001 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) VMENTRY [ rIP = 0x%(1)08x ]
Shouldn't these be kept in numerical order?
> diff -r ee39668a7840 -r aef9e2deb9a7 xen/arch/x86/hvm/emulate.c
> --- a/xen/arch/x86/hvm/emulate.c
> +++ b/xen/arch/x86/hvm/emulate.c
> @@ -45,6 +45,9 @@ static void hvmtrace_io_assist(int is_mm
> size += 4;
> }
>
> + *(uint32_t *)&buffer[size] = guest_cpu_user_regs()->eip;
> + size += 4;
> +
...unconditionally overruning a stack buffer with a guest register.
> trace_var(event, 0/*!cycles*/, size, buffer);
> }
>
> @@ -153,8 +156,6 @@ static int hvmemul_do_io(
> p->df = df;
> p->data = value;
>
> - hvmtrace_io_assist(is_mmio, p);
> -
> if ( is_mmio )
> {
> rc = hvm_mmio_intercept(p);
> @@ -166,6 +167,8 @@ static int hvmemul_do_io(
> rc = hvm_portio_intercept(p);
> }
>
> + hvmtrace_io_assist(is_mmio, p);
> +
Why so?
Tim.
--
Tim Deegan <Tim.Deegan@citrix.com>
Principal Software Engineer, Xen Platform Team
Citrix Systems UK Ltd. (Company #02937203, SL9 0BG)
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-04-07 14:49 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-07 14:26 nested virtualization: tracing capabilities Christoph Egger
2011-04-07 14:49 ` Tim Deegan
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.