1. 07 5月, 2015 4 次提交
    • J
      kvm: x86: Extended struct kvm_lapic_irq with msi_redir_hint for MSI delivery · 93bbf0b8
      James Sullivan 提交于
      Extended struct kvm_lapic_irq with bool msi_redir_hint, which will
      be used to determine if the delivery of the MSI should target only
      the lowest priority CPU in the logical group specified for delivery.
      (In physical dest mode, the RH bit is not relevant). Initialized the value
      of msi_redir_hint to true when RH=1 in kvm_set_msi_irq(), and initialized
      to false in all other cases.
      
      Added value of msi_redir_hint to a debug message dump of an IRQ in
      apic_send_ipi().
      Signed-off-by: NJames Sullivan <sullivan.james.f@gmail.com>
      Reviewed-by: NRadim Krčmář <rkrcmar@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      93bbf0b8
    • P
      KVM: x86: tweak types of fields in kvm_lapic_irq · b7cb2231
      Paolo Bonzini 提交于
      Change to u16 if they only contain data in the low 16 bits.
      
      Change the level field to bool, since we assign 1 sometimes, but
      just mask icr_low with APIC_INT_ASSERT in apic_send_ipi.
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      b7cb2231
    • N
      KVM: x86: INIT and reset sequences are different · d28bc9dd
      Nadav Amit 提交于
      x86 architecture defines differences between the reset and INIT sequences.
      INIT does not initialize the FPU (including MMX, XMM, YMM, etc.), TSC, PMU,
      MSRs (in general), MTRRs machine-check, APIC ID, APIC arbitration ID and BSP.
      
      References (from Intel SDM):
      
      "If the MP protocol has completed and a BSP is chosen, subsequent INITs (either
      to a specific processor or system wide) do not cause the MP protocol to be
      repeated." [8.4.2: MP Initialization Protocol Requirements and Restrictions]
      
      [Table 9-1. IA-32 Processor States Following Power-up, Reset, or INIT]
      
      "If the processor is reset by asserting the INIT# pin, the x87 FPU state is not
      changed." [9.2: X87 FPU INITIALIZATION]
      
      "The state of the local APIC following an INIT reset is the same as it is after
      a power-up or hardware reset, except that the APIC ID and arbitration ID
      registers are not affected." [10.4.7.3: Local APIC State After an INIT Reset
      ("Wait-for-SIPI" State)]
      Signed-off-by: NNadav Amit <namit@cs.technion.ac.il>
      Message-Id: <1428924848-28212-1-git-send-email-namit@cs.technion.ac.il>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      d28bc9dd
    • N
      KVM: x86: Support for disabling quirks · 90de4a18
      Nadav Amit 提交于
      Introducing KVM_CAP_DISABLE_QUIRKS for disabling x86 quirks that were previous
      created in order to overcome QEMU issues. Those issue were mostly result of
      invalid VM BIOS.  Currently there are two quirks that can be disabled:
      
      1. KVM_QUIRK_LINT0_REENABLED - LINT0 was enabled after boot
      2. KVM_QUIRK_CD_NW_CLEARED - CD and NW are cleared after boot
      
      These two issues are already resolved in recent releases of QEMU, and would
      therefore be disabled by QEMU.
      Signed-off-by: NNadav Amit <namit@cs.technion.ac.il>
      Message-Id: <1428879221-29996-1-git-send-email-namit@cs.technion.ac.il>
      [Report capability from KVM_CHECK_EXTENSION too. - Paolo]
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      90de4a18
  2. 15 4月, 2015 1 次提交
    • P
      KVM: x86: cleanup kvm_irq_delivery_to_apic_fast · bea15428
      Paolo Bonzini 提交于
      Sparse is reporting a "we previously assumed 'src' could be null" error.
      This is true as far as the static analyzer can see, but in practice only
      IPIs can set shorthand to self and they also set 'src', so it's ok.
      Still, move the initialization of x2apic_ipi (and thus the NULL check for
      src right before the first use.
      
      While at it, initializing ret to "false" is somewhat confusing because of
      the almost immediate assigned of "true" to the same variable.  Thus,
      initialize it to "true" and modify it in the only path that used to use
      the value from "bool ret = false".  There is no change in generated code
      from this change.
      Reported-by: NDan Carpenter <dan.carpenter@oracle.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      bea15428
  3. 08 4月, 2015 5 次提交
    • N
      KVM: x86: BSP in MSR_IA32_APICBASE is writable · 58d269d8
      Nadav Amit 提交于
      After reset, the CPU can change the BSP, which will be used upon INIT.  Reset
      should return the BSP which QEMU asked for, and therefore handled accordingly.
      
      To quote: "If the MP protocol has completed and a BSP is chosen, subsequent
      INITs (either to a specific processor or system wide) do not cause the MP
      protocol to be repeated."
      [Intel SDM 8.4.2: MP Initialization Protocol Requirements and Restrictions]
      Signed-off-by: NNadav Amit <namit@cs.technion.ac.il>
      Message-Id: <1427933438-12782-3-git-send-email-namit@cs.technion.ac.il>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      58d269d8
    • R
      KVM: x86: simplify kvm_apic_map · 3b5a5ffa
      Radim Krčmář 提交于
      recalculate_apic_map() uses two passes over all VCPUs.  This is a relic
      from time when we selected a global mode in the first pass and set up
      the optimized table in the second pass (to have a consistent mode).
      
      Recent changes made mixed mode unoptimized and we can do it in one pass.
      Format of logical MDA is a function of the mode, so we encode it in
      apic_logical_id() and drop obsoleted variables from the struct.
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      Message-Id: <1423766494-26150-5-git-send-email-rkrcmar@redhat.com>
      [Add lid_bits temporary in apic_logical_id. - Paolo]
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      3b5a5ffa
    • R
      KVM: x86: avoid logical_map when it is invalid · 3548a259
      Radim Krčmář 提交于
      We want to support mixed modes and the easiest solution is to avoid
      optimizing those weird and unlikely scenarios.
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      Message-Id: <1423766494-26150-4-git-send-email-rkrcmar@redhat.com>
      [Add comment above KVM_APIC_MODE_* defines. - Paolo]
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      3548a259
    • R
      KVM: x86: fix mixed APIC mode broadcast · 9ea369b0
      Radim Krčmář 提交于
      Broadcast allowed only one global APIC mode, but mixed modes are
      theoretically possible.  x2APIC IPI doesn't mean 0xff as broadcast,
      the rest does.
      
      x2APIC broadcasts are accepted by xAPIC.  If we take SDM to be logical,
      even addreses beginning with 0xff should be accepted, but real hardware
      disagrees.  This patch aims for simple code by considering most of real
      behavior as undefined.
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      Message-Id: <1423766494-26150-3-git-send-email-rkrcmar@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      9ea369b0
    • R
      KVM: x86: use MDA for interrupt matching · 03d2249e
      Radim Krčmář 提交于
      In mixed modes, we musn't deliver xAPIC IPIs like x2APIC and vice versa.
      Instead of preserving the information in apic_send_ipi(), we regain it
      by converting all destinations into correct MDA in the slow path.
      This allows easier reasoning about subsequent matching.
      
      Our kvm_apic_broadcast() had an interesting design decision: it didn't
      consider IOxAPIC 0xff as broadcast in x2APIC mode ...
      everything worked because IOxAPIC can't set that in physical mode and
      logical mode considered it as a message for first 8 VCPUs.
      This patch interprets IOxAPIC 0xff as x2APIC broadcast.
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      Message-Id: <1423766494-26150-2-git-send-email-rkrcmar@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      03d2249e
  4. 27 3月, 2015 1 次提交
  5. 24 3月, 2015 1 次提交
  6. 03 3月, 2015 1 次提交
    • R
      KVM: SVM: fix interrupt injection (apic->isr_count always 0) · f563db4b
      Radim Krčmář 提交于
      In commit b4eef9b3, we started to use hwapic_isr_update() != NULL
      instead of kvm_apic_vid_enabled(vcpu->kvm).  This didn't work because
      SVM had it defined and "apicv" path in apic_{set,clear}_isr() does not
      change apic->isr_count, because it should always be 1.  The initial
      value of apic->isr_count was based on kvm_apic_vid_enabled(vcpu->kvm),
      which is always 0 for SVM, so KVM could have injected interrupts when it
      shouldn't.
      
      Fix it by implicitly setting SVM's hwapic_isr_update to NULL and make the
      initial isr_count depend on hwapic_isr_update() for good measure.
      
      Fixes: b4eef9b3 ("kvm: x86: vmx: NULL out hwapic_isr_update() in case of !enable_apicv")
      Reported-and-tested-by: NBorislav Petkov <bp@suse.de>
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      Signed-off-by: NMarcelo Tosatti <mtosatti@redhat.com>
      f563db4b
  7. 04 2月, 2015 1 次提交
    • W
      KVM: nVMX: Enable nested posted interrupt processing · 705699a1
      Wincy Van 提交于
      If vcpu has a interrupt in vmx non-root mode, injecting that interrupt
      requires a vmexit.  With posted interrupt processing, the vmexit
      is not needed, and interrupts are fully taken care of by hardware.
      In nested vmx, this feature avoids much more vmexits than non-nested vmx.
      
      When L1 asks L0 to deliver L1's posted interrupt vector, and the target
      VCPU is in non-root mode, we use a physical ipi to deliver POSTED_INTR_NV
      to the target vCPU.  Using POSTED_INTR_NV avoids unexpected interrupts
      if a concurrent vmexit happens and L1's vector is different with L0's.
      The IPI triggers posted interrupt processing in the target physical CPU.
      
      In case the target vCPU was not in guest mode, complete the posted
      interrupt delivery on the next entry to L2.
      Signed-off-by: NWincy Van <fanwenyi0529@gmail.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      705699a1
  8. 03 2月, 2015 1 次提交
  9. 30 1月, 2015 5 次提交
  10. 09 1月, 2015 4 次提交
  11. 04 12月, 2014 7 次提交
  12. 24 11月, 2014 1 次提交
  13. 17 11月, 2014 3 次提交
    • N
      KVM: x86: Fix lost interrupt on irr_pending race · f210f757
      Nadav Amit 提交于
      apic_find_highest_irr assumes irr_pending is set if any vector in APIC_IRR is
      set.  If this assumption is broken and apicv is disabled, the injection of
      interrupts may be deferred until another interrupt is delivered to the guest.
      Ultimately, if no other interrupt should be injected to that vCPU, the pending
      interrupt may be lost.
      
      commit 56cc2406 ("KVM: nVMX: fix "acknowledge interrupt on exit" when APICv
      is in use") changed the behavior of apic_clear_irr so irr_pending is cleared
      after setting APIC_IRR vector. After this commit, if apic_set_irr and
      apic_clear_irr run simultaneously, a race may occur, resulting in APIC_IRR
      vector set, and irr_pending cleared. In the following example, assume a single
      vector is set in IRR prior to calling apic_clear_irr:
      
      apic_set_irr				apic_clear_irr
      ------------				--------------
      apic->irr_pending = true;
      					apic_clear_vector(...);
      					vec = apic_search_irr(apic);
      					// => vec == -1
      apic_set_vector(...);
      					apic->irr_pending = (vec != -1);
      					// => apic->irr_pending == false
      
      Nonetheless, it appears the race might even occur prior to this commit:
      
      apic_set_irr				apic_clear_irr
      ------------				--------------
      apic->irr_pending = true;
      					apic->irr_pending = false;
      					apic_clear_vector(...);
      					if (apic_search_irr(apic) != -1)
      						apic->irr_pending = true;
      					// => apic->irr_pending == false
      apic_set_vector(...);
      
      Fixing this issue by:
      1. Restoring the previous behavior of apic_clear_irr: clear irr_pending, call
         apic_clear_vector, and then if APIC_IRR is non-zero, set irr_pending.
      2. On apic_set_irr: first call apic_set_vector, then set irr_pending.
      Signed-off-by: NNadav Amit <namit@cs.technion.ac.il>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      f210f757
    • P
      KVM: compute correct map even if all APICs are software disabled · a3e339e1
      Paolo Bonzini 提交于
      Logical destination mode can be used to send NMI IPIs even when all
      APICs are software disabled, so if all APICs are software disabled we
      should still look at the DFRs.
      
      So the DFRs should all be the same, even if some or all APICs are
      software disabled.  However, the SDM does not say this, so tweak
      the logic as follows:
      
      - if one APIC is enabled and has LDR != 0, use that one to build the map.
      This picks the right DFR in case an OS is only setting it for the
      software-enabled APICs, or in case an OS is using logical addressing
      on some APICs while leaving the rest in reset state (using LDR was
      suggested by Radim).
      
      - if all APICs are disabled, pick a random one to build the map.
      We use the last one with LDR != 0 for simplicity.
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      a3e339e1
    • N
      KVM: x86: Software disabled APIC should still deliver NMIs · 173beedc
      Nadav Amit 提交于
      Currently, the APIC logical map does not consider VCPUs whose local-apic is
      software-disabled.  However, NMIs, INIT, etc. should still be delivered to such
      VCPUs. Therefore, the APIC mode should first be determined, and then the map,
      considering all VCPUs should be constructed.
      
      To address this issue, first find the APIC mode, and only then construct the
      logical map.
      Signed-off-by: NNadav Amit <namit@cs.technion.ac.il>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      173beedc
  14. 08 11月, 2014 1 次提交
  15. 07 11月, 2014 1 次提交
  16. 03 11月, 2014 3 次提交
    • R
      KVM: x86: optimize some accesses to LVTT and SPIV · f30ebc31
      Radim Krčmář 提交于
      We mirror a subset of these registers in separate variables.
      Using them directly should be faster.
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      f30ebc31
    • R
      KVM: x86: detect LVTT changes under APICv · a323b409
      Radim Krčmář 提交于
      APIC-write VM exits are "trap-like": they save CS:RIP values for the
      instruction after the write, and more importantly, the handler will
      already see the new value in the virtual-APIC page.  This means that
      apic_reg_write cannot use kvm_apic_get_reg to omit timer cancelation
      when mode changes.
      
      timer_mode_mask shouldn't be changing as it depends on cpuid.
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      a323b409
    • R
      KVM: x86: detect SPIV changes under APICv · e462755c
      Radim Krčmář 提交于
      APIC-write VM exits are "trap-like": they save CS:RIP values for the
      instruction after the write, and more importantly, the handler will
      already see the new value in the virtual-APIC page.
      
      This caused a bug if you used KVM_SET_IRQCHIP to set the SW-enabled bit
      in the SPIV register.  The chain of events is as follows:
      
      * When the irqchip is added to the destination VM, the apic_sw_disabled
      static key is incremented (1)
      
      * When the KVM_SET_IRQCHIP ioctl is invoked, it is decremented (0)
      
      * When the guest disables the bit in the SPIV register, e.g. as part of
      shutdown, apic_set_spiv does not notice the change and the static key is
      _not_ incremented.
      
      * When the guest is destroyed, the static key is decremented (-1),
      resulting in this trace:
      
        WARNING: at kernel/jump_label.c:81 __static_key_slow_dec+0xa6/0xb0()
        jump label: negative count!
      
        [<ffffffff816bf898>] dump_stack+0x19/0x1b
        [<ffffffff8107c6f1>] warn_slowpath_common+0x61/0x80
        [<ffffffff8107c76c>] warn_slowpath_fmt+0x5c/0x80
        [<ffffffff811931e6>] __static_key_slow_dec+0xa6/0xb0
        [<ffffffff81193226>] static_key_slow_dec_deferred+0x16/0x20
        [<ffffffffa0637698>] kvm_free_lapic+0x88/0xa0 [kvm]
        [<ffffffffa061c63e>] kvm_arch_vcpu_uninit+0x2e/0xe0 [kvm]
        [<ffffffffa05ff301>] kvm_vcpu_uninit+0x21/0x40 [kvm]
        [<ffffffffa067cec7>] vmx_free_vcpu+0x47/0x70 [kvm_intel]
        [<ffffffffa061bc50>] kvm_arch_vcpu_free+0x50/0x60 [kvm]
        [<ffffffffa061ca22>] kvm_arch_destroy_vm+0x102/0x260 [kvm]
        [<ffffffff810b68fd>] ? synchronize_srcu+0x1d/0x20
        [<ffffffffa06030d1>] kvm_put_kvm+0xe1/0x1c0 [kvm]
        [<ffffffffa06036f8>] kvm_vcpu_release+0x18/0x20 [kvm]
        [<ffffffff81215c62>] __fput+0x102/0x310
        [<ffffffff81215f4e>] ____fput+0xe/0x10
        [<ffffffff810ab664>] task_work_run+0xb4/0xe0
        [<ffffffff81083944>] do_exit+0x304/0xc60
        [<ffffffff816c8dfc>] ? _raw_spin_unlock_irq+0x2c/0x50
        [<ffffffff810fd22d>] ?  trace_hardirqs_on_caller+0xfd/0x1c0
        [<ffffffff8108432c>] do_group_exit+0x4c/0xc0
        [<ffffffff810843b4>] SyS_exit_group+0x14/0x20
        [<ffffffff816d33a9>] system_call_fastpath+0x16/0x1b
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      e462755c