lkml.org 
[lkml]   [2020]   [May]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 02/10] KVM: nVMX: Unconditionally validate CR3 during nested transitions
    Date
    Unconditionally check the validity of the incoming CR3 during nested
    VM-Enter/VM-Exit to avoid invoking kvm_read_cr3() in the common case
    where the guest isn't using PAE paging. If vmcs.GUEST_CR3 hasn't yet
    been cached (common case), kvm_read_cr3() will trigger a VMREAD. The
    VMREAD (~30 cycles) alone is likely slower than nested_cr3_valid()
    (~5 cycles if vcpu->arch.maxphyaddr gets a cache hit), and the poor
    exchange only gets worse when retpolines are enabled as the call to
    kvm_x86_ops.cache_reg() will incur a retpoline (60+ cycles).

    Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
    ---
    arch/x86/kvm/vmx/nested.c | 27 +++++++++++++--------------
    1 file changed, 13 insertions(+), 14 deletions(-)

    diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
    index b57420f3dd8f..1f2f41e821f9 100644
    --- a/arch/x86/kvm/vmx/nested.c
    +++ b/arch/x86/kvm/vmx/nested.c
    @@ -1120,21 +1120,20 @@ static bool nested_vmx_transition_mmu_sync(struct kvm_vcpu *vcpu)
    static int nested_vmx_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3, bool nested_ept,
    u32 *entry_failure_code)
    {
    - if (cr3 != kvm_read_cr3(vcpu) || (!nested_ept && pdptrs_changed(vcpu))) {
    - if (CC(!nested_cr3_valid(vcpu, cr3))) {
    - *entry_failure_code = ENTRY_FAIL_DEFAULT;
    - return -EINVAL;
    - }
    + if (CC(!nested_cr3_valid(vcpu, cr3))) {
    + *entry_failure_code = ENTRY_FAIL_DEFAULT;
    + return -EINVAL;
    + }

    - /*
    - * If PAE paging and EPT are both on, CR3 is not used by the CPU and
    - * must not be dereferenced.
    - */
    - if (is_pae_paging(vcpu) && !nested_ept) {
    - if (CC(!load_pdptrs(vcpu, vcpu->arch.walk_mmu, cr3))) {
    - *entry_failure_code = ENTRY_FAIL_PDPTE;
    - return -EINVAL;
    - }
    + /*
    + * If PAE paging and EPT are both on, CR3 is not used by the CPU and
    + * must not be dereferenced.
    + */
    + if (!nested_ept && is_pae_paging(vcpu) &&
    + (cr3 != kvm_read_cr3(vcpu) || pdptrs_changed(vcpu))) {
    + if (CC(!load_pdptrs(vcpu, vcpu->arch.walk_mmu, cr3))) {
    + *entry_failure_code = ENTRY_FAIL_PDPTE;
    + return -EINVAL;
    }
    }

    --
    2.26.0
    \
     
     \ /
      Last update: 2020-05-02 06:33    [W:3.264 / U:0.276 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site