diff options
| -rw-r--r-- | arch/x86/kvm/svm.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index bf5799dc4f9f..c17404add91f 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
| @@ -2059,10 +2059,14 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) | |||
| 2059 | 2059 | ||
| 2060 | switch (ecx) { | 2060 | switch (ecx) { |
| 2061 | case MSR_IA32_TSC: { | 2061 | case MSR_IA32_TSC: { |
| 2062 | u64 tsc; | 2062 | u64 tsc_offset; |
| 2063 | 2063 | ||
| 2064 | rdtscll(tsc); | 2064 | if (is_nested(svm)) |
| 2065 | *data = svm->vmcb->control.tsc_offset + tsc; | 2065 | tsc_offset = svm->nested.hsave->control.tsc_offset; |
| 2066 | else | ||
| 2067 | tsc_offset = svm->vmcb->control.tsc_offset; | ||
| 2068 | |||
| 2069 | *data = tsc_offset + native_read_tsc(); | ||
| 2066 | break; | 2070 | break; |
| 2067 | } | 2071 | } |
| 2068 | case MSR_K6_STAR: | 2072 | case MSR_K6_STAR: |
| @@ -2148,10 +2152,17 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) | |||
| 2148 | 2152 | ||
| 2149 | switch (ecx) { | 2153 | switch (ecx) { |
| 2150 | case MSR_IA32_TSC: { | 2154 | case MSR_IA32_TSC: { |
| 2151 | u64 tsc; | 2155 | u64 tsc_offset = data - native_read_tsc(); |
| 2156 | u64 g_tsc_offset = 0; | ||
| 2157 | |||
| 2158 | if (is_nested(svm)) { | ||
| 2159 | g_tsc_offset = svm->vmcb->control.tsc_offset - | ||
| 2160 | svm->nested.hsave->control.tsc_offset; | ||
| 2161 | svm->nested.hsave->control.tsc_offset = tsc_offset; | ||
| 2162 | } | ||
| 2163 | |||
| 2164 | svm->vmcb->control.tsc_offset = tsc_offset + g_tsc_offset; | ||
| 2152 | 2165 | ||
| 2153 | rdtscll(tsc); | ||
| 2154 | svm->vmcb->control.tsc_offset = data - tsc; | ||
| 2155 | break; | 2166 | break; |
| 2156 | } | 2167 | } |
| 2157 | case MSR_K6_STAR: | 2168 | case MSR_K6_STAR: |
