aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/kvm/svm.c8
-rw-r--r--arch/x86/kvm/vmx.c16
-rw-r--r--arch/x86/kvm/x86.c8
4 files changed, 29 insertions, 4 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index b31a3417a405..6ab4241c27cb 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -630,6 +630,7 @@ struct kvm_x86_ops {
630 void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset); 630 void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
631 631
632 u64 (*compute_tsc_offset)(struct kvm_vcpu *vcpu, u64 target_tsc); 632 u64 (*compute_tsc_offset)(struct kvm_vcpu *vcpu, u64 target_tsc);
633 u64 (*read_l1_tsc)(struct kvm_vcpu *vcpu);
633 634
634 void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2); 635 void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2);
635 636
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index f043168a5ab1..590d1d2d620b 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2910,6 +2910,13 @@ static int cr8_write_interception(struct vcpu_svm *svm)
2910 return 0; 2910 return 0;
2911} 2911}
2912 2912
2913u64 svm_read_l1_tsc(struct kvm_vcpu *vcpu)
2914{
2915 struct vmcb *vmcb = get_host_vmcb(to_svm(vcpu));
2916 return vmcb->control.tsc_offset +
2917 svm_scale_tsc(vcpu, native_read_tsc());
2918}
2919
2913static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) 2920static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
2914{ 2921{
2915 struct vcpu_svm *svm = to_svm(vcpu); 2922 struct vcpu_svm *svm = to_svm(vcpu);
@@ -4201,6 +4208,7 @@ static struct kvm_x86_ops svm_x86_ops = {
4201 .write_tsc_offset = svm_write_tsc_offset, 4208 .write_tsc_offset = svm_write_tsc_offset,
4202 .adjust_tsc_offset = svm_adjust_tsc_offset, 4209 .adjust_tsc_offset = svm_adjust_tsc_offset,
4203 .compute_tsc_offset = svm_compute_tsc_offset, 4210 .compute_tsc_offset = svm_compute_tsc_offset,
4211 .read_l1_tsc = svm_read_l1_tsc,
4204 4212
4205 .set_tdp_cr3 = set_tdp_cr3, 4213 .set_tdp_cr3 = set_tdp_cr3,
4206 4214
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 03df703c8f20..97b64543d4ed 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1748,6 +1748,21 @@ static u64 guest_read_tsc(void)
1748} 1748}
1749 1749
1750/* 1750/*
1751 * Like guest_read_tsc, but always returns L1's notion of the timestamp
1752 * counter, even if a nested guest (L2) is currently running.
1753 */
1754u64 vmx_read_l1_tsc(struct kvm_vcpu *vcpu)
1755{
1756 u64 host_tsc, tsc_offset;
1757
1758 rdtscll(host_tsc);
1759 tsc_offset = is_guest_mode(vcpu) ?
1760 to_vmx(vcpu)->nested.vmcs01_tsc_offset :
1761 vmcs_read64(TSC_OFFSET);
1762 return host_tsc + tsc_offset;
1763}
1764
1765/*
1751 * Empty call-back. Needs to be implemented when VMX enables the SET_TSC_KHZ 1766 * Empty call-back. Needs to be implemented when VMX enables the SET_TSC_KHZ
1752 * ioctl. In this case the call-back should update internal vmx state to make 1767 * ioctl. In this case the call-back should update internal vmx state to make
1753 * the changes effective. 1768 * the changes effective.
@@ -7010,6 +7025,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
7010 .write_tsc_offset = vmx_write_tsc_offset, 7025 .write_tsc_offset = vmx_write_tsc_offset,
7011 .adjust_tsc_offset = vmx_adjust_tsc_offset, 7026 .adjust_tsc_offset = vmx_adjust_tsc_offset,
7012 .compute_tsc_offset = vmx_compute_tsc_offset, 7027 .compute_tsc_offset = vmx_compute_tsc_offset,
7028 .read_l1_tsc = vmx_read_l1_tsc,
7013 7029
7014 .set_tdp_cr3 = vmx_set_cr3, 7030 .set_tdp_cr3 = vmx_set_cr3,
7015 7031
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ea8f9f03e923..6b37f18a1663 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1098,7 +1098,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
1098 1098
1099 /* Keep irq disabled to prevent changes to the clock */ 1099 /* Keep irq disabled to prevent changes to the clock */
1100 local_irq_save(flags); 1100 local_irq_save(flags);
1101 kvm_get_msr(v, MSR_IA32_TSC, &tsc_timestamp); 1101 tsc_timestamp = kvm_x86_ops->read_l1_tsc(v);
1102 kernel_ns = get_kernel_ns(); 1102 kernel_ns = get_kernel_ns();
1103 this_tsc_khz = vcpu_tsc_khz(v); 1103 this_tsc_khz = vcpu_tsc_khz(v);
1104 if (unlikely(this_tsc_khz == 0)) { 1104 if (unlikely(this_tsc_khz == 0)) {
@@ -2218,7 +2218,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
2218 s64 tsc_delta; 2218 s64 tsc_delta;
2219 u64 tsc; 2219 u64 tsc;
2220 2220
2221 kvm_get_msr(vcpu, MSR_IA32_TSC, &tsc); 2221 tsc = kvm_x86_ops->read_l1_tsc(vcpu);
2222 tsc_delta = !vcpu->arch.last_guest_tsc ? 0 : 2222 tsc_delta = !vcpu->arch.last_guest_tsc ? 0 :
2223 tsc - vcpu->arch.last_guest_tsc; 2223 tsc - vcpu->arch.last_guest_tsc;
2224 2224
@@ -2242,7 +2242,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
2242{ 2242{
2243 kvm_x86_ops->vcpu_put(vcpu); 2243 kvm_x86_ops->vcpu_put(vcpu);
2244 kvm_put_guest_fpu(vcpu); 2244 kvm_put_guest_fpu(vcpu);
2245 kvm_get_msr(vcpu, MSR_IA32_TSC, &vcpu->arch.last_guest_tsc); 2245 vcpu->arch.last_guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu);
2246} 2246}
2247 2247
2248static int is_efer_nx(void) 2248static int is_efer_nx(void)
@@ -5729,7 +5729,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
5729 if (hw_breakpoint_active()) 5729 if (hw_breakpoint_active())
5730 hw_breakpoint_restore(); 5730 hw_breakpoint_restore();
5731 5731
5732 kvm_get_msr(vcpu, MSR_IA32_TSC, &vcpu->arch.last_guest_tsc); 5732 vcpu->arch.last_guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu);
5733 5733
5734 vcpu->mode = OUTSIDE_GUEST_MODE; 5734 vcpu->mode = OUTSIDE_GUEST_MODE;
5735 smp_wmb(); 5735 smp_wmb();