lkml.org 
[lkml]   [2009]   [Apr]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 088/100] KVM: VMX: Update necessary state when guest enters long mode
    -stable review patch.  If anyone has any objections, please let us know.
    ---------------------

    From: Amit Shah <amit.shah@redhat.com>

    upstream commit: 401d10dee083bda281f2fdcdf654080313ba30ec

    setup_msrs() should be called when entering long mode to save the
    shadow state for the 64-bit guest state.

    Using vmx_set_efer() in enter_lmode() removes some duplicated code
    and also ensures we call setup_msrs(). We can safely pass the value
    of shadow_efer to vmx_set_efer() as no other bits in the efer change
    while enabling long mode (guest first sets EFER.LME, then sets CR0.PG
    which causes a vmexit where we activate long mode).

    With this fix, is_long_mode() can check for EFER.LMA set instead of
    EFER.LME and 5e23049e86dd298b72e206b420513dbc3a240cd9 can be reverted.

    Signed-off-by: Amit Shah <amit.shah@redhat.com>
    Signed-off-by: Avi Kivity <avi@redhat.com>
    Signed-off-by: Chris Wright <chrisw@sous-sol.org>
    ---
    arch/x86/kvm/vmx.c | 54 +++++++++++++++++++++++------------------------------
    1 file changed, 24 insertions(+), 30 deletions(-)

    --- a/arch/x86/kvm/vmx.c
    +++ b/arch/x86/kvm/vmx.c
    @@ -1433,6 +1433,29 @@ continue_rmode:
    init_rmode(vcpu->kvm);
    }

    +static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
    +{
    + struct vcpu_vmx *vmx = to_vmx(vcpu);
    + struct kvm_msr_entry *msr = find_msr_entry(vmx, MSR_EFER);
    +
    + vcpu->arch.shadow_efer = efer;
    + if (!msr)
    + return;
    + if (efer & EFER_LMA) {
    + vmcs_write32(VM_ENTRY_CONTROLS,
    + vmcs_read32(VM_ENTRY_CONTROLS) |
    + VM_ENTRY_IA32E_MODE);
    + msr->data = efer;
    + } else {
    + vmcs_write32(VM_ENTRY_CONTROLS,
    + vmcs_read32(VM_ENTRY_CONTROLS) &
    + ~VM_ENTRY_IA32E_MODE);
    +
    + msr->data = efer & ~EFER_LME;
    + }
    + setup_msrs(vmx);
    +}
    +
    #ifdef CONFIG_X86_64

    static void enter_lmode(struct kvm_vcpu *vcpu)
    @@ -1447,13 +1470,8 @@ static void enter_lmode(struct kvm_vcpu
    (guest_tr_ar & ~AR_TYPE_MASK)
    | AR_TYPE_BUSY_64_TSS);
    }
    -
    vcpu->arch.shadow_efer |= EFER_LMA;
    -
    - find_msr_entry(to_vmx(vcpu), MSR_EFER)->data |= EFER_LMA | EFER_LME;
    - vmcs_write32(VM_ENTRY_CONTROLS,
    - vmcs_read32(VM_ENTRY_CONTROLS)
    - | VM_ENTRY_IA32E_MODE);
    + vmx_set_efer(vcpu, vcpu->arch.shadow_efer);
    }

    static void exit_lmode(struct kvm_vcpu *vcpu)
    @@ -1612,30 +1630,6 @@ static void vmx_set_cr4(struct kvm_vcpu
    vmcs_writel(GUEST_CR4, hw_cr4);
    }

    -static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer)
    -{
    - struct vcpu_vmx *vmx = to_vmx(vcpu);
    - struct kvm_msr_entry *msr = find_msr_entry(vmx, MSR_EFER);
    -
    - vcpu->arch.shadow_efer = efer;
    - if (!msr)
    - return;
    - if (efer & EFER_LMA) {
    - vmcs_write32(VM_ENTRY_CONTROLS,
    - vmcs_read32(VM_ENTRY_CONTROLS) |
    - VM_ENTRY_IA32E_MODE);
    - msr->data = efer;
    -
    - } else {
    - vmcs_write32(VM_ENTRY_CONTROLS,
    - vmcs_read32(VM_ENTRY_CONTROLS) &
    - ~VM_ENTRY_IA32E_MODE);
    -
    - msr->data = efer & ~EFER_LME;
    - }
    - setup_msrs(vmx);
    -}
    -
    static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
    {
    struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];


    \
     
     \ /
      Last update: 2009-04-23 09:57    [W:4.122 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site