aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@amd.com>2009-05-28 05:56:31 -0400
committerAvi Kivity <avi@redhat.com>2009-09-10 01:32:43 -0400
commit017cb99e875f2d8ff375cbb576c794b081cd0bd5 (patch)
tree082e502aa174a68f86266e57b55cf35e7d93a13c
parente7333391403b31feb27a05bc0dcd052a471f1276 (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.h2
-rw-r--r--arch/x86/kvm/svm.c8
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
374static void svm_enable_lbrv(struct vcpu_svm *svm) 372static 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: