|
@@ -701,6 +701,20 @@ static void init_sys_seg(struct vmcb_seg *seg, uint32_t type)
|
|
|
seg->base = 0;
|
|
|
}
|
|
|
|
|
|
+static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
|
|
|
+{
|
|
|
+ struct vcpu_svm *svm = to_svm(vcpu);
|
|
|
+ u64 g_tsc_offset = 0;
|
|
|
+
|
|
|
+ if (is_nested(svm)) {
|
|
|
+ g_tsc_offset = svm->vmcb->control.tsc_offset -
|
|
|
+ svm->nested.hsave->control.tsc_offset;
|
|
|
+ svm->nested.hsave->control.tsc_offset = offset;
|
|
|
+ }
|
|
|
+
|
|
|
+ svm->vmcb->control.tsc_offset = offset + g_tsc_offset;
|
|
|
+}
|
|
|
+
|
|
|
static void init_vmcb(struct vcpu_svm *svm)
|
|
|
{
|
|
|
struct vmcb_control_area *control = &svm->vmcb->control;
|
|
@@ -901,7 +915,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
|
|
|
svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT;
|
|
|
svm->asid_generation = 0;
|
|
|
init_vmcb(svm);
|
|
|
- svm->vmcb->control.tsc_offset = 0-native_read_tsc();
|
|
|
+ svm_write_tsc_offset(&svm->vcpu, 0-native_read_tsc());
|
|
|
|
|
|
err = fx_init(&svm->vcpu);
|
|
|
if (err)
|
|
@@ -2566,20 +2580,9 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
|
|
|
struct vcpu_svm *svm = to_svm(vcpu);
|
|
|
|
|
|
switch (ecx) {
|
|
|
- case MSR_IA32_TSC: {
|
|
|
- u64 tsc_offset = data - native_read_tsc();
|
|
|
- u64 g_tsc_offset = 0;
|
|
|
-
|
|
|
- if (is_nested(svm)) {
|
|
|
- g_tsc_offset = svm->vmcb->control.tsc_offset -
|
|
|
- svm->nested.hsave->control.tsc_offset;
|
|
|
- svm->nested.hsave->control.tsc_offset = tsc_offset;
|
|
|
- }
|
|
|
-
|
|
|
- svm->vmcb->control.tsc_offset = tsc_offset + g_tsc_offset;
|
|
|
-
|
|
|
+ case MSR_IA32_TSC:
|
|
|
+ svm_write_tsc_offset(vcpu, data - native_read_tsc());
|
|
|
break;
|
|
|
- }
|
|
|
case MSR_STAR:
|
|
|
svm->vmcb->save.star = data;
|
|
|
break;
|