[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: Enable MTF for HVM guest single step in gdb
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1229428160 0 # Node ID 5b73fa1b9562d18ecdde2b3c8556989bdb2117e0 # Parent f827181eadd4f3f8f6afb37b493e9c9e1d511204 x86: Enable MTF for HVM guest single step in gdb Signed-off-by: Edwin Zhai <edwin.zhai@xxxxxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- tools/libxc/xc_domain.c | 14 ++++++++++++ tools/libxc/xc_ptrace.c | 41 ++++++++++++++++++++++++++----------- tools/libxc/xenctrl.h | 6 +++++ xen/arch/x86/domctl.c | 26 +++++++++++++++++++++++ xen/arch/x86/hvm/hvm.c | 26 +++++++++++++++++++++++ xen/arch/x86/hvm/vmx/intr.c | 8 +++++++ xen/arch/x86/hvm/vmx/vmcs.c | 10 ++++++++- xen/arch/x86/hvm/vmx/vmx.c | 13 ++++++++++- xen/include/asm-x86/hvm/hvm.h | 2 + xen/include/asm-x86/hvm/vcpu.h | 1 xen/include/asm-x86/hvm/vmx/vmcs.h | 3 ++ xen/include/asm-x86/hvm/vmx/vmx.h | 1 xen/include/public/domctl.h | 12 ++++++++++ 13 files changed, 149 insertions(+), 14 deletions(-) diff -r f827181eadd4 -r 5b73fa1b9562 tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Mon Dec 15 11:37:14 2008 +0000 +++ b/tools/libxc/xc_domain.c Tue Dec 16 11:49:20 2008 +0000 @@ -1061,6 +1061,20 @@ int xc_domain_suppress_spurious_page_fau } +int xc_domain_debug_control(int xc, uint32_t domid, uint32_t sop, uint32_t vcpu) +{ + DECLARE_DOMCTL; + + memset(&domctl, 0, sizeof(domctl)); + domctl.domain = (domid_t)domid; + domctl.cmd = XEN_DOMCTL_debug_op; + domctl.u.debug_op.op = sop; + domctl.u.debug_op.vcpu = vcpu; + + return do_domctl(xc, &domctl); +} + + /* * Local variables: * mode: C diff -r f827181eadd4 -r 5b73fa1b9562 tools/libxc/xc_ptrace.c --- a/tools/libxc/xc_ptrace.c Mon Dec 15 11:37:14 2008 +0000 +++ b/tools/libxc/xc_ptrace.c Tue Dec 16 11:49:20 2008 +0000 @@ -524,10 +524,20 @@ xc_ptrace( /* XXX we can still have problems if the user switches threads * during single-stepping - but that just seems retarded */ - ctxt[cpu].c.user_regs.eflags |= PSL_T; - if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, - &ctxt[cpu]))) - goto out_error_domctl; + /* Try to enalbe Monitor Trap Flag for HVM, and fall back to TF + * if no MTF support + */ + if ( !current_is_hvm || + xc_domain_debug_control(xc_handle, + current_domid, + XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_ON, + cpu) ) + { + ctxt[cpu].c.user_regs.eflags |= PSL_T; + if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, + &ctxt[cpu]))) + goto out_error_domctl; + } /* FALLTHROUGH */ case PTRACE_CONT: @@ -538,15 +548,22 @@ xc_ptrace( { FOREACH_CPU(cpumap, index) { cpu = index - 1; - if (fetch_regs(xc_handle, cpu, NULL)) - goto out_error; - /* Clear trace flag */ - if ( ctxt[cpu].c.user_regs.eflags & PSL_T ) + if ( !current_is_hvm || + xc_domain_debug_control(xc_handle, + current_domid, + XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_OFF, + cpu) ) { - ctxt[cpu].c.user_regs.eflags &= ~PSL_T; - if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, - cpu, &ctxt[cpu]))) - goto out_error_domctl; + if (fetch_regs(xc_handle, cpu, NULL)) + goto out_error; + /* Clear trace flag */ + if ( ctxt[cpu].c.user_regs.eflags & PSL_T ) + { + ctxt[cpu].c.user_regs.eflags &= ~PSL_T; + if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, + cpu, &ctxt[cpu]))) + goto out_error_domctl; + } } } } diff -r f827181eadd4 -r 5b73fa1b9562 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Mon Dec 15 11:37:14 2008 +0000 +++ b/tools/libxc/xenctrl.h Tue Dec 16 11:49:20 2008 +0000 @@ -1111,6 +1111,12 @@ int xc_domain_set_target(int xc_handle, uint32_t domid, uint32_t target); +/* Control the domain for debug */ +int xc_domain_debug_control(int xc_handle, + uint32_t domid, + uint32_t sop, + uint32_t vcpu); + #if defined(__i386__) || defined(__x86_64__) int xc_cpuid_check(int xc, const unsigned int *input, diff -r f827181eadd4 -r 5b73fa1b9562 xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Mon Dec 15 11:37:14 2008 +0000 +++ b/xen/arch/x86/domctl.c Tue Dec 16 11:49:20 2008 +0000 @@ -1022,6 +1022,32 @@ long arch_do_domctl( } break; + case XEN_DOMCTL_debug_op: + { + struct domain *d; + struct vcpu *v; + + ret = -ESRCH; + d = rcu_lock_domain_by_id(domctl->domain); + if ( d == NULL ) + break; + + ret = -EINVAL; + if ( (domctl->u.debug_op.vcpu >= MAX_VIRT_CPUS) || + ((v = d->vcpu[domctl->u.debug_op.vcpu]) == NULL) ) + goto debug_op_out; + + ret = -EINVAL; + if ( !is_hvm_domain(d)) + goto debug_op_out; + + ret = hvm_debug_op(v, domctl->u.debug_op.op); + + debug_op_out: + rcu_unlock_domain(d); + } + break; + default: ret = -ENOSYS; break; diff -r f827181eadd4 -r 5b73fa1b9562 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Mon Dec 15 11:37:14 2008 +0000 +++ b/xen/arch/x86/hvm/hvm.c Tue Dec 16 11:49:20 2008 +0000 @@ -2700,6 +2700,32 @@ long do_hvm_op(unsigned long op, XEN_GUE return rc; } +int hvm_debug_op(struct vcpu *v, int32_t op) +{ + int rc; + + switch ( op ) + { + case XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_ON: + case XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_OFF: + rc = -ENOSYS; + if ( !cpu_has_monitor_trap_flag ) + break; + rc = 0; + vcpu_pause(v); + v->arch.hvm_vcpu.single_step = + (op == XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_ON); + vcpu_unpause(v); /* guest will latch new state */ + break; + default: + rc = -ENOSYS; + break; + } + + return rc; +} + + /* * Local variables: * mode: C diff -r f827181eadd4 -r 5b73fa1b9562 xen/arch/x86/hvm/vmx/intr.c --- a/xen/arch/x86/hvm/vmx/intr.c Mon Dec 15 11:37:14 2008 +0000 +++ b/xen/arch/x86/hvm/vmx/intr.c Tue Dec 16 11:49:20 2008 +0000 @@ -117,6 +117,14 @@ asmlinkage void vmx_intr_assist(void) unsigned int tpr_threshold = 0; enum hvm_intblk intblk; + /* Block event injection when single step with MTF. */ + if ( unlikely(v->arch.hvm_vcpu.single_step) ) + { + v->arch.hvm_vmx.exec_control |= CPU_BASED_MONITOR_TRAP_FLAG; + __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control); + return; + } + /* Crank the handle on interrupt state. */ pt_update_irq(v); hvm_dirq_assist(v); diff -r f827181eadd4 -r 5b73fa1b9562 xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Mon Dec 15 11:37:14 2008 +0000 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Tue Dec 16 11:49:20 2008 +0000 @@ -99,6 +99,7 @@ static void vmx_init_vmcs_config(void) (opt_softtsc ? CPU_BASED_RDTSC_EXITING : 0)); opt = (CPU_BASED_ACTIVATE_MSR_BITMAP | CPU_BASED_TPR_SHADOW | + CPU_BASED_MONITOR_TRAP_FLAG | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS); _vmx_cpu_based_exec_control = adjust_vmx_controls( min, opt, MSR_IA32_VMX_PROCBASED_CTLS); @@ -515,6 +516,9 @@ static int construct_vmcs(struct vcpu *v v->arch.hvm_vmx.secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_EPT; } + /* Do not enable Monitor Trap Flag unless start single step debug */ + v->arch.hvm_vmx.exec_control &= ~CPU_BASED_MONITOR_TRAP_FLAG; + __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control); if ( cpu_has_vmx_secondary_exec_control ) __vmwrite(SECONDARY_VM_EXEC_CONTROL, @@ -867,7 +871,11 @@ void vmx_do_resume(struct vcpu *v) if ( unlikely(v->arch.hvm_vcpu.debug_state_latch != debug_state) ) { unsigned long intercepts = __vmread(EXCEPTION_BITMAP); - unsigned long mask = (1U << TRAP_debug) | (1U << TRAP_int3); + unsigned long mask = 1u << TRAP_int3; + + if ( !cpu_has_monitor_trap_flag ) + mask |= 1u << TRAP_debug; + v->arch.hvm_vcpu.debug_state_latch = debug_state; if ( debug_state ) intercepts |= mask; diff -r f827181eadd4 -r 5b73fa1b9562 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Mon Dec 15 11:37:14 2008 +0000 +++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Dec 16 11:49:20 2008 +0000 @@ -1263,6 +1263,8 @@ void vmx_inject_hw_exception(int trap, i __restore_debug_registers(curr); write_debugreg(6, read_debugreg(6) | 0x4000); } + if ( cpu_has_monitor_trap_flag ) + break; case TRAP_int3: if ( curr->domain->debugger_attached ) { @@ -2348,7 +2350,7 @@ asmlinkage void vmx_vmexit_handler(struc */ exit_qualification = __vmread(EXIT_QUALIFICATION); write_debugreg(6, exit_qualification | 0xffff0ff0); - if ( !v->domain->debugger_attached ) + if ( !v->domain->debugger_attached || cpu_has_monitor_trap_flag ) goto exit_and_crash; domain_pause_for_debugger(); break; @@ -2538,6 +2540,15 @@ asmlinkage void vmx_vmexit_handler(struc break; } + case EXIT_REASON_MONITOR_TRAP_FLAG: + { + v->arch.hvm_vmx.exec_control &= ~CPU_BASED_MONITOR_TRAP_FLAG; + __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control); + if ( v->domain->debugger_attached && v->arch.hvm_vcpu.single_step ) + domain_pause_for_debugger(); + break; + } + default: exit_and_crash: gdprintk(XENLOG_ERR, "Bad vmexit (reason %x)\n", exit_reason); diff -r f827181eadd4 -r 5b73fa1b9562 xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h Mon Dec 15 11:37:14 2008 +0000 +++ b/xen/include/asm-x86/hvm/hvm.h Tue Dec 16 11:49:20 2008 +0000 @@ -321,4 +321,6 @@ static inline void hvm_set_info_guest(st return hvm_funcs.set_info_guest(v); } +int hvm_debug_op(struct vcpu *v, int32_t op); + #endif /* __ASM_X86_HVM_HVM_H__ */ diff -r f827181eadd4 -r 5b73fa1b9562 xen/include/asm-x86/hvm/vcpu.h --- a/xen/include/asm-x86/hvm/vcpu.h Mon Dec 15 11:37:14 2008 +0000 +++ b/xen/include/asm-x86/hvm/vcpu.h Tue Dec 16 11:49:20 2008 +0000 @@ -59,6 +59,7 @@ struct hvm_vcpu { bool_t flag_dr_dirty; bool_t debug_state_latch; + bool_t single_step; union { struct arch_vmx_struct vmx; diff -r f827181eadd4 -r 5b73fa1b9562 xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Mon Dec 15 11:37:14 2008 +0000 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Tue Dec 16 11:49:20 2008 +0000 @@ -142,6 +142,7 @@ void vmx_vmcs_exit(struct vcpu *v); #define CPU_BASED_MOV_DR_EXITING 0x00800000 #define CPU_BASED_UNCOND_IO_EXITING 0x01000000 #define CPU_BASED_ACTIVATE_IO_BITMAP 0x02000000 +#define CPU_BASED_MONITOR_TRAP_FLAG 0x08000000 #define CPU_BASED_ACTIVATE_MSR_BITMAP 0x10000000 #define CPU_BASED_MONITOR_EXITING 0x20000000 #define CPU_BASED_PAUSE_EXITING 0x40000000 @@ -186,6 +187,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT) #define cpu_has_vmx_vpid \ (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID) +#define cpu_has_monitor_trap_flag \ + (vmx_cpu_based_exec_control & CPU_BASED_MONITOR_TRAP_FLAG) /* GUEST_INTERRUPTIBILITY_INFO flags. */ #define VMX_INTR_SHADOW_STI 0x00000001 diff -r f827181eadd4 -r 5b73fa1b9562 xen/include/asm-x86/hvm/vmx/vmx.h --- a/xen/include/asm-x86/hvm/vmx/vmx.h Mon Dec 15 11:37:14 2008 +0000 +++ b/xen/include/asm-x86/hvm/vmx/vmx.h Tue Dec 16 11:49:20 2008 +0000 @@ -96,6 +96,7 @@ void vmx_realmode(struct cpu_user_regs * #define EXIT_REASON_INVALID_GUEST_STATE 33 #define EXIT_REASON_MSR_LOADING 34 #define EXIT_REASON_MWAIT_INSTRUCTION 36 +#define EXIT_REASON_MONITOR_TRAP_FLAG 37 #define EXIT_REASON_MONITOR_INSTRUCTION 39 #define EXIT_REASON_PAUSE_INSTRUCTION 40 #define EXIT_REASON_MACHINE_CHECK 41 diff -r f827181eadd4 -r 5b73fa1b9562 xen/include/public/domctl.h --- a/xen/include/public/domctl.h Mon Dec 15 11:37:14 2008 +0000 +++ b/xen/include/public/domctl.h Tue Dec 16 11:49:20 2008 +0000 @@ -619,6 +619,17 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_subsc */ #define XEN_DOMCTL_suppress_spurious_page_faults 53 +#define XEN_DOMCTL_debug_op 54 +#define XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_OFF 0 +#define XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_ON 1 +struct xen_domctl_debug_op { + uint32_t op; /* IN */ + uint32_t vcpu; /* IN */ +}; +typedef struct xen_domctl_debug_op xen_domctl_debug_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_debug_op_t); + + struct xen_domctl { uint32_t cmd; uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */ @@ -658,6 +669,7 @@ struct xen_domctl { struct xen_domctl_set_opt_feature set_opt_feature; struct xen_domctl_set_target set_target; struct xen_domctl_subscribe subscribe; + struct xen_domctl_debug_op debug_op; #if defined(__i386__) || defined(__x86_64__) struct xen_domctl_cpuid cpuid; #endif _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |