diff -r be52424a543e xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Fri Jun 27 14:15:11 2008 +0100 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Tue Jul 08 22:26:57 2008 +0800 @@ -40,6 +40,7 @@ static int opt_vpid_enabled = 1; boolean_param("vpid", opt_vpid_enabled); +int softtsc = 1; /* Dynamic (run-time adjusted) execution control flags. */ u32 vmx_pin_based_exec_control __read_mostly; @@ -96,6 +97,8 @@ CPU_BASED_MOV_DR_EXITING | CPU_BASED_ACTIVATE_IO_BITMAP | CPU_BASED_USE_TSC_OFFSETING); + if (softtsc) + min |= CPU_BASED_RDTSC_EXITING; opt = (CPU_BASED_ACTIVATE_MSR_BITMAP | CPU_BASED_TPR_SHADOW | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS); diff -r be52424a543e xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Fri Jun 27 14:15:11 2008 +0100 +++ b/xen/arch/x86/hvm/vmx/vmx.c Tue Jul 08 22:26:57 2008 +0800 @@ -1375,6 +1375,17 @@ if ( paging_invlpg(curr, vaddr) ) vpid_sync_vcpu_gva(curr, vaddr); } + +static void vmx_rdtsc_intercept(struct cpu_user_regs *regs) +{ + uint64_t tsc; + struct vcpu *v = current; + + tsc = hvm_get_guest_tsc(v); + regs->eax = tsc & 0xffff; + regs->edx = tsc >> 32 & 0xffff; +} + #define CASE_SET_REG(REG, reg) \ case VMX_CONTROL_REG_ACCESS_GPR_ ## REG: regs->reg = value; break @@ -2192,6 +2203,11 @@ vmx_invlpg_intercept(exit_qualification); break; } + case EXIT_REASON_RDTSC: + inst_len = __get_instruction_length(); + __update_guest_eip(inst_len); + vmx_rdtsc_intercept(regs); + break; case EXIT_REASON_VMCALL: { int rc;