1. 28 10月, 2021 1 次提交
    • D
      KVM: x86: Take srcu lock in post_kvm_run_save() · f3d1436d
      David Woodhouse 提交于
      The Xen interrupt injection for event channels relies on accessing the
      guest's vcpu_info structure in __kvm_xen_has_interrupt(), through a
      gfn_to_hva_cache.
      
      This requires the srcu lock to be held, which is mostly the case except
      for this code path:
      
      [   11.822877] WARNING: suspicious RCU usage
      [   11.822965] -----------------------------
      [   11.823013] include/linux/kvm_host.h:664 suspicious rcu_dereference_check() usage!
      [   11.823131]
      [   11.823131] other info that might help us debug this:
      [   11.823131]
      [   11.823196]
      [   11.823196] rcu_scheduler_active = 2, debug_locks = 1
      [   11.823253] 1 lock held by dom:0/90:
      [   11.823292]  #0: ffff998956ec8118 (&vcpu->mutex){+.+.}, at: kvm_vcpu_ioctl+0x85/0x680
      [   11.823379]
      [   11.823379] stack backtrace:
      [   11.823428] CPU: 2 PID: 90 Comm: dom:0 Kdump: loaded Not tainted 5.4.34+ #5
      [   11.823496] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
      [   11.823612] Call Trace:
      [   11.823645]  dump_stack+0x7a/0xa5
      [   11.823681]  lockdep_rcu_suspicious+0xc5/0x100
      [   11.823726]  __kvm_xen_has_interrupt+0x179/0x190
      [   11.823773]  kvm_cpu_has_extint+0x6d/0x90
      [   11.823813]  kvm_cpu_accept_dm_intr+0xd/0x40
      [   11.823853]  kvm_vcpu_ready_for_interrupt_injection+0x20/0x30
                    < post_kvm_run_save() inlined here >
      [   11.823906]  kvm_arch_vcpu_ioctl_run+0x135/0x6a0
      [   11.823947]  kvm_vcpu_ioctl+0x263/0x680
      
      Fixes: 40da8ccd ("KVM: x86/xen: Add event channel interrupt vector upcall")
      Signed-off-by: NDavid Woodhouse <dwmw@amazon.co.uk>
      Cc: stable@vger.kernel.org
      Message-Id: <606aaaf29fca3850a63aa4499826104e77a72346.camel@infradead.org>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      f3d1436d
  2. 25 10月, 2021 1 次提交
    • D
      KVM: x86: switch pvclock_gtod_sync_lock to a raw spinlock · 8228c77d
      David Woodhouse 提交于
      On the preemption path when updating a Xen guest's runstate times, this
      lock is taken inside the scheduler rq->lock, which is a raw spinlock.
      This was shown in a lockdep warning:
      
      [   89.138354] =============================
      [   89.138356] [ BUG: Invalid wait context ]
      [   89.138358] 5.15.0-rc5+ #834 Tainted: G S        I E
      [   89.138360] -----------------------------
      [   89.138361] xen_shinfo_test/2575 is trying to lock:
      [   89.138363] ffffa34a0364efd8 (&kvm->arch.pvclock_gtod_sync_lock){....}-{3:3}, at: get_kvmclock_ns+0x1f/0x130 [kvm]
      [   89.138442] other info that might help us debug this:
      [   89.138444] context-{5:5}
      [   89.138445] 4 locks held by xen_shinfo_test/2575:
      [   89.138447]  #0: ffff972bdc3b8108 (&vcpu->mutex){+.+.}-{4:4}, at: kvm_vcpu_ioctl+0x77/0x6f0 [kvm]
      [   89.138483]  #1: ffffa34a03662e90 (&kvm->srcu){....}-{0:0}, at: kvm_arch_vcpu_ioctl_run+0xdc/0x8b0 [kvm]
      [   89.138526]  #2: ffff97331fdbac98 (&rq->__lock){-.-.}-{2:2}, at: __schedule+0xff/0xbd0
      [   89.138534]  #3: ffffa34a03662e90 (&kvm->srcu){....}-{0:0}, at: kvm_arch_vcpu_put+0x26/0x170 [kvm]
      ...
      [   89.138695]  get_kvmclock_ns+0x1f/0x130 [kvm]
      [   89.138734]  kvm_xen_update_runstate+0x14/0x90 [kvm]
      [   89.138783]  kvm_xen_update_runstate_guest+0x15/0xd0 [kvm]
      [   89.138830]  kvm_arch_vcpu_put+0xe6/0x170 [kvm]
      [   89.138870]  kvm_sched_out+0x2f/0x40 [kvm]
      [   89.138900]  __schedule+0x5de/0xbd0
      
      Cc: stable@vger.kernel.org
      Reported-by: syzbot+b282b65c2c68492df769@syzkaller.appspotmail.com
      Fixes: 30b5c851 ("KVM: x86/xen: Add support for vCPU runstate information")
      Signed-off-by: NDavid Woodhouse <dwmw@amazon.co.uk>
      Message-Id: <1b02a06421c17993df337493a68ba923f3bd5c0f.camel@infradead.org>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      8228c77d
  3. 22 10月, 2021 7 次提交
    • P
      KVM: SEV-ES: go over the sev_pio_data buffer in multiple passes if needed · 95e16b47
      Paolo Bonzini 提交于
      The PIO scratch buffer is larger than a single page, and therefore
      it is not possible to copy it in a single step to vcpu->arch/pio_data.
      Bound each call to emulator_pio_in/out to a single page; keep
      track of how many I/O operations are left in vcpu->arch.sev_pio_count,
      so that the operation can be restarted in the complete_userspace_io
      callback.
      
      For OUT, this means that the previous kvm_sev_es_outs implementation
      becomes an iterator of the loop, and we can consume the sev_pio_data
      buffer before leaving to userspace.
      
      For IN, instead, consuming the buffer and decreasing sev_pio_count
      is always done in the complete_userspace_io callback, because that
      is when the memcpy is done into sev_pio_data.
      
      Cc: stable@vger.kernel.org
      Fixes: 7ed9abfe ("KVM: SVM: Support string IO operations for an SEV-ES guest")
      Reported-by: NFelix Wilhelm <fwilhelm@google.com>
      Reviewed-by: NMaxim Levitsky <mlevitsk@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      95e16b47
    • P
      KVM: SEV-ES: keep INS functions together · 4fa4b38d
      Paolo Bonzini 提交于
      Make the diff a little nicer when we actually get to fixing
      the bug.  No functional change intended.
      
      Cc: stable@vger.kernel.org
      Fixes: 7ed9abfe ("KVM: SVM: Support string IO operations for an SEV-ES guest")
      Reviewed-by: NMaxim Levitsky <mlevitsk@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      4fa4b38d
    • P
      KVM: x86: remove unnecessary arguments from complete_emulator_pio_in · 6b5efc93
      Paolo Bonzini 提交于
      complete_emulator_pio_in can expect that vcpu->arch.pio has been filled in,
      and therefore does not need the size and count arguments.  This makes things
      nicer when the function is called directly from a complete_userspace_io
      callback.
      
      No functional change intended.
      
      Cc: stable@vger.kernel.org
      Fixes: 7ed9abfe ("KVM: SVM: Support string IO operations for an SEV-ES guest")
      Reviewed-by: NMaxim Levitsky <mlevitsk@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      6b5efc93
    • P
      KVM: x86: split the two parts of emulator_pio_in · 3b27de27
      Paolo Bonzini 提交于
      emulator_pio_in handles both the case where the data is pending in
      vcpu->arch.pio.count, and the case where I/O has to be done via either
      an in-kernel device or a userspace exit.  For SEV-ES we would like
      to split these, to identify clearly the moment at which the
      sev_pio_data is consumed.  To this end, create two different
      functions: __emulator_pio_in fills in vcpu->arch.pio.count, while
      complete_emulator_pio_in clears it and releases vcpu->arch.pio.data.
      
      Because this patch has to be backported, things are left a bit messy.
      kernel_pio() operates on vcpu->arch.pio, which leads to emulator_pio_in()
      having with two calls to complete_emulator_pio_in().  It will be fixed
      in the next release.
      
      While at it, remove the unused void* val argument of emulator_pio_in_out.
      The function currently hardcodes vcpu->arch.pio_data as the
      source/destination buffer, which sucks but will be fixed after the more
      severe SEV-ES buffer overflow.
      
      No functional change intended.
      
      Cc: stable@vger.kernel.org
      Fixes: 7ed9abfe ("KVM: SVM: Support string IO operations for an SEV-ES guest")
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      3b27de27
    • P
      KVM: SEV-ES: clean up kvm_sev_es_ins/outs · ea724ea4
      Paolo Bonzini 提交于
      A few very small cleanups to the functions, smushed together because
      the patch is already very small like this:
      
      - inline emulator_pio_in_emulated and emulator_pio_out_emulated,
        since we already have the vCPU
      
      - remove the data argument and pull setting vcpu->arch.sev_pio_data into
        the caller
      
      - remove unnecessary clearing of vcpu->arch.pio.count when
        emulation is done by the kernel (and therefore vcpu->arch.pio.count
        is already clear on exit from emulator_pio_in and emulator_pio_out).
      
      No functional change intended.
      
      Cc: stable@vger.kernel.org
      Fixes: 7ed9abfe ("KVM: SVM: Support string IO operations for an SEV-ES guest")
      Reviewed-by: NMaxim Levitsky <mlevitsk@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      ea724ea4
    • P
      KVM: x86: leave vcpu->arch.pio.count alone in emulator_pio_in_out · 0d33b1ba
      Paolo Bonzini 提交于
      Currently emulator_pio_in clears vcpu->arch.pio.count twice if
      emulator_pio_in_out performs kernel PIO.  Move the clear into
      emulator_pio_out where it is actually necessary.
      
      No functional change intended.
      
      Cc: stable@vger.kernel.org
      Fixes: 7ed9abfe ("KVM: SVM: Support string IO operations for an SEV-ES guest")
      Reviewed-by: NMaxim Levitsky <mlevitsk@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      0d33b1ba
    • P
      KVM: SEV-ES: rename guest_ins_data to sev_pio_data · b5998402
      Paolo Bonzini 提交于
      We will be using this field for OUTS emulation as well, in case the
      data that is pushed via OUTS spans more than one page.  In that case,
      there will be a need to save the data pointer across exits to userspace.
      
      So, change the name to something that refers to any kind of PIO.
      Also spell out what it is used for, namely SEV-ES.
      
      No functional change intended.
      
      Cc: stable@vger.kernel.org
      Fixes: 7ed9abfe ("KVM: SVM: Support string IO operations for an SEV-ES guest")
      Reviewed-by: NMaxim Levitsky <mlevitsk@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      b5998402
  4. 21 10月, 2021 1 次提交
  5. 19 10月, 2021 1 次提交
    • P
      KVM: X86: fix lazy allocation of rmaps · fa13843d
      Paolo Bonzini 提交于
      If allocation of rmaps fails, but some of the pointers have already been written,
      those pointers can be cleaned up when the memslot is freed, or even reused later
      for another attempt at allocating the rmaps.  Therefore there is no need to
      WARN, as done for example in memslot_rmap_alloc, but the allocation *must* be
      skipped lest KVM will overwrite the previous pointer and will indeed leak memory.
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      fa13843d
  6. 22 9月, 2021 6 次提交
    • F
      kvm: x86: Add AMD PMU MSRs to msrs_to_save_all[] · e1fc1553
      Fares Mehanna 提交于
      Intel PMU MSRs is in msrs_to_save_all[], so add AMD PMU MSRs to have a
      consistent behavior between Intel and AMD when using KVM_GET_MSRS,
      KVM_SET_MSRS or KVM_GET_MSR_INDEX_LIST.
      
      We have to add legacy and new MSRs to handle guests running without
      X86_FEATURE_PERFCTR_CORE.
      Signed-off-by: NFares Mehanna <faresx@amazon.de>
      Message-Id: <20210915133951.22389-1-faresx@amazon.de>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      e1fc1553
    • M
      KVM: x86: reset pdptrs_from_userspace when exiting smm · 37687c40
      Maxim Levitsky 提交于
      When exiting SMM, pdpts are loaded again from the guest memory.
      
      This fixes a theoretical bug, when exit from SMM triggers entry to the
      nested guest which re-uses some of the migration
      code which uses this flag as a workaround for a legacy userspace.
      Signed-off-by: NMaxim Levitsky <mlevitsk@redhat.com>
      Message-Id: <20210913140954.165665-4-mlevitsk@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      37687c40
    • S
      KVM: x86: Identify vCPU0 by its vcpu_idx instead of its vCPUs array entry · 94c245a2
      Sean Christopherson 提交于
      Use vcpu_idx to identify vCPU0 when updating HyperV's TSC page, which is
      shared by all vCPUs and "owned" by vCPU0 (because vCPU0 is the only vCPU
      that's guaranteed to exist).  Using kvm_get_vcpu() to find vCPU works,
      but it's a rather odd and suboptimal method to check the index of a given
      vCPU.
      
      No functional change intended.
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Reviewed-by: NJim Mattson <jmattson@google.com>
      Reviewed-by: NMaxim Levitsky <mlevitsk@redhat.com>
      Reviewed-by: NVitaly Kuznetsov <vkuznets@redhat.com>
      Message-Id: <20210910183220.2397812-3-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      94c245a2
    • H
      KVM: x86: Handle SRCU initialization failure during page track init · eb7511bf
      Haimin Zhang 提交于
      Check the return of init_srcu_struct(), which can fail due to OOM, when
      initializing the page track mechanism.  Lack of checking leads to a NULL
      pointer deref found by a modified syzkaller.
      Reported-by: NTCS Robot <tcs_robot@tencent.com>
      Signed-off-by: NHaimin Zhang <tcs_kernel@tencent.com>
      Message-Id: <1630636626-12262-1-git-send-email-tcs_kernel@tencent.com>
      [Move the call towards the beginning of kvm_arch_init_vm. - Paolo]
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      eb7511bf
    • S
      KVM: x86: Clear KVM's cached guest CR3 at RESET/INIT · 03a6e840
      Sean Christopherson 提交于
      Explicitly zero the guest's CR3 and mark it available+dirty at RESET/INIT.
      Per Intel's SDM and AMD's APM, CR3 is zeroed at both RESET and INIT.  For
      RESET, this is a nop as vcpu is zero-allocated.  For INIT, the bug has
      likely escaped notice because no firmware/kernel puts its page tables root
      at PA=0, let alone relies on INIT to get the desired CR3 for such page
      tables.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Message-Id: <20210921000303.400537-3-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      03a6e840
    • S
      KVM: x86: Mark all registers as avail/dirty at vCPU creation · 7117003f
      Sean Christopherson 提交于
      Mark all registers as available and dirty at vCPU creation, as the vCPU has
      obviously not been loaded into hardware, let alone been given the chance to
      be modified in hardware.  On SVM, reading from "uninitialized" hardware is
      a non-issue as VMCBs are zero allocated (thus not truly uninitialized) and
      hardware does not allow for arbitrary field encoding schemes.
      
      On VMX, backing memory for VMCSes is also zero allocated, but true
      initialization of the VMCS _technically_ requires VMWRITEs, as the VMX
      architectural specification technically allows CPU implementations to
      encode fields with arbitrary schemes.  E.g. a CPU could theoretically store
      the inverted value of every field, which would result in VMREAD to a
      zero-allocated field returns all ones.
      
      In practice, only the AR_BYTES fields are known to be manipulated by
      hardware during VMREAD/VMREAD; no known hardware or VMM (for nested VMX)
      does fancy encoding of cacheable field values (CR0, CR3, CR4, etc...).  In
      other words, this is technically a bug fix, but practically speakings it's
      a glorified nop.
      
      Failure to mark registers as available has been a lurking bug for quite
      some time.  The original register caching supported only GPRs (+RIP, which
      is kinda sorta a GPR), with the masks initialized at ->vcpu_reset().  That
      worked because the two cacheable registers, RIP and RSP, are generally
      speaking not read as side effects in other flows.
      
      Arguably, commit aff48baa ("KVM: Fetch guest cr3 from hardware on
      demand") was the first instance of failure to mark regs available.  While
      _just_ marking CR3 available during vCPU creation wouldn't have fixed the
      VMREAD from an uninitialized VMCS bug because ept_update_paging_mode_cr0()
      unconditionally read vmcs.GUEST_CR3, marking CR3 _and_ intentionally not
      reading GUEST_CR3 when it's available would have avoided VMREAD to a
      technically-uninitialized VMCS.
      
      Fixes: aff48baa ("KVM: Fetch guest cr3 from hardware on demand")
      Fixes: 6de4f3ad ("KVM: Cache pdptrs")
      Fixes: 6de12732 ("KVM: VMX: Optimize vmx_get_rflags()")
      Fixes: 2fb92db1 ("KVM: VMX: Cache vmcs segment fields")
      Fixes: bd31fe49 ("KVM: VMX: Add proper cache tracking for CR0")
      Fixes: f98c1e77 ("KVM: VMX: Add proper cache tracking for CR4")
      Fixes: 5addc235 ("KVM: VMX: Cache vmcs.EXIT_QUALIFICATION using arch avail_reg flags")
      Fixes: 87915858 ("KVM: VMX: Cache vmcs.EXIT_INTR_INFO using arch avail_reg flags")
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Message-Id: <20210921000303.400537-2-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      7117003f
  7. 06 9月, 2021 1 次提交
  8. 21 8月, 2021 7 次提交
    • M
      KVM: x86: implement KVM_GUESTDBG_BLOCKIRQ · 61e5f69e
      Maxim Levitsky 提交于
      KVM_GUESTDBG_BLOCKIRQ will allow KVM to block all interrupts
      while running.
      
      This change is mostly intended for more robust single stepping
      of the guest and it has the following benefits when enabled:
      
      * Resuming from a breakpoint is much more reliable.
        When resuming execution from a breakpoint, with interrupts enabled,
        more often than not, KVM would inject an interrupt and make the CPU
        jump immediately to the interrupt handler and eventually return to
        the breakpoint, to trigger it again.
      
        From the user point of view it looks like the CPU never executed a
        single instruction and in some cases that can even prevent forward
        progress, for example, when the breakpoint is placed by an automated
        script (e.g lx-symbols), which does something in response to the
        breakpoint and then continues the guest automatically.
        If the script execution takes enough time for another interrupt to
        arrive, the guest will be stuck on the same breakpoint RIP forever.
      
      * Normal single stepping is much more predictable, since it won't
        land the debugger into an interrupt handler.
      
      * RFLAGS.TF has less chance to be leaked to the guest:
      
        We set that flag behind the guest's back to do single stepping
        but if single step lands us into an interrupt/exception handler
        it will be leaked to the guest in the form of being pushed
        to the stack.
        This doesn't completely eliminate this problem as exceptions
        can still happen, but at least this reduces the chances
        of this happening.
      Signed-off-by: NMaxim Levitsky <mlevitsk@redhat.com>
      Message-Id: <20210811122927.900604-6-mlevitsk@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      61e5f69e
    • M
      KVM: x86/mmu: Add detailed page size stats · 71f51d2c
      Mingwei Zhang 提交于
      Existing KVM code tracks the number of large pages regardless of their
      sizes. Therefore, when large page of 1GB (or larger) is adopted, the
      information becomes less useful because lpages counts a mix of 1G and 2M
      pages.
      
      So remove the lpages since it is easy for user space to aggregate the info.
      Instead, provide a comprehensive page stats of all sizes from 4K to 512G.
      Suggested-by: NBen Gardon <bgardon@google.com>
      Reviewed-by: NDavid Matlack <dmatlack@google.com>
      Reviewed-by: NBen Gardon <bgardon@google.com>
      Signed-off-by: NMingwei Zhang <mizhang@google.com>
      Cc: Jing Zhang <jingzhangos@google.com>
      Cc: David Matlack <dmatlack@google.com>
      Cc: Sean Christopherson <seanjc@google.com>
      Message-Id: <20210803044607.599629-4-mizhang@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      71f51d2c
    • J
      KVM: stats: Support linear and logarithmic histogram statistics · f95937cc
      Jing Zhang 提交于
      Add new types of KVM stats, linear and logarithmic histogram.
      Histogram are very useful for observing the value distribution
      of time or size related stats.
      Signed-off-by: NJing Zhang <jingzhangos@google.com>
      Message-Id: <20210802165633.1866976-2-jingzhangos@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      f95937cc
    • M
      KVM: SVM: avoid refreshing avic if its state didn't change · 06ef8134
      Maxim Levitsky 提交于
      Since AVIC can be inhibited and uninhibited rapidly it is possible that
      we have nothing to do by the time the svm_refresh_apicv_exec_ctrl
      is called.
      
      Detect and avoid this, which will be useful when we will start calling
      avic_vcpu_load/avic_vcpu_put when the avic inhibition state changes.
      Signed-off-by: NMaxim Levitsky <mlevitsk@redhat.com>
      Message-Id: <20210810205251.424103-14-mlevitsk@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      06ef8134
    • M
      KVM: x86: APICv: fix race in kvm_request_apicv_update on SVM · b0a1637f
      Maxim Levitsky 提交于
      Currently on SVM, the kvm_request_apicv_update toggles the APICv
      memslot without doing any synchronization.
      
      If there is a mismatch between that memslot state and the AVIC state,
      on one of the vCPUs, an APIC mmio access can be lost:
      
      For example:
      
      VCPU0: enable the APIC_ACCESS_PAGE_PRIVATE_MEMSLOT
      VCPU1: access an APIC mmio register.
      
      Since AVIC is still disabled on VCPU1, the access will not be intercepted
      by it, and neither will it cause MMIO fault, but rather it will just be
      read/written from/to the dummy page mapped into the
      APIC_ACCESS_PAGE_PRIVATE_MEMSLOT.
      
      Fix that by adding a lock guarding the AVIC state changes, and carefully
      order the operations of kvm_request_apicv_update to avoid this race:
      
      1. Take the lock
      2. Send KVM_REQ_APICV_UPDATE
      3. Update the apic inhibit reason
      4. Release the lock
      
      This ensures that at (2) all vCPUs are kicked out of the guest mode,
      but don't yet see the new avic state.
      Then only after (4) all other vCPUs can update their AVIC state and resume.
      Signed-off-by: NMaxim Levitsky <mlevitsk@redhat.com>
      Message-Id: <20210810205251.424103-10-mlevitsk@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      b0a1637f
    • M
      KVM: x86: don't disable APICv memslot when inhibited · 36222b11
      Maxim Levitsky 提交于
      Thanks to the former patches, it is now possible to keep the APICv
      memslot always enabled, and it will be invisible to the guest
      when it is inhibited
      
      This code is based on a suggestion from Sean Christopherson:
      https://lkml.org/lkml/2021/7/19/2970Suggested-by: NSean Christopherson <seanjc@google.com>
      Signed-off-by: NMaxim Levitsky <mlevitsk@redhat.com>
      Message-Id: <20210810205251.424103-9-mlevitsk@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      36222b11
    • P
      KVM: X86: Introduce kvm_mmu_slot_lpages() helpers · 4139b197
      Peter Xu 提交于
      Introduce kvm_mmu_slot_lpages() to calculcate lpage_info and rmap array size.
      The other __kvm_mmu_slot_lpages() can take an extra parameter of npages rather
      than fetching from the memslot pointer.  Start to use the latter one in
      kvm_alloc_memslot_metadata().
      Signed-off-by: NPeter Xu <peterx@redhat.com>
      Message-Id: <20210730220455.26054-4-peterx@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      4139b197
  9. 13 8月, 2021 4 次提交
    • S
      KVM: x86: Kill off __ex() and __kvm_handle_fault_on_reboot() · ad0577c3
      Sean Christopherson 提交于
      Remove the __kvm_handle_fault_on_reboot() and __ex() macros now that all
      VMX and SVM instructions use asm goto to handle the fault (or in the
      case of VMREAD, completely custom logic).  Drop kvm_spurious_fault()'s
      asmlinkage annotation as __kvm_handle_fault_on_reboot() was the only
      flow that invoked it from assembly code.
      
      Cc: Uros Bizjak <ubizjak@gmail.com>
      Cc: Like Xu <like.xu.linux@gmail.com>
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Message-Id: <20210809173955.1710866-2-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      ad0577c3
    • P
      KVM: VMX: Reset DR6 only when KVM_DEBUGREG_WONT_EXIT · 1ccb6f98
      Paolo Bonzini 提交于
      The commit efdab992 ("KVM: x86: fix escape of guest dr6 to the host")
      fixed a bug by resetting DR6 unconditionally when the vcpu being scheduled out.
      
      But writing to debug registers is slow, and it can be visible in perf results
      sometimes, even if neither the host nor the guest activate breakpoints.
      
      Since KVM_DEBUGREG_WONT_EXIT on Intel processors is the only case
      where DR6 gets the guest value, and it never happens at all on SVM,
      the register can be cleared in vmx.c right after reading it.
      Reported-by: NLai Jiangshan <laijs@linux.alibaba.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      1ccb6f98
    • P
      KVM: X86: Set host DR6 only on VMX and for KVM_DEBUGREG_WONT_EXIT · 375e28ff
      Paolo Bonzini 提交于
      Commit c77fb5fe ("KVM: x86: Allow the guest to run with dirty debug
      registers") allows the guest accessing to DRs without exiting when
      KVM_DEBUGREG_WONT_EXIT and we need to ensure that they are synchronized
      on entry to the guest---including DR6 that was not synced before the commit.
      
      But the commit sets the hardware DR6 not only when KVM_DEBUGREG_WONT_EXIT,
      but also when KVM_DEBUGREG_BP_ENABLED.  The second case is unnecessary
      and just leads to a more case which leaks stale DR6 to the host which has
      to be resolved by unconditionally reseting DR6 in kvm_arch_vcpu_put().
      
      Even if KVM_DEBUGREG_WONT_EXIT, however, setting the host DR6 only matters
      on VMX because SVM always uses the DR6 value from the VMCB.  So move this
      line to vmx.c and make it conditional on KVM_DEBUGREG_WONT_EXIT.
      Reported-by: NLai Jiangshan <jiangshanlai@gmail.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      375e28ff
    • L
      KVM: X86: Remove unneeded KVM_DEBUGREG_RELOAD · 34e9f860
      Lai Jiangshan 提交于
      Commit ae561ede ("KVM: x86: DR0-DR3 are not clear on reset") added code to
      ensure eff_db are updated when they're modified through non-standard paths.
      
      But there is no reason to also update hardware DRs unless hardware breakpoints
      are active or DR exiting is disabled, and in those cases updating hardware is
      handled by KVM_DEBUGREG_WONT_EXIT and KVM_DEBUGREG_BP_ENABLED.
      
      KVM_DEBUGREG_RELOAD just causes unnecesarry load of hardware DRs and is better
      to be removed.
      Suggested-by: NSean Christopherson <seanjc@google.com>
      Signed-off-by: NLai Jiangshan <laijs@linux.alibaba.com>
      Message-Id: <20210809174307.145263-1-jiangshanlai@gmail.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      34e9f860
  10. 05 8月, 2021 1 次提交
    • P
      KVM: xen: do not use struct gfn_to_hva_cache · 319afe68
      Paolo Bonzini 提交于
      gfn_to_hva_cache is not thread-safe, so it is usually used only within
      a vCPU (whose code is protected by vcpu->mutex).  The Xen interface
      implementation has such a cache in kvm->arch, but it is not really
      used except to store the location of the shared info page.  Replace
      shinfo_set and shinfo_cache with just the value that is passed via
      KVM_XEN_ATTR_TYPE_SHARED_INFO; the only complication is that the
      initialization value is not zero anymore and therefore kvm_xen_init_vm
      needs to be introduced.
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      319afe68
  11. 03 8月, 2021 1 次提交
  12. 02 8月, 2021 9 次提交
    • S
      KVM: x86: Preserve guest's CR0.CD/NW on INIT · 4c72ab5a
      Sean Christopherson 提交于
      Preserve CR0.CD and CR0.NW on INIT instead of forcing them to '1', as
      defined by both Intel's SDM and AMD's APM.
      
      Note, current versions of Intel's SDM are very poorly written with
      respect to INIT behavior.  Table 9-1. "IA-32 and Intel 64 Processor
      States Following Power-up, Reset, or INIT" quite clearly lists power-up,
      RESET, _and_ INIT as setting CR0=60000010H, i.e. CD/NW=1.  But the SDM
      then attempts to qualify CD/NW behavior in a footnote:
      
        2. The CD and NW flags are unchanged, bit 4 is set to 1, all other bits
           are cleared.
      
      Presumably that footnote is only meant for INIT, as the RESET case and
      especially the power-up case are rather non-sensical.  Another footnote
      all but confirms that:
      
        6. Internal caches are invalid after power-up and RESET, but left
           unchanged with an INIT.
      
      Bare metal testing shows that CD/NW are indeed preserved on INIT (someone
      else can hack their BIOS to check RESET and power-up :-D).
      Reported-by: NReiji Watanabe <reijiw@google.com>
      Reviewed-by: NReiji Watanabe <reijiw@google.com>
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Message-Id: <20210713163324.627647-47-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      4c72ab5a
    • S
      KVM: SVM: Emulate #INIT in response to triple fault shutdown · 265e4353
      Sean Christopherson 提交于
      Emulate a full #INIT instead of simply initializing the VMCB if the
      guest hits a shutdown.  Initializing the VMCB but not other vCPU state,
      much of which is mirrored by the VMCB, results in incoherent and broken
      vCPU state.
      
      Ideally, KVM would not automatically init anything on shutdown, and
      instead put the vCPU into e.g. KVM_MP_STATE_UNINITIALIZED and force
      userspace to explicitly INIT or RESET the vCPU.  Even better would be to
      add KVM_MP_STATE_SHUTDOWN, since technically NMI can break shutdown
      (and SMI on Intel CPUs).
      
      But, that ship has sailed, and emulating #INIT is the next best thing as
      that has at least some connection with reality since there exist bare
      metal platforms that automatically INIT the CPU if it hits shutdown.
      
      Fixes: 46fe4ddd ("[PATCH] KVM: SVM: Propagate cpu shutdown events to userspace")
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Message-Id: <20210713163324.627647-45-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      265e4353
    • S
      KVM: x86: Move setting of sregs during vCPU RESET/INIT to common x86 · f39e805e
      Sean Christopherson 提交于
      Move the setting of CR0, CR4, EFER, RFLAGS, and RIP from vendor code to
      common x86.  VMX and SVM now have near-identical sequences, the only
      difference being that VMX updates the exception bitmap.  Updating the
      bitmap on SVM is unnecessary, but benign.  Unfortunately it can't be left
      behind in VMX due to the need to update exception intercepts after the
      control registers are set.
      Reviewed-by: NReiji Watanabe <reijiw@google.com>
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Message-Id: <20210713163324.627647-37-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      f39e805e
    • S
      KVM: x86/mmu: Skip the permission_fault() check on MMIO if CR0.PG=0 · 908b7d43
      Sean Christopherson 提交于
      Skip the MMU permission_fault() check if paging is disabled when
      verifying the cached MMIO GVA is usable.  The check is unnecessary and
      can theoretically get a false positive since the MMU doesn't zero out
      "permissions" or "pkru_mask" when guest paging is disabled.
      
      The obvious alternative is to zero out all the bitmasks when configuring
      nonpaging MMUs, but that's unnecessary work and doesn't align with the
      MMU's general approach of doing as little as possible for flows that are
      supposed to be unreachable.
      
      This is nearly a nop as the false positive is nothing more than an
      insignificant performance blip, and more or less limited to string MMIO
      when L1 is running with paging disabled.  KVM doesn't cache MMIO if L2 is
      active with nested TDP since the "GVA" is really an L2 GPA.  If L2 is
      active without nested TDP, then paging can't be disabled as neither VMX
      nor SVM allows entering the guest without paging of some form.
      
      Jumping back to L1 with paging disabled, in that case direct_map is true
      and so KVM will use CR2 as a GPA; the only time it doesn't is if the
      fault from the emulator doesn't match or emulator_can_use_gpa(), and that
      fails only on string MMIO and other instructions with multiple memory
      operands.
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Message-Id: <20210713163324.627647-27-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      908b7d43
    • S
      KVM: x86: Move EDX initialization at vCPU RESET to common code · 49d8665c
      Sean Christopherson 提交于
      Move the EDX initialization at vCPU RESET, which is now identical between
      VMX and SVM, into common code.
      
      No functional change intended.
      Reviewed-by: NReiji Watanabe <reijiw@google.com>
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Message-Id: <20210713163324.627647-20-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      49d8665c
    • S
      KVM: x86: Flush the guest's TLB on INIT · df37ed38
      Sean Christopherson 提交于
      Flush the guest's TLB on INIT, as required by Intel's SDM.  Although
      AMD's APM states that the TLBs are unchanged by INIT, it's not clear that
      that's correct as the APM also states that the TLB is flush on "External
      initialization of the processor."  Regardless, relying on the guest to be
      paranoid is unnecessarily risky, while an unnecessary flush is benign
      from a functional perspective and likely has no measurable impact on
      guest performance.
      
      Note, as of the April 2021 version of Intels' SDM, it also contradicts
      itself with respect to TLB flushing.  The overview of INIT explicitly
      calls out the TLBs as being invalidated, while a table later in the same
      section says they are unchanged.
      
        9.1 INITIALIZATION OVERVIEW:
          The major difference is that during an INIT, the internal caches, MSRs,
          MTRRs, and x87 FPU state are left unchanged (although, the TLBs and BTB
          are invalidated as with a hardware reset)
      
        Table 9-1:
      
        Register                    Power up    Reset      INIT
        Data and Code Cache, TLBs:  Invalid[6]  Invalid[6] Unchanged
      
      Given Core2's erratum[*] about global TLB entries not being flush on INIT,
      it's safe to assume that the table is simply wrong.
      
        AZ28. INIT Does Not Clear Global Entries in the TLB
        Problem: INIT may not flush a TLB entry when:
          • The processor is in protected mode with paging enabled and the page global enable
            flag is set (PGE bit of CR4 register)
          • G bit for the page table entry is set
          • TLB entry is present in TLB when INIT occurs
          • Software may encounter unexpected page fault or incorrect address translation due
            to a TLB entry erroneously left in TLB after INIT.
      
        Workaround: Write to CR3, CR4 (setting bits PSE, PGE or PAE) or CR0 (setting
                    bits PG or PE) registers before writing to memory early in BIOS
                    code to clear all the global entries from TLB.
      
        Status: For the steppings affected, see the Summary Tables of Changes.
      
      [*] https://www.intel.com/content/dam/support/us/en/documents/processors/mobile/celeron/sb/320121.pdf
      
      Fixes: 6aa8b732 ("[PATCH] kvm: userspace interface")
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Message-Id: <20210713163324.627647-2-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      df37ed38
    • M
      KVM: x86: APICv: drop immediate APICv disablement on current vCPU · df63202f
      Maxim Levitsky 提交于
      Special case of disabling the APICv on the current vCPU right away in
      kvm_request_apicv_update doesn't bring much benefit vs raising
      KVM_REQ_APICV_UPDATE on it instead, since this request will be processed
      on the next entry to the guest.
      (the comment about having another #VMEXIT is wrong).
      
      It also hides various assumptions that APIVc enable state matches
      the APICv inhibit state, as this special case only makes those states
      match on the current vCPU.
      
      Previous patches fixed few such assumptions so now it should be safe
      to drop this special case.
      Signed-off-by: NMaxim Levitsky <mlevitsk@redhat.com>
      Message-Id: <20210713142023.106183-5-mlevitsk@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      df63202f
    • P
      KVM: X86: Add per-vm stat for max rmap list size · ec1cf69c
      Peter Xu 提交于
      Add a new statistic max_mmu_rmap_size, which stores the maximum size of rmap
      for the vm.
      Signed-off-by: NPeter Xu <peterx@redhat.com>
      Message-Id: <20210625153214.43106-2-peterx@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      ec1cf69c
    • S
      KVM: x86: Hoist kvm_dirty_regs check out of sync_regs() · e489a4a6
      Sean Christopherson 提交于
      Move the kvm_dirty_regs vs. KVM_SYNC_X86_VALID_FIELDS check out of
      sync_regs() and into its sole caller, kvm_arch_vcpu_ioctl_run().  This
      allows a future patch to allow synchronizing select state for protected
      VMs.
      Signed-off-by: NSean Christopherson <sean.j.christopherson@intel.com>
      Signed-off-by: NIsaku Yamahata <isaku.yamahata@intel.com>
      Reviewed-by: NPaolo Bonzini <pbonzini@redhat.com>
      Message-Id: <889017a8d31cea46472e0c64b234ef5919278ed9.1625186503.git.isaku.yamahata@intel.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      e489a4a6