|
@@ -2059,10 +2059,14 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
|
|
|
|
|
|
switch (ecx) {
|
|
switch (ecx) {
|
|
case MSR_IA32_TSC: {
|
|
case MSR_IA32_TSC: {
|
|
- u64 tsc;
|
|
|
|
|
|
+ u64 tsc_offset;
|
|
|
|
|
|
- rdtscll(tsc);
|
|
|
|
- *data = svm->vmcb->control.tsc_offset + tsc;
|
|
|
|
|
|
+ if (is_nested(svm))
|
|
|
|
+ tsc_offset = svm->nested.hsave->control.tsc_offset;
|
|
|
|
+ else
|
|
|
|
+ tsc_offset = svm->vmcb->control.tsc_offset;
|
|
|
|
+
|
|
|
|
+ *data = tsc_offset + native_read_tsc();
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
case MSR_K6_STAR:
|
|
case MSR_K6_STAR:
|
|
@@ -2148,10 +2152,17 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
|
|
|
|
|
|
switch (ecx) {
|
|
switch (ecx) {
|
|
case MSR_IA32_TSC: {
|
|
case MSR_IA32_TSC: {
|
|
- u64 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;
|
|
|
|
|
|
- rdtscll(tsc);
|
|
|
|
- svm->vmcb->control.tsc_offset = data - tsc;
|
|
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
case MSR_K6_STAR:
|
|
case MSR_K6_STAR:
|