diff options
| author | Andre Przywara <andre.przywara@amd.com> | 2009-05-28 05:56:31 -0400 |
|---|---|---|
| committer | Avi Kivity <avi@redhat.com> | 2009-09-10 01:32:43 -0400 |
| commit | 017cb99e875f2d8ff375cbb576c794b081cd0bd5 (patch) | |
| tree | 082e502aa174a68f86266e57b55cf35e7d93a13c | |
| parent | e7333391403b31feb27a05bc0dcd052a471f1276 (diff) | |
KVM: SVM: use explicit 64bit storage for sysenter values
Since AMD does not support sysenter in 64bit mode, the VMCB fields storing
the MSRs are truncated to 32bit upon VMRUN/#VMEXIT. So store the values
in a separate 64bit storage to avoid truncation.
[andre: fix amd->amd migration]
Signed-off-by: Christoph Egger <christoph.egger@amd.com>
Signed-off-by: Andre Przywara <andre.przywara@amd.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
| -rw-r--r-- | arch/x86/kvm/kvm_svm.h | 2 | ||||
| -rw-r--r-- | arch/x86/kvm/svm.c | 8 |
2 files changed, 6 insertions, 4 deletions
diff --git a/arch/x86/kvm/kvm_svm.h b/arch/x86/kvm/kvm_svm.h index ed66e4c078dc..6f275b4cf628 100644 --- a/arch/x86/kvm/kvm_svm.h +++ b/arch/x86/kvm/kvm_svm.h | |||
| @@ -27,6 +27,8 @@ struct vcpu_svm { | |||
| 27 | unsigned long vmcb_pa; | 27 | unsigned long vmcb_pa; |
| 28 | struct svm_cpu_data *svm_data; | 28 | struct svm_cpu_data *svm_data; |
| 29 | uint64_t asid_generation; | 29 | uint64_t asid_generation; |
| 30 | uint64_t sysenter_esp; | ||
| 31 | uint64_t sysenter_eip; | ||
| 30 | 32 | ||
| 31 | u64 next_rip; | 33 | u64 next_rip; |
| 32 | 34 | ||
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 48b22c9892d8..e3e7edca35d1 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
| @@ -367,8 +367,6 @@ static void svm_vcpu_init_msrpm(u32 *msrpm) | |||
| 367 | #endif | 367 | #endif |
| 368 | set_msr_interception(msrpm, MSR_K6_STAR, 1, 1); | 368 | set_msr_interception(msrpm, MSR_K6_STAR, 1, 1); |
| 369 | set_msr_interception(msrpm, MSR_IA32_SYSENTER_CS, 1, 1); | 369 | set_msr_interception(msrpm, MSR_IA32_SYSENTER_CS, 1, 1); |
| 370 | set_msr_interception(msrpm, MSR_IA32_SYSENTER_ESP, 1, 1); | ||
| 371 | set_msr_interception(msrpm, MSR_IA32_SYSENTER_EIP, 1, 1); | ||
| 372 | } | 370 | } |
| 373 | 371 | ||
| 374 | static void svm_enable_lbrv(struct vcpu_svm *svm) | 372 | static void svm_enable_lbrv(struct vcpu_svm *svm) |
| @@ -1981,10 +1979,10 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) | |||
| 1981 | *data = svm->vmcb->save.sysenter_cs; | 1979 | *data = svm->vmcb->save.sysenter_cs; |
| 1982 | break; | 1980 | break; |
| 1983 | case MSR_IA32_SYSENTER_EIP: | 1981 | case MSR_IA32_SYSENTER_EIP: |
| 1984 | *data = svm->vmcb->save.sysenter_eip; | 1982 | *data = svm->sysenter_eip; |
| 1985 | break; | 1983 | break; |
| 1986 | case MSR_IA32_SYSENTER_ESP: | 1984 | case MSR_IA32_SYSENTER_ESP: |
| 1987 | *data = svm->vmcb->save.sysenter_esp; | 1985 | *data = svm->sysenter_esp; |
| 1988 | break; | 1986 | break; |
| 1989 | /* Nobody will change the following 5 values in the VMCB so | 1987 | /* Nobody will change the following 5 values in the VMCB so |
| 1990 | we can safely return them on rdmsr. They will always be 0 | 1988 | we can safely return them on rdmsr. They will always be 0 |
| @@ -2071,9 +2069,11 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) | |||
| 2071 | svm->vmcb->save.sysenter_cs = data; | 2069 | svm->vmcb->save.sysenter_cs = data; |
| 2072 | break; | 2070 | break; |
| 2073 | case MSR_IA32_SYSENTER_EIP: | 2071 | case MSR_IA32_SYSENTER_EIP: |
| 2072 | svm->sysenter_eip = data; | ||
| 2074 | svm->vmcb->save.sysenter_eip = data; | 2073 | svm->vmcb->save.sysenter_eip = data; |
| 2075 | break; | 2074 | break; |
| 2076 | case MSR_IA32_SYSENTER_ESP: | 2075 | case MSR_IA32_SYSENTER_ESP: |
| 2076 | svm->sysenter_esp = data; | ||
| 2077 | svm->vmcb->save.sysenter_esp = data; | 2077 | svm->vmcb->save.sysenter_esp = data; |
| 2078 | break; | 2078 | break; |
| 2079 | case MSR_IA32_DEBUGCTLMSR: | 2079 | case MSR_IA32_DEBUGCTLMSR: |
