KVM: SVM: use explicit 64bit storage for sysenter values
authorAndre Przywara <andre.przywara@amd.com>
Thu, 28 May 2009 09:56:31 +0000 (11:56 +0200)
committerAvi Kivity <avi@redhat.com>
Thu, 10 Sep 2009 05:32:43 +0000 (08:32 +0300)
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>
arch/x86/kvm/kvm_svm.h
arch/x86/kvm/svm.c

index ed66e4c078dc64229d5684d5bcf0ed5373098d7b..6f275b4cf6287f5d757273f3668adb64b2a74969 100644 (file)
@@ -27,6 +27,8 @@ struct vcpu_svm {
        unsigned long vmcb_pa;
        struct svm_cpu_data *svm_data;
        uint64_t asid_generation;
+       uint64_t sysenter_esp;
+       uint64_t sysenter_eip;
 
        u64 next_rip;
 
index 48b22c9892d893e41dc18fad7d9d9e0ac9f0c377..e3e7edca35d19f49cffec8f9337f690bee243882 100644 (file)
@@ -367,8 +367,6 @@ static void svm_vcpu_init_msrpm(u32 *msrpm)
 #endif
        set_msr_interception(msrpm, MSR_K6_STAR, 1, 1);
        set_msr_interception(msrpm, MSR_IA32_SYSENTER_CS, 1, 1);
-       set_msr_interception(msrpm, MSR_IA32_SYSENTER_ESP, 1, 1);
-       set_msr_interception(msrpm, MSR_IA32_SYSENTER_EIP, 1, 1);
 }
 
 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)
                *data = svm->vmcb->save.sysenter_cs;
                break;
        case MSR_IA32_SYSENTER_EIP:
-               *data = svm->vmcb->save.sysenter_eip;
+               *data = svm->sysenter_eip;
                break;
        case MSR_IA32_SYSENTER_ESP:
-               *data = svm->vmcb->save.sysenter_esp;
+               *data = svm->sysenter_esp;
                break;
        /* Nobody will change the following 5 values in the VMCB so
           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)
                svm->vmcb->save.sysenter_cs = data;
                break;
        case MSR_IA32_SYSENTER_EIP:
+               svm->sysenter_eip = data;
                svm->vmcb->save.sysenter_eip = data;
                break;
        case MSR_IA32_SYSENTER_ESP:
+               svm->sysenter_esp = data;
                svm->vmcb->save.sysenter_esp = data;
                break;
        case MSR_IA32_DEBUGCTLMSR: