lkml.org 
[lkml]   [2021]   [Dec]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH V2 1/3] KVM: VMX: Save HOST_CR3 in vmx_prepare_switch_to_guest()
    Date
    From: Lai Jiangshan <laijs@linux.alibaba.com>

    The host CR3 in the vcpu thread can only be changed when scheduling.

    So HOST_CR3 can be saved only in vmx_prepare_switch_to_guest() and be
    synced in vmx_sync_vmcs_host_state() when switching VMCS.

    vmx_set_host_fs_gs() is called in both places, so it is renamed to
    vmx_set_vmcs_host_state() and it also updates the HOST_CR3.

    Signed-off-by: Lai Jiangshan <laijs@linux.alibaba.com>
    ---
    arch/x86/kvm/vmx/nested.c | 11 +++--------
    arch/x86/kvm/vmx/vmx.c | 21 +++++++++++----------
    arch/x86/kvm/vmx/vmx.h | 5 +++--
    3 files changed, 17 insertions(+), 20 deletions(-)

    diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
    index 26b236187850..d07a7fa75783 100644
    --- a/arch/x86/kvm/vmx/nested.c
    +++ b/arch/x86/kvm/vmx/nested.c
    @@ -245,7 +245,8 @@ static void vmx_sync_vmcs_host_state(struct vcpu_vmx *vmx,
    src = &prev->host_state;
    dest = &vmx->loaded_vmcs->host_state;

    - vmx_set_host_fs_gs(dest, src->fs_sel, src->gs_sel, src->fs_base, src->gs_base);
    + vmx_set_vmcs_host_state(dest, src->cr3, src->fs_sel, src->gs_sel,
    + src->fs_base, src->gs_base);
    dest->ldt_sel = src->ldt_sel;
    #ifdef CONFIG_X86_64
    dest->ds_sel = src->ds_sel;
    @@ -3054,7 +3055,7 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
    static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu)
    {
    struct vcpu_vmx *vmx = to_vmx(vcpu);
    - unsigned long cr3, cr4;
    + unsigned long cr4;
    bool vm_fail;

    if (!nested_early_check)
    @@ -3077,12 +3078,6 @@ static int nested_vmx_check_vmentry_hw(struct kvm_vcpu *vcpu)
    */
    vmcs_writel(GUEST_RFLAGS, 0);

    - cr3 = __get_current_cr3_fast();
    - if (unlikely(cr3 != vmx->loaded_vmcs->host_state.cr3)) {
    - vmcs_writel(HOST_CR3, cr3);
    - vmx->loaded_vmcs->host_state.cr3 = cr3;
    - }
    -
    cr4 = cr4_read_shadow();
    if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) {
    vmcs_writel(HOST_CR4, cr4);
    diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
    index 7826556b2a47..5f281f5ee961 100644
    --- a/arch/x86/kvm/vmx/vmx.c
    +++ b/arch/x86/kvm/vmx/vmx.c
    @@ -1069,9 +1069,14 @@ static void pt_guest_exit(struct vcpu_vmx *vmx)
    wrmsrl(MSR_IA32_RTIT_CTL, vmx->pt_desc.host.ctl);
    }

    -void vmx_set_host_fs_gs(struct vmcs_host_state *host, u16 fs_sel, u16 gs_sel,
    - unsigned long fs_base, unsigned long gs_base)
    +void vmx_set_vmcs_host_state(struct vmcs_host_state *host, unsigned long cr3,
    + u16 fs_sel, u16 gs_sel,
    + unsigned long fs_base, unsigned long gs_base)
    {
    + if (unlikely(cr3 != host->cr3)) {
    + vmcs_writel(HOST_CR3, cr3);
    + host->cr3 = cr3;
    + }
    if (unlikely(fs_sel != host->fs_sel)) {
    if (!(fs_sel & 7))
    vmcs_write16(HOST_FS_SELECTOR, fs_sel);
    @@ -1166,7 +1171,9 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
    gs_base = segment_base(gs_sel);
    #endif

    - vmx_set_host_fs_gs(host_state, fs_sel, gs_sel, fs_base, gs_base);
    + vmx_set_vmcs_host_state(host_state, __get_current_cr3_fast(),
    + fs_sel, gs_sel, fs_base, gs_base);
    +
    vmx->guest_state_loaded = true;
    }

    @@ -6629,7 +6636,7 @@ static noinstr void vmx_vcpu_enter_exit(struct kvm_vcpu *vcpu,
    static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
    {
    struct vcpu_vmx *vmx = to_vmx(vcpu);
    - unsigned long cr3, cr4;
    + unsigned long cr4;

    /* Record the guest's net vcpu time for enforced NMI injections. */
    if (unlikely(!enable_vnmi &&
    @@ -6674,12 +6681,6 @@ static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
    vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
    vcpu->arch.regs_dirty = 0;

    - cr3 = __get_current_cr3_fast();
    - if (unlikely(cr3 != vmx->loaded_vmcs->host_state.cr3)) {
    - vmcs_writel(HOST_CR3, cr3);
    - vmx->loaded_vmcs->host_state.cr3 = cr3;
    - }
    -
    cr4 = cr4_read_shadow();
    if (unlikely(cr4 != vmx->loaded_vmcs->host_state.cr4)) {
    vmcs_writel(HOST_CR4, cr4);
    diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
    index 99588aa8474b..acb874db02da 100644
    --- a/arch/x86/kvm/vmx/vmx.h
    +++ b/arch/x86/kvm/vmx/vmx.h
    @@ -374,8 +374,9 @@ int allocate_vpid(void);
    void free_vpid(int vpid);
    void vmx_set_constant_host_state(struct vcpu_vmx *vmx);
    void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu);
    -void vmx_set_host_fs_gs(struct vmcs_host_state *host, u16 fs_sel, u16 gs_sel,
    - unsigned long fs_base, unsigned long gs_base);
    +void vmx_set_vmcs_host_state(struct vmcs_host_state *host, unsigned long cr3,
    + u16 fs_sel, u16 gs_sel,
    + unsigned long fs_base, unsigned long gs_base);
    int vmx_get_cpl(struct kvm_vcpu *vcpu);
    bool vmx_emulation_required(struct kvm_vcpu *vcpu);
    unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu);
    --
    2.19.1.6.gb485710b
    \
     
     \ /
      Last update: 2021-12-16 03:20    [W:3.067 / U:1.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site