1. 15 3月, 2021 3 次提交
    • S
      KVM: x86: Handle triple fault in L2 without killing L1 · cb6a32c2
      Sean Christopherson 提交于
      Synthesize a nested VM-Exit if L2 triggers an emulated triple fault
      instead of exiting to userspace, which likely will kill L1.  Any flow
      that does KVM_REQ_TRIPLE_FAULT is suspect, but the most common scenario
      for L2 killing L1 is if L0 (KVM) intercepts a contributory exception that
      is _not_intercepted by L1.  E.g. if KVM is intercepting #GPs for the
      VMware backdoor, a #GP that occurs in L2 while vectoring an injected #DF
      will cause KVM to emulate triple fault.
      
      Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
      Cc: Jim Mattson <jmattson@google.com>
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Message-Id: <20210302174515.2812275-2-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      cb6a32c2
    • S
      KVM: x86/mmu: Unexport MMU load/unload functions · 61a1773e
      Sean Christopherson 提交于
      Unexport the MMU load and unload helpers now that they are no longer
      used (incorrectly) in vendor code.
      
      Opportunistically move the kvm_mmu_sync_roots() declaration into mmu.h,
      it should not be exposed to vendor code.
      
      No functional change intended.
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Message-Id: <20210305011101.3597423-16-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      61a1773e
    • D
      KVM: x86: to track if L1 is running L2 VM · 43c11d91
      Dongli Zhang 提交于
      The new per-cpu stat 'nested_run' is introduced in order to track if L1 VM
      is running or used to run L2 VM.
      
      An example of the usage of 'nested_run' is to help the host administrator
      to easily track if any L1 VM is used to run L2 VM. Suppose there is issue
      that may happen with nested virtualization, the administrator will be able
      to easily narrow down and confirm if the issue is due to nested
      virtualization via 'nested_run'. For example, whether the fix like
      commit 88dddc11 ("KVM: nVMX: do not use dangling shadow VMCS after
      guest reset") is required.
      
      Cc: Joe Jin <joe.jin@oracle.com>
      Signed-off-by: NDongli Zhang <dongli.zhang@oracle.com>
      Message-Id: <20210305225747.7682-1-dongli.zhang@oracle.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      43c11d91
  2. 13 3月, 2021 1 次提交
    • M
      kvm: x86: annotate RCU pointers · 6fcd9cbc
      Muhammad Usama Anjum 提交于
      This patch adds the annotation to fix the following sparse errors:
      arch/x86/kvm//x86.c:8147:15: error: incompatible types in comparison expression (different address spaces):
      arch/x86/kvm//x86.c:8147:15:    struct kvm_apic_map [noderef] __rcu *
      arch/x86/kvm//x86.c:8147:15:    struct kvm_apic_map *
      arch/x86/kvm//x86.c:10628:16: error: incompatible types in comparison expression (different address spaces):
      arch/x86/kvm//x86.c:10628:16:    struct kvm_apic_map [noderef] __rcu *
      arch/x86/kvm//x86.c:10628:16:    struct kvm_apic_map *
      arch/x86/kvm//x86.c:10629:15: error: incompatible types in comparison expression (different address spaces):
      arch/x86/kvm//x86.c:10629:15:    struct kvm_pmu_event_filter [noderef] __rcu *
      arch/x86/kvm//x86.c:10629:15:    struct kvm_pmu_event_filter *
      arch/x86/kvm//lapic.c:267:15: error: incompatible types in comparison expression (different address spaces):
      arch/x86/kvm//lapic.c:267:15:    struct kvm_apic_map [noderef] __rcu *
      arch/x86/kvm//lapic.c:267:15:    struct kvm_apic_map *
      arch/x86/kvm//lapic.c:269:9: error: incompatible types in comparison expression (different address spaces):
      arch/x86/kvm//lapic.c:269:9:    struct kvm_apic_map [noderef] __rcu *
      arch/x86/kvm//lapic.c:269:9:    struct kvm_apic_map *
      arch/x86/kvm//lapic.c:637:15: error: incompatible types in comparison expression (different address spaces):
      arch/x86/kvm//lapic.c:637:15:    struct kvm_apic_map [noderef] __rcu *
      arch/x86/kvm//lapic.c:637:15:    struct kvm_apic_map *
      arch/x86/kvm//lapic.c:994:15: error: incompatible types in comparison expression (different address spaces):
      arch/x86/kvm//lapic.c:994:15:    struct kvm_apic_map [noderef] __rcu *
      arch/x86/kvm//lapic.c:994:15:    struct kvm_apic_map *
      arch/x86/kvm//lapic.c:1036:15: error: incompatible types in comparison expression (different address spaces):
      arch/x86/kvm//lapic.c:1036:15:    struct kvm_apic_map [noderef] __rcu *
      arch/x86/kvm//lapic.c:1036:15:    struct kvm_apic_map *
      arch/x86/kvm//lapic.c:1173:15: error: incompatible types in comparison expression (different address spaces):
      arch/x86/kvm//lapic.c:1173:15:    struct kvm_apic_map [noderef] __rcu *
      arch/x86/kvm//lapic.c:1173:15:    struct kvm_apic_map *
      arch/x86/kvm//pmu.c:190:18: error: incompatible types in comparison expression (different address spaces):
      arch/x86/kvm//pmu.c:190:18:    struct kvm_pmu_event_filter [noderef] __rcu *
      arch/x86/kvm//pmu.c:190:18:    struct kvm_pmu_event_filter *
      arch/x86/kvm//pmu.c:251:18: error: incompatible types in comparison expression (different address spaces):
      arch/x86/kvm//pmu.c:251:18:    struct kvm_pmu_event_filter [noderef] __rcu *
      arch/x86/kvm//pmu.c:251:18:    struct kvm_pmu_event_filter *
      arch/x86/kvm//pmu.c:522:18: error: incompatible types in comparison expression (different address spaces):
      arch/x86/kvm//pmu.c:522:18:    struct kvm_pmu_event_filter [noderef] __rcu *
      arch/x86/kvm//pmu.c:522:18:    struct kvm_pmu_event_filter *
      arch/x86/kvm//pmu.c:522:18: error: incompatible types in comparison expression (different address spaces):
      arch/x86/kvm//pmu.c:522:18:    struct kvm_pmu_event_filter [noderef] __rcu *
      arch/x86/kvm//pmu.c:522:18:    struct kvm_pmu_event_filter *
      Signed-off-by: NMuhammad Usama Anjum <musamaanjum@gmail.com>
      Message-Id: <20210305191123.GA497469@LEGION>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      6fcd9cbc
  3. 03 3月, 2021 1 次提交
    • D
      KVM: x86/xen: Add support for vCPU runstate information · 30b5c851
      David Woodhouse 提交于
      This is how Xen guests do steal time accounting. The hypervisor records
      the amount of time spent in each of running/runnable/blocked/offline
      states.
      
      In the Xen accounting, a vCPU is still in state RUNSTATE_running while
      in Xen for a hypercall or I/O trap, etc. Only if Xen explicitly schedules
      does the state become RUNSTATE_blocked. In KVM this means that even when
      the vCPU exits the kvm_run loop, the state remains RUNSTATE_running.
      
      The VMM can explicitly set the vCPU to RUNSTATE_blocked by using the
      KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT attribute, and can also use
      KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST to retrospectively add a given
      amount of time to the blocked state and subtract it from the running
      state.
      
      The state_entry_time corresponds to get_kvmclock_ns() at the time the
      vCPU entered the current state, and the total times of all four states
      should always add up to state_entry_time.
      Co-developed-by: NJoao Martins <joao.m.martins@oracle.com>
      Signed-off-by: NJoao Martins <joao.m.martins@oracle.com>
      Signed-off-by: NDavid Woodhouse <dwmw@amazon.co.uk>
      Message-Id: <20210301125309.874953-2-dwmw2@infradead.org>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      30b5c851
  4. 26 2月, 2021 1 次提交
  5. 19 2月, 2021 5 次提交
  6. 09 2月, 2021 5 次提交
    • V
      KVM: x86: hyper-v: Make Hyper-V emulation enablement conditional · 8f014550
      Vitaly Kuznetsov 提交于
      Hyper-V emulation is enabled in KVM unconditionally. This is bad at least
      from security standpoint as it is an extra attack surface. Ideally, there
      should be a per-VM capability explicitly enabled by VMM but currently it
      is not the case and we can't mandate one without breaking backwards
      compatibility. We can, however, check guest visible CPUIDs and only enable
      Hyper-V emulation when "Hv#1" interface was exposed in
      HYPERV_CPUID_INTERFACE.
      
      Note, VMMs are free to act in any sequence they like, e.g. they can try
      to set MSRs first and CPUIDs later so we still need to allow the host
      to read/write Hyper-V specific MSRs unconditionally.
      Signed-off-by: NVitaly Kuznetsov <vkuznets@redhat.com>
      Message-Id: <20210126134816.1880136-14-vkuznets@redhat.com>
      [Add selftest vcpu_set_hv_cpuid API to avoid breaking xen_vmcall_test. - Paolo]
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      8f014550
    • V
      KVM: x86: hyper-v: Allocate 'struct kvm_vcpu_hv' dynamically · 4592b7ea
      Vitaly Kuznetsov 提交于
      Hyper-V context is only needed for guests which use Hyper-V emulation in
      KVM (e.g. Windows/Hyper-V guests). 'struct kvm_vcpu_hv' is, however, quite
      big, it accounts for more than 1/4 of the total 'struct kvm_vcpu_arch'
      which is also quite big already. This all looks like a waste.
      
      Allocate 'struct kvm_vcpu_hv' dynamically. This patch does not bring any
      (intentional) functional change as we still allocate the context
      unconditionally but it paves the way to doing that only when needed.
      Signed-off-by: NVitaly Kuznetsov <vkuznets@redhat.com>
      Message-Id: <20210126134816.1880136-13-vkuznets@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      4592b7ea
    • V
      KVM: Raise the maximum number of user memslots · 4fc096a9
      Vitaly Kuznetsov 提交于
      Current KVM_USER_MEM_SLOTS limits are arch specific (512 on Power, 509 on x86,
      32 on s390, 16 on MIPS) but they don't really need to be. Memory slots are
      allocated dynamically in KVM when added so the only real limitation is
      'id_to_index' array which is 'short'. We don't have any other
      KVM_MEM_SLOTS_NUM/KVM_USER_MEM_SLOTS-sized statically defined structures.
      
      Low KVM_USER_MEM_SLOTS can be a limiting factor for some configurations.
      In particular, when QEMU tries to start a Windows guest with Hyper-V SynIC
      enabled and e.g. 256 vCPUs the limit is hit as SynIC requires two pages per
      vCPU and the guest is free to pick any GFN for each of them, this fragments
      memslots as QEMU wants to have a separate memslot for each of these pages
      (which are supposed to act as 'overlay' pages).
      Signed-off-by: NVitaly Kuznetsov <vkuznets@redhat.com>
      Message-Id: <20210127175731.2020089-3-vkuznets@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      4fc096a9
    • P
      KVM: x86: reading DR cannot fail · 29d6ca41
      Paolo Bonzini 提交于
      kvm_get_dr and emulator_get_dr except an in-range value for the register
      number so they cannot fail.  Change the return type to void.
      Suggested-by: NSean Christopherson <seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      29d6ca41
    • P
      KVM: x86: compile out TDP MMU on 32-bit systems · 897218ff
      Paolo Bonzini 提交于
      The TDP MMU assumes that it can do atomic accesses to 64-bit PTEs.
      Rather than just disabling it, compile it out completely so that it
      is possible to use for example 64-bit xchg.
      
      To limit the number of stubs, wrap all accesses to tdp_mmu_enabled
      or tdp_mmu_page with a function.  Calls to all other functions in
      tdp_mmu.c are eliminated and do not even reach the linker.
      Reviewed-by: NSean Christopherson <seanjc@google.com>
      Tested-by: NSean Christopherson <seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      897218ff
  7. 04 2月, 2021 14 次提交
    • S
      KVM: x86: SEV: Treat C-bit as legal GPA bit regardless of vCPU mode · ca29e145
      Sean Christopherson 提交于
      Rename cr3_lm_rsvd_bits to reserved_gpa_bits, and use it for all GPA
      legality checks.  AMD's APM states:
      
        If the C-bit is an address bit, this bit is masked from the guest
        physical address when it is translated through the nested page tables.
      
      Thus, any access that can conceivably be run through NPT should ignore
      the C-bit when checking for validity.
      
      For features that KVM emulates in software, e.g. MTRRs, there is no
      clear direction in the APM for how the C-bit should be handled.  For
      such cases, follow the SME behavior inasmuch as possible, since SEV is
      is essentially a VM-specific variant of SME.  For SME, the APM states:
      
        In this case the upper physical address bits are treated as reserved
        when the feature is enabled except where otherwise indicated.
      
      Collecting the various relavant SME snippets in the APM and cross-
      referencing the omissions with Linux kernel code, this leaves MTTRs and
      APIC_BASE as the only flows that KVM emulates that should _not_ ignore
      the C-bit.
      
      Note, this means the reserved bit checks in the page tables are
      technically broken.  This will be remedied in a future patch.
      
      Although the page table checks are technically broken, in practice, it's
      all but guaranteed to be irrelevant.  NPT is required for SEV, i.e.
      shadowing page tables isn't needed in the common case.  Theoretically,
      the checks could be in play for nested NPT, but it's extremely unlikely
      that anyone is running nested VMs on SEV, as doing so would require L1
      to expose sensitive data to L0, e.g. the entire VMCB.  And if anyone is
      running nested VMs, L0 can't read the guest's encrypted memory, i.e. L1
      would need to put its NPT in shared memory, in which case the C-bit will
      never be set.  Or, L1 could use shadow paging, but again, if L0 needs to
      read page tables, e.g. to load PDPTRs, the memory can't be encrypted if
      L1 has any expectation of L0 doing the right thing.
      
      Cc: Tom Lendacky <thomas.lendacky@amd.com>
      Cc: Brijesh Singh <brijesh.singh@amd.com>
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Message-Id: <20210204000117.3303214-8-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      ca29e145
    • D
      KVM: x86/xen: Add event channel interrupt vector upcall · 40da8ccd
      David Woodhouse 提交于
      It turns out that we can't handle event channels *entirely* in userspace
      by delivering them as ExtINT, because KVM is a bit picky about when it
      accepts ExtINT interrupts from a legacy PIC. The in-kernel local APIC
      has to have LVT0 configured in APIC_MODE_EXTINT and unmasked, which
      isn't necessarily the case for Xen guests especially on secondary CPUs.
      
      To cope with this, add kvm_xen_get_interrupt() which checks the
      evtchn_pending_upcall field in the Xen vcpu_info, and delivers the Xen
      upcall vector (configured by KVM_XEN_ATTR_TYPE_UPCALL_VECTOR) if it's
      set regardless of LAPIC LVT0 configuration. This gives us the minimum
      support we need for completely userspace-based implementation of event
      channels.
      
      This does mean that vcpu_enter_guest() needs to check for the
      evtchn_pending_upcall flag being set, because it can't rely on someone
      having set KVM_REQ_EVENT unless we were to add some way for userspace to
      do so manually.
      Signed-off-by: NDavid Woodhouse <dwmw@amazon.co.uk>
      40da8ccd
    • J
      KVM: x86/xen: register vcpu time info region · f2340cd9
      Joao Martins 提交于
      Allow the Xen emulated guest the ability to register secondary
      vcpu time information. On Xen guests this is used in order to be
      mapped to userspace and hence allow vdso gettimeofday to work.
      Signed-off-by: NJoao Martins <joao.m.martins@oracle.com>
      Signed-off-by: NDavid Woodhouse <dwmw@amazon.co.uk>
      f2340cd9
    • J
      KVM: x86/xen: register vcpu info · 73e69a86
      Joao Martins 提交于
      The vcpu info supersedes the per vcpu area of the shared info page and
      the guest vcpus will use this instead.
      Signed-off-by: NJoao Martins <joao.m.martins@oracle.com>
      Signed-off-by: NAnkur Arora <ankur.a.arora@oracle.com>
      Signed-off-by: NDavid Woodhouse <dwmw@amazon.co.uk>
      73e69a86
    • J
      KVM: x86/xen: register shared_info page · 13ffb97a
      Joao Martins 提交于
      Add KVM_XEN_ATTR_TYPE_SHARED_INFO to allow hypervisor to know where the
      guest's shared info page is.
      Signed-off-by: NJoao Martins <joao.m.martins@oracle.com>
      Signed-off-by: NDavid Woodhouse <dwmw@amazon.co.uk>
      13ffb97a
    • D
      a3833b81
    • J
      KVM: x86/xen: intercept xen hypercalls if enabled · 23200b7a
      Joao Martins 提交于
      Add a new exit reason for emulator to handle Xen hypercalls.
      
      Since this means KVM owns the ABI, dispense with the facility for the
      VMM to provide its own copy of the hypercall pages; just fill them in
      directly using VMCALL/VMMCALL as we do for the Hyper-V hypercall page.
      
      This behaviour is enabled by a new INTERCEPT_HCALL flag in the
      KVM_XEN_HVM_CONFIG ioctl structure, and advertised by the same flag
      being returned from the KVM_CAP_XEN_HVM check.
      
      Rename xen_hvm_config() to kvm_xen_write_hypercall_page() and move it
      to the nascent xen.c while we're at it, and add a test case.
      Signed-off-by: NJoao Martins <joao.m.martins@oracle.com>
      Signed-off-by: NDavid Woodhouse <dwmw@amazon.co.uk>
      23200b7a
    • B
      KVM: x86/mmu: Use atomic ops to set SPTEs in TDP MMU map · 9a77daac
      Ben Gardon 提交于
      To prepare for handling page faults in parallel, change the TDP MMU
      page fault handler to use atomic operations to set SPTEs so that changes
      are not lost if multiple threads attempt to modify the same SPTE.
      Reviewed-by: NPeter Feiner <pfeiner@google.com>
      Signed-off-by: NBen Gardon <bgardon@google.com>
      
      Message-Id: <20210202185734.1680553-21-bgardon@google.com>
      [Document new locking rules. - Paolo]
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      9a77daac
    • B
      KVM: x86/mmu: Use an rwlock for the x86 MMU · 531810ca
      Ben Gardon 提交于
      Add a read / write lock to be used in place of the MMU spinlock on x86.
      The rwlock will enable the TDP MMU to handle page faults, and other
      operations in parallel in future commits.
      Reviewed-by: NPeter Feiner <pfeiner@google.com>
      Signed-off-by: NBen Gardon <bgardon@google.com>
      
      Message-Id: <20210202185734.1680553-19-bgardon@google.com>
      [Introduce virt/kvm/mmu_lock.h - Paolo]
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      531810ca
    • J
      KVM: x86: use static calls to reduce kvm_x86_ops overhead · b3646477
      Jason Baron 提交于
      Convert kvm_x86_ops to use static calls. Note that all kvm_x86_ops are
      covered here except for 'pmu_ops and 'nested ops'.
      
      Here are some numbers running cpuid in a loop of 1 million calls averaged
      over 5 runs, measured in the vm (lower is better).
      
      Intel Xeon 3000MHz:
      
                 |default    |mitigations=off
      -------------------------------------
      vanilla    |.671s      |.486s
      static call|.573s(-15%)|.458s(-6%)
      
      AMD EPYC 2500MHz:
      
                 |default    |mitigations=off
      -------------------------------------
      vanilla    |.710s      |.609s
      static call|.664s(-6%) |.609s(0%)
      
      Cc: Paolo Bonzini <pbonzini@redhat.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Ingo Molnar <mingo@redhat.com>
      Cc: Borislav Petkov <bp@alien8.de>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Andrea Arcangeli <aarcange@redhat.com>
      Cc: Sean Christopherson <seanjc@google.com>
      Signed-off-by: NJason Baron <jbaron@akamai.com>
      Message-Id: <e057bf1b8a7ad15652df6eeba3f907ae758d3399.1610680941.git.jbaron@akamai.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      b3646477
    • J
      KVM: x86: introduce definitions to support static calls for kvm_x86_ops · 9af5471b
      Jason Baron 提交于
      Use static calls to improve kvm_x86_ops performance. Introduce the
      definitions that will be used by a subsequent patch to actualize the
      savings. Add a new kvm-x86-ops.h header that can be used for the
      definition of static calls. This header is also intended to be
      used to simplify the defition of svm_kvm_ops and vmx_x86_ops.
      
      Note that all functions in kvm_x86_ops are covered here except for
      'pmu_ops' and 'nested ops'. I think they can be covered by static
      calls in a simlilar manner, but were omitted from this series to
      reduce scope and because I don't think they have as large of a
      performance impact.
      
      Cc: Paolo Bonzini <pbonzini@redhat.com>
      Cc: Sean Christopherson <seanjc@google.com>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Ingo Molnar <mingo@redhat.com>
      Cc: Borislav Petkov <bp@alien8.de>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Andrea Arcangeli <aarcange@redhat.com>
      Signed-off-by: NJason Baron <jbaron@akamai.com>
      Message-Id: <e5cc82ead7ab37b2dceb0837a514f3f8bea4f8d1.1610680941.git.jbaron@akamai.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      9af5471b
    • C
      KVM: X86: Rename DR6_INIT to DR6_ACTIVE_LOW · 9a3ecd5e
      Chenyi Qiang 提交于
      DR6_INIT contains the 1-reserved bits as well as the bit that is cleared
      to 0 when the condition (e.g. RTM) happens. The value can be used to
      initialize dr6 and also be the XOR mask between the #DB exit
      qualification (or payload) and DR6.
      
      Concerning that DR6_INIT is used as initial value only once, rename it
      to DR6_ACTIVE_LOW and apply it in other places, which would make the
      incoming changes for bus lock debug exception more simple.
      Signed-off-by: NChenyi Qiang <chenyi.qiang@intel.com>
      Message-Id: <20210202090433.13441-2-chenyi.qiang@intel.com>
      [Define DR6_FIXED_1 from DR6_ACTIVE_LOW and DR6_VOLATILE. - Paolo]
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      9a3ecd5e
    • C
      KVM: VMX: Enable bus lock VM exit · fe6b6bc8
      Chenyi Qiang 提交于
      Virtual Machine can exploit bus locks to degrade the performance of
      system. Bus lock can be caused by split locked access to writeback(WB)
      memory or by using locks on uncacheable(UC) memory. The bus lock is
      typically >1000 cycles slower than an atomic operation within a cache
      line. It also disrupts performance on other cores (which must wait for
      the bus lock to be released before their memory operations can
      complete).
      
      To address the threat, bus lock VM exit is introduced to notify the VMM
      when a bus lock was acquired, allowing it to enforce throttling or other
      policy based mitigations.
      
      A VMM can enable VM exit due to bus locks by setting a new "Bus Lock
      Detection" VM-execution control(bit 30 of Secondary Processor-based VM
      execution controls). If delivery of this VM exit was preempted by a
      higher priority VM exit (e.g. EPT misconfiguration, EPT violation, APIC
      access VM exit, APIC write VM exit, exception bitmap exiting), bit 26 of
      exit reason in vmcs field is set to 1.
      
      In current implementation, the KVM exposes this capability through
      KVM_CAP_X86_BUS_LOCK_EXIT. The user can get the supported mode bitmap
      (i.e. off and exit) and enable it explicitly (disabled by default). If
      bus locks in guest are detected by KVM, exit to user space even when
      current exit reason is handled by KVM internally. Set a new field
      KVM_RUN_BUS_LOCK in vcpu->run->flags to inform the user space that there
      is a bus lock detected in guest.
      
      Document for Bus Lock VM exit is now available at the latest "Intel
      Architecture Instruction Set Extensions Programming Reference".
      
      Document Link:
      https://software.intel.com/content/www/us/en/develop/download/intel-architecture-instruction-set-extensions-programming-reference.htmlCo-developed-by: NXiaoyao Li <xiaoyao.li@intel.com>
      Signed-off-by: NXiaoyao Li <xiaoyao.li@intel.com>
      Signed-off-by: NChenyi Qiang <chenyi.qiang@intel.com>
      Message-Id: <20201106090315.18606-4-chenyi.qiang@intel.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      fe6b6bc8
    • S
      KVM: x86/mmu: Remove the defunct update_pte() paging hook · c5e2184d
      Sean Christopherson 提交于
      Remove the update_pte() shadow paging logic, which was obsoleted by
      commit 4731d4c7 ("KVM: MMU: out of sync shadow core"), but never
      removed.  As pointed out by Yu, KVM never write protects leaf page
      tables for the purposes of shadow paging, and instead marks their
      associated shadow page as unsync so that the guest can write PTEs at
      will.
      
      The update_pte() path, which predates the unsync logic, optimizes COW
      scenarios by refreshing leaf SPTEs when they are written, as opposed to
      zapping the SPTE, restarting the guest, and installing the new SPTE on
      the subsequent fault.  Since KVM no longer write-protects leaf page
      tables, update_pte() is unreachable and can be dropped.
      Reported-by: NYu Zhang <yu.c.zhang@intel.com>
      Signed-off-by: NSean Christopherson <seanjc@google.com>
      Message-Id: <20210115004051.4099250-1-seanjc@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      c5e2184d
  8. 08 1月, 2021 2 次提交
    • T
      KVM: SVM: Add support for booting APs in an SEV-ES guest · 647daca2
      Tom Lendacky 提交于
      Typically under KVM, an AP is booted using the INIT-SIPI-SIPI sequence,
      where the guest vCPU register state is updated and then the vCPU is VMRUN
      to begin execution of the AP. For an SEV-ES guest, this won't work because
      the guest register state is encrypted.
      
      Following the GHCB specification, the hypervisor must not alter the guest
      register state, so KVM must track an AP/vCPU boot. Should the guest want
      to park the AP, it must use the AP Reset Hold exit event in place of, for
      example, a HLT loop.
      
      First AP boot (first INIT-SIPI-SIPI sequence):
        Execute the AP (vCPU) as it was initialized and measured by the SEV-ES
        support. It is up to the guest to transfer control of the AP to the
        proper location.
      
      Subsequent AP boot:
        KVM will expect to receive an AP Reset Hold exit event indicating that
        the vCPU is being parked and will require an INIT-SIPI-SIPI sequence to
        awaken it. When the AP Reset Hold exit event is received, KVM will place
        the vCPU into a simulated HLT mode. Upon receiving the INIT-SIPI-SIPI
        sequence, KVM will make the vCPU runnable. It is again up to the guest
        to then transfer control of the AP to the proper location.
      
        To differentiate between an actual HLT and an AP Reset Hold, a new MP
        state is introduced, KVM_MP_STATE_AP_RESET_HOLD, which the vCPU is
        placed in upon receiving the AP Reset Hold exit event. Additionally, to
        communicate the AP Reset Hold exit event up to userspace (if needed), a
        new exit reason is introduced, KVM_EXIT_AP_RESET_HOLD.
      
      A new x86 ops function is introduced, vcpu_deliver_sipi_vector, in order
      to accomplish AP booting. For VMX, vcpu_deliver_sipi_vector is set to the
      original SIPI delivery function, kvm_vcpu_deliver_sipi_vector(). SVM adds
      a new function that, for non SEV-ES guests, invokes the original SIPI
      delivery function, kvm_vcpu_deliver_sipi_vector(), but for SEV-ES guests,
      implements the logic above.
      Signed-off-by: NTom Lendacky <thomas.lendacky@amd.com>
      Message-Id: <e8fbebe8eb161ceaabdad7c01a5859a78b424d5e.1609791600.git.thomas.lendacky@amd.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      647daca2
    • B
      KVM: x86/mmu: Clarify TDP MMU page list invariants · c0dba6e4
      Ben Gardon 提交于
      The tdp_mmu_roots and tdp_mmu_pages in struct kvm_arch should only contain
      pages with tdp_mmu_page set to true. tdp_mmu_pages should not contain any
      pages with a non-zero root_count and tdp_mmu_roots should only contain
      pages with a positive root_count, unless a thread holds the MMU lock and
      is in the process of modifying the list. Various functions expect these
      invariants to be maintained, but they are not explictily documented. Add
      to the comments on both fields to document the above invariants.
      Signed-off-by: NBen Gardon <bgardon@google.com>
      Message-Id: <20210107001935.3732070-2-bgardon@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      c0dba6e4
  9. 15 12月, 2020 7 次提交
    • T
      KVM: SVM: Guest FPU state save/restore not needed for SEV-ES guest · ed02b213
      Tom Lendacky 提交于
      The guest FPU state is automatically restored on VMRUN and saved on VMEXIT
      by the hardware, so there is no reason to do this in KVM. Eliminate the
      allocation of the guest_fpu save area and key off that to skip operations
      related to the guest FPU state.
      Signed-off-by: NTom Lendacky <thomas.lendacky@amd.com>
      Message-Id: <173e429b4d0d962c6a443c4553ffdaf31b7665a4.1607620209.git.thomas.lendacky@amd.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      ed02b213
    • T
      KVM: SVM: Do not report support for SMM for an SEV-ES guest · 5719455f
      Tom Lendacky 提交于
      SEV-ES guests do not currently support SMM. Update the has_emulated_msr()
      kvm_x86_ops function to take a struct kvm parameter so that the capability
      can be reported at a VM level.
      
      Since this op is also called during KVM initialization and before a struct
      kvm instance is available, comments will be added to each implementation
      of has_emulated_msr() to indicate the kvm parameter can be null.
      Signed-off-by: NTom Lendacky <thomas.lendacky@amd.com>
      Message-Id: <75de5138e33b945d2fb17f81ae507bda381808e3.1607620209.git.thomas.lendacky@amd.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      5719455f
    • T
      KVM: SVM: Add support for CR4 write traps for an SEV-ES guest · 5b51cb13
      Tom Lendacky 提交于
      For SEV-ES guests, the interception of control register write access
      is not recommended. Control register interception occurs prior to the
      control register being modified and the hypervisor is unable to modify
      the control register itself because the register is located in the
      encrypted register state.
      
      SEV-ES guests introduce new control register write traps. These traps
      provide intercept support of a control register write after the control
      register has been modified. The new control register value is provided in
      the VMCB EXITINFO1 field, allowing the hypervisor to track the setting
      of the guest control registers.
      
      Add support to track the value of the guest CR4 register using the control
      register write trap so that the hypervisor understands the guest operating
      mode.
      Signed-off-by: NTom Lendacky <thomas.lendacky@amd.com>
      Message-Id: <c3880bf2db8693aa26f648528fbc6e967ab46e25.1607620209.git.thomas.lendacky@amd.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      5b51cb13
    • T
      KVM: SVM: Add support for CR0 write traps for an SEV-ES guest · f27ad38a
      Tom Lendacky 提交于
      For SEV-ES guests, the interception of control register write access
      is not recommended. Control register interception occurs prior to the
      control register being modified and the hypervisor is unable to modify
      the control register itself because the register is located in the
      encrypted register state.
      
      SEV-ES support introduces new control register write traps. These traps
      provide intercept support of a control register write after the control
      register has been modified. The new control register value is provided in
      the VMCB EXITINFO1 field, allowing the hypervisor to track the setting
      of the guest control registers.
      
      Add support to track the value of the guest CR0 register using the control
      register write trap so that the hypervisor understands the guest operating
      mode.
      Signed-off-by: NTom Lendacky <thomas.lendacky@amd.com>
      Message-Id: <182c9baf99df7e40ad9617ff90b84542705ef0d7.1607620209.git.thomas.lendacky@amd.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      f27ad38a
    • T
      KVM: SVM: Support string IO operations for an SEV-ES guest · 7ed9abfe
      Tom Lendacky 提交于
      For an SEV-ES guest, string-based port IO is performed to a shared
      (un-encrypted) page so that both the hypervisor and guest can read or
      write to it and each see the contents.
      
      For string-based port IO operations, invoke SEV-ES specific routines that
      can complete the operation using common KVM port IO support.
      Signed-off-by: NTom Lendacky <thomas.lendacky@amd.com>
      Message-Id: <9d61daf0ffda496703717218f415cdc8fd487100.1607620209.git.thomas.lendacky@amd.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      7ed9abfe
    • P
      KVM: x86: introduce complete_emulated_msr callback · f9a4d621
      Paolo Bonzini 提交于
      This will be used by SEV-ES to inject MSR failure via the GHCB.
      Reviewed-by: NTom Lendacky <thomas.lendacky@amd.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      f9a4d621
    • T
      KVM: SVM: Add support for the SEV-ES VMSA · add5e2f0
      Tom Lendacky 提交于
      Allocate a page during vCPU creation to be used as the encrypted VM save
      area (VMSA) for the SEV-ES guest. Provide a flag in the kvm_vcpu_arch
      structure that indicates whether the guest state is protected.
      
      When freeing a VMSA page that has been encrypted, the cache contents must
      be flushed using the MSR_AMD64_VM_PAGE_FLUSH before freeing the page.
      
      [ i386 build warnings ]
      Reported-by: Nkernel test robot <lkp@intel.com>
      Signed-off-by: NTom Lendacky <thomas.lendacky@amd.com>
      Message-Id: <fde272b17eec804f3b9db18c131262fe074015c5.1607620209.git.thomas.lendacky@amd.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      add5e2f0
  10. 27 11月, 2020 1 次提交
    • P
      KVM: x86: Fix split-irqchip vs interrupt injection window request · 71cc849b
      Paolo Bonzini 提交于
      kvm_cpu_accept_dm_intr and kvm_vcpu_ready_for_interrupt_injection are
      a hodge-podge of conditions, hacked together to get something that
      more or less works.  But what is actually needed is much simpler;
      in both cases the fundamental question is, do we have a place to stash
      an interrupt if userspace does KVM_INTERRUPT?
      
      In userspace irqchip mode, that is !vcpu->arch.interrupt.injected.
      Currently kvm_event_needs_reinjection(vcpu) covers it, but it is
      unnecessarily restrictive.
      
      In split irqchip mode it's a bit more complicated, we need to check
      kvm_apic_accept_pic_intr(vcpu) (the IRQ window exit is basically an INTACK
      cycle and thus requires ExtINTs not to be masked) as well as
      !pending_userspace_extint(vcpu).  However, there is no need to
      check kvm_event_needs_reinjection(vcpu), since split irqchip keeps
      pending ExtINT state separate from event injection state, and checking
      kvm_cpu_has_interrupt(vcpu) is wrong too since ExtINT has higher
      priority than APIC interrupts.  In fact the latter fixes a bug:
      when userspace requests an IRQ window vmexit, an interrupt in the
      local APIC can cause kvm_cpu_has_interrupt() to be true and thus
      kvm_vcpu_ready_for_interrupt_injection() to return false.  When this
      happens, vcpu_run does not exit to userspace but the interrupt window
      vmexits keep occurring.  The VM loops without any hope of making progress.
      
      Once we try to fix these with something like
      
           return kvm_arch_interrupt_allowed(vcpu) &&
      -        !kvm_cpu_has_interrupt(vcpu) &&
      -        !kvm_event_needs_reinjection(vcpu) &&
      -        kvm_cpu_accept_dm_intr(vcpu);
      +        (!lapic_in_kernel(vcpu)
      +         ? !vcpu->arch.interrupt.injected
      +         : (kvm_apic_accept_pic_intr(vcpu)
      +            && !pending_userspace_extint(v)));
      
      we realize two things.  First, thanks to the previous patch the complex
      conditional can reuse !kvm_cpu_has_extint(vcpu).  Second, the interrupt
      window request in vcpu_enter_guest()
      
              bool req_int_win =
                      dm_request_for_irq_injection(vcpu) &&
                      kvm_cpu_accept_dm_intr(vcpu);
      
      should be kept in sync with kvm_vcpu_ready_for_interrupt_injection():
      it is unnecessary to ask the processor for an interrupt window
      if we would not be able to return to userspace.  Therefore,
      kvm_cpu_accept_dm_intr(vcpu) is basically !kvm_cpu_has_extint(vcpu)
      ANDed with the existing check for masked ExtINT.  It all makes sense:
      
      - we can accept an interrupt from userspace if there is a place
        to stash it (and, for irqchip split, ExtINTs are not masked).
        Interrupts from userspace _can_ be accepted even if right now
        EFLAGS.IF=0.
      
      - in order to tell userspace we will inject its interrupt ("IRQ
        window open" i.e. kvm_vcpu_ready_for_interrupt_injection), both
        KVM and the vCPU need to be ready to accept the interrupt.
      
      ... and this is what the patch implements.
      Reported-by: NDavid Woodhouse <dwmw@amazon.co.uk>
      Analyzed-by: NDavid Woodhouse <dwmw@amazon.co.uk>
      Cc: stable@vger.kernel.org
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      Reviewed-by: NNikos Tsironis <ntsironis@arrikto.com>
      Reviewed-by: NDavid Woodhouse <dwmw@amazon.co.uk>
      Tested-by: NDavid Woodhouse <dwmw@amazon.co.uk>
      71cc849b