lkml.org 
[lkml]   [2020]   [Jun]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.7 217/265] KVM: nVMX: Plumb L2 GPA through to PML emulation
    Date
    From: Sean Christopherson <sean.j.christopherson@intel.com>

    commit 2dbebf7ae1ed9a420d954305e2c9d5ed39ec57c3 upstream.

    Explicitly pass the L2 GPA to kvm_arch_write_log_dirty(), which for all
    intents and purposes is vmx_write_pml_buffer(), instead of having the
    latter pull the GPA from vmcs.GUEST_PHYSICAL_ADDRESS. If the dirty bit
    update is the result of KVM emulation (rare for L2), then the GPA in the
    VMCS may be stale and/or hold a completely unrelated GPA.

    Fixes: c5f983f6e8455 ("nVMX: Implement emulated Page Modification Logging")
    Cc: stable@vger.kernel.org
    Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
    Message-Id: <20200622215832.22090-2-sean.j.christopherson@intel.com>
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    arch/x86/include/asm/kvm_host.h | 2 +-
    arch/x86/kvm/mmu.h | 2 +-
    arch/x86/kvm/mmu/mmu.c | 4 ++--
    arch/x86/kvm/mmu/paging_tmpl.h | 7 ++++---
    arch/x86/kvm/vmx/vmx.c | 6 +++---
    5 files changed, 11 insertions(+), 10 deletions(-)

    diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
    index 0a6b35353fc79..86e2e0272c576 100644
    --- a/arch/x86/include/asm/kvm_host.h
    +++ b/arch/x86/include/asm/kvm_host.h
    @@ -1195,7 +1195,7 @@ struct kvm_x86_ops {
    void (*enable_log_dirty_pt_masked)(struct kvm *kvm,
    struct kvm_memory_slot *slot,
    gfn_t offset, unsigned long mask);
    - int (*write_log_dirty)(struct kvm_vcpu *vcpu);
    + int (*write_log_dirty)(struct kvm_vcpu *vcpu, gpa_t l2_gpa);

    /* pmu operations of sub-arch */
    const struct kvm_pmu_ops *pmu_ops;
    diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
    index 8a3b1bce722a4..d0e3b1b6845b5 100644
    --- a/arch/x86/kvm/mmu.h
    +++ b/arch/x86/kvm/mmu.h
    @@ -222,7 +222,7 @@ void kvm_mmu_gfn_disallow_lpage(struct kvm_memory_slot *slot, gfn_t gfn);
    void kvm_mmu_gfn_allow_lpage(struct kvm_memory_slot *slot, gfn_t gfn);
    bool kvm_mmu_slot_gfn_write_protect(struct kvm *kvm,
    struct kvm_memory_slot *slot, u64 gfn);
    -int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu);
    +int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu, gpa_t l2_gpa);

    int kvm_mmu_post_init_vm(struct kvm *kvm);
    void kvm_mmu_pre_destroy_vm(struct kvm *kvm);
    diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
    index 92d0569541943..eb27ab47d6073 100644
    --- a/arch/x86/kvm/mmu/mmu.c
    +++ b/arch/x86/kvm/mmu/mmu.c
    @@ -1746,10 +1746,10 @@ void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm,
    * Emulate arch specific page modification logging for the
    * nested hypervisor
    */
    -int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu)
    +int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu, gpa_t l2_gpa)
    {
    if (kvm_x86_ops.write_log_dirty)
    - return kvm_x86_ops.write_log_dirty(vcpu);
    + return kvm_x86_ops.write_log_dirty(vcpu, l2_gpa);

    return 0;
    }
    diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h
    index 9bdf9b7d9a962..7098f843eabdd 100644
    --- a/arch/x86/kvm/mmu/paging_tmpl.h
    +++ b/arch/x86/kvm/mmu/paging_tmpl.h
    @@ -235,7 +235,7 @@ static inline unsigned FNAME(gpte_access)(u64 gpte)
    static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu,
    struct kvm_mmu *mmu,
    struct guest_walker *walker,
    - int write_fault)
    + gpa_t addr, int write_fault)
    {
    unsigned level, index;
    pt_element_t pte, orig_pte;
    @@ -260,7 +260,7 @@ static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu,
    !(pte & PT_GUEST_DIRTY_MASK)) {
    trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte));
    #if PTTYPE == PTTYPE_EPT
    - if (kvm_arch_write_log_dirty(vcpu))
    + if (kvm_arch_write_log_dirty(vcpu, addr))
    return -EINVAL;
    #endif
    pte |= PT_GUEST_DIRTY_MASK;
    @@ -457,7 +457,8 @@ retry_walk:
    (PT_GUEST_DIRTY_SHIFT - PT_GUEST_ACCESSED_SHIFT);

    if (unlikely(!accessed_dirty)) {
    - ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker, write_fault);
    + ret = FNAME(update_accessed_dirty_bits)(vcpu, mmu, walker,
    + addr, write_fault);
    if (unlikely(ret < 0))
    goto error;
    else if (ret)
    diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
    index 8f59f8c8fd05d..2d7ce012b1d5f 100644
    --- a/arch/x86/kvm/vmx/vmx.c
    +++ b/arch/x86/kvm/vmx/vmx.c
    @@ -7333,11 +7333,11 @@ static void vmx_flush_log_dirty(struct kvm *kvm)
    kvm_flush_pml_buffers(kvm);
    }

    -static int vmx_write_pml_buffer(struct kvm_vcpu *vcpu)
    +static int vmx_write_pml_buffer(struct kvm_vcpu *vcpu, gpa_t gpa)
    {
    struct vmcs12 *vmcs12;
    struct vcpu_vmx *vmx = to_vmx(vcpu);
    - gpa_t gpa, dst;
    + gpa_t dst;

    if (is_guest_mode(vcpu)) {
    WARN_ON_ONCE(vmx->nested.pml_full);
    @@ -7356,7 +7356,7 @@ static int vmx_write_pml_buffer(struct kvm_vcpu *vcpu)
    return 1;
    }

    - gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS) & ~0xFFFull;
    + gpa &= ~0xFFFull;
    dst = vmcs12->pml_address + sizeof(u64) * vmcs12->guest_pml_index;

    if (kvm_write_guest_page(vcpu->kvm, gpa_to_gfn(dst), &gpa,
    --
    2.25.1
    \
     
     \ /
      Last update: 2020-06-29 20:35    [W:4.034 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site