diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index 9d51d5a27..febe7967c 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -1973,6 +1973,9 @@ vlapic_wrmsr(struct vcpu *vcpu, uint32_t msr, uint64_t val) cancel_timer(vlapic->last_timer, vcpu->pcpu_id); vlapic->last_timer = -1; } else { + /*transfer guest tsc to host tsc*/ + val -= exec_vmread64(VMX_TSC_OFFSET_FULL); + vlapic->last_timer = update_timer(vlapic->last_timer, tsc_periodic_time, (long)vcpu, diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c index 73d2f6650..02cfb7df5 100644 --- a/hypervisor/arch/x86/guest/vmsr.c +++ b/hypervisor/arch/x86/guest/vmsr.c @@ -39,7 +39,7 @@ static const uint32_t emulated_msrs[] = { MSR_IA32_TSC_DEADLINE, /* Enable TSC_DEADLINE VMEXIT */ MSR_IA32_BIOS_UPDT_TRIG, /* Enable MSR_IA32_BIOS_UPDT_TRIG */ MSR_IA32_BIOS_SIGN_ID, /* Enable MSR_IA32_BIOS_SIGN_ID */ - + MSR_IA32_TIME_STAMP_COUNTER, /* following MSR not emulated now */ /* @@ -48,7 +48,6 @@ static const uint32_t emulated_msrs[] = { * MSR_IA32_SYSENTER_ESP, * MSR_IA32_SYSENTER_EIP, * MSR_IA32_TSC_AUX, - * MSR_IA32_TIME_STAMP_COUNTER, */ }; @@ -57,6 +56,7 @@ enum { IDX_TSC_DEADLINE, IDX_BIOS_UPDT_TRIG, IDX_BIOS_SIGN_ID, + IDX_TSC, IDX_MAX_MSR }; @@ -169,7 +169,6 @@ int rdmsr_handler(struct vcpu *vcpu) { uint32_t msr; uint64_t v = 0; - uint32_t id; int cur_context = vcpu->arch_vcpu.cur_context; /* Read the msr value */ @@ -182,6 +181,12 @@ int rdmsr_handler(struct vcpu *vcpu) v = vcpu->guest_msrs[IDX_TSC_DEADLINE]; break; } + case MSR_IA32_TIME_STAMP_COUNTER: + { + /*Add the TSC_offset to host TSC to get guest TSC */ + v = rdtsc() + exec_vmread64(VMX_TSC_OFFSET_FULL); + break; + } case MSR_IA32_MTRR_CAP: case MSR_IA32_MTRR_DEF_TYPE: @@ -218,15 +223,6 @@ int rdmsr_handler(struct vcpu *vcpu) v = vcpu->arch_vcpu.msr_tsc_aux; break; } - case MSR_IA32_TIME_STAMP_COUNTER: - { - /* Read the host TSC value */ - CPU_RDTSCP_EXECUTE(&v, &id); - - /* Add the TSC_offset to host TSC and return the value */ - v += exec_vmread64(VMX_TSC_OFFSET_FULL); - break; - } case MSR_IA32_APIC_BASE: { /* Read APIC base */ @@ -273,6 +269,13 @@ int wrmsr_handler(struct vcpu *vcpu) vcpu->guest_msrs[IDX_TSC_DEADLINE] = v; break; } + case MSR_IA32_TIME_STAMP_COUNTER: + { + /*Caculate TSC offset from changed TSC MSR value*/ + exec_vmwrite64(VMX_TSC_OFFSET_FULL, v - rdtsc()); + break; + } + case MSR_IA32_MTRR_CAP: case MSR_IA32_MTRR_DEF_TYPE: case MSR_IA32_MTRR_PHYSBASE_0 ... MSR_IA32_MTRR_PHYSMASK_9: diff --git a/hypervisor/arch/x86/vmx.c b/hypervisor/arch/x86/vmx.c index 702bd6425..5224fb602 100644 --- a/hypervisor/arch/x86/vmx.c +++ b/hypervisor/arch/x86/vmx.c @@ -880,7 +880,7 @@ static void init_exec_ctrl(struct vcpu *vcpu) * the IA32_VMX_PROCBASED_CTRLS MSR are always read as 1 --- A.3.2 */ value32 = msr_read(MSR_IA32_VMX_PROCBASED_CTLS); - value32 |= (/* VMX_PROCBASED_CTLS_TSC_OFF | */ + value32 |= (VMX_PROCBASED_CTLS_TSC_OFF | /* VMX_PROCBASED_CTLS_RDTSC | */ VMX_PROCBASED_CTLS_IO_BITMAP | VMX_PROCBASED_CTLS_MSR_BITMAP | @@ -1016,7 +1016,7 @@ static void init_exec_ctrl(struct vcpu *vcpu) exec_vmwrite64(VMX_EXECUTIVE_VMCS_PTR_FULL, 0); /* Setup Time stamp counter offset - pg 2902 24.6.5 */ - /* exec_vmwrite64(VMX_TSC_OFFSET_FULL, VMX_TSC_OFFSET_HIGH, 0); */ + exec_vmwrite64(VMX_TSC_OFFSET_FULL, 0); /* Set up the link pointer */ exec_vmwrite64(VMX_VMS_LINK_PTR_FULL, 0xFFFFFFFFFFFFFFFF);