1. 27 4月, 2017 1 次提交
  2. 21 4月, 2017 2 次提交
    • M
      kvm: better MWAIT emulation for guests · 668fffa3
      Michael S. Tsirkin 提交于
      Guests that are heavy on futexes end up IPI'ing each other a lot. That
      can lead to significant slowdowns and latency increase for those guests
      when running within KVM.
      
      If only a single guest is needed on a host, we have a lot of spare host
      CPU time we can throw at the problem. Modern CPUs implement a feature
      called "MWAIT" which allows guests to wake up sleeping remote CPUs without
      an IPI - thus without an exit - at the expense of never going out of guest
      context.
      
      The decision whether this is something sensible to use should be up to the
      VM admin, so to user space. We can however allow MWAIT execution on systems
      that support it properly hardware wise.
      
      This patch adds a CAP to user space and a KVM cpuid leaf to indicate
      availability of native MWAIT execution. With that enabled, the worst a
      guest can do is waste as many cycles as a "jmp ." would do, so it's not
      a privilege problem.
      
      We consciously do *not* expose the feature in our CPUID bitmap, as most
      people will want to benefit from sleeping vCPUs to allow for over commit.
      Reported-by: N"Gabriel L. Somlo" <gsomlo@gmail.com>
      Signed-off-by: NMichael S. Tsirkin <mst@redhat.com>
      [agraf: fix amd, change commit message]
      Signed-off-by: NAlexander Graf <agraf@suse.de>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      668fffa3
    • D
      KVM: VMX: drop vmm_exclusive module parameter · fe0e80be
      David Hildenbrand 提交于
      vmm_exclusive=0 leads to KVM setting X86_CR4_VMXE always and calling
      VMXON only when the vcpu is loaded. X86_CR4_VMXE is used as an
      indication in cpu_emergency_vmxoff() (called on kdump) if VMXOFF has to be
      called. This is obviously not the case if both are used independtly.
      Calling VMXOFF without a previous VMXON will result in an exception.
      
      In addition, X86_CR4_VMXE is used as a mean to test if VMX is already in
      use by another VMM in hardware_enable(). So there can't really be
      co-existance. If the other VMM is prepared for co-existance and does a
      similar check, only one VMM can exist. If the other VMM is not prepared
      and blindly sets/clears X86_CR4_VMXE, we will get inconsistencies with
      X86_CR4_VMXE.
      
      As we also had bug reports related to clearing of vmcs with vmm_exclusive=0
      this seems to be pretty much untested. So let's better drop it.
      
      While at it, directly move setting/clearing X86_CR4_VMXE into
      kvm_cpu_vmxon/off.
      Signed-off-by: NDavid Hildenbrand <david@redhat.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      fe0e80be
  3. 14 4月, 2017 1 次提交
    • R
      KVM: nVMX: fix AD condition when handling EPT violation · 33251870
      Radim Krčmář 提交于
      I have introduced this bug when applying and simplifying Paolo's patch
      as we agreed on the list.  The original was "x &= ~y; if (z) x |= y;".
      
      Here is the story of a bad workflow:
      
        A maintainer was already testing with the intended change, but it was
        applied only to a testing repo on a different machine.  When the time
        to push tested patches to kvm/next came, he realized that this change
        was missing and quickly added it to the maintenance repo, didn't test
        again (because the change is trivial, right), and pushed the world to
        fire.
      
      Fixes: ae1e2d10 ("kvm: nVMX: support EPT accessed/dirty bits")
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      33251870
  4. 07 4月, 2017 7 次提交
  5. 28 3月, 2017 1 次提交
  6. 24 3月, 2017 3 次提交
    • W
      KVM: VMX: Fix enable VPID conditions · 08d839c4
      Wanpeng Li 提交于
      This can be reproduced by running L2 on L1, and disable VPID on L0
      if w/o commit "KVM: nVMX: Fix nested VPID vmx exec control", the L2
      crash as below:
      
      KVM: entry failed, hardware error 0x7
      EAX=00000000 EBX=00000000 ECX=00000000 EDX=000306c3
      ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
      EIP=0000fff0 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
      ES =0000 00000000 0000ffff 00009300
      CS =f000 ffff0000 0000ffff 00009b00
      SS =0000 00000000 0000ffff 00009300
      DS =0000 00000000 0000ffff 00009300
      FS =0000 00000000 0000ffff 00009300
      GS =0000 00000000 0000ffff 00009300
      LDT=0000 00000000 0000ffff 00008200
      TR =0000 00000000 0000ffff 00008b00
      GDT=     00000000 0000ffff
      IDT=     00000000 0000ffff
      CR0=60000010 CR2=00000000 CR3=00000000 CR4=00000000
      DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
      DR6=00000000ffff0ff0 DR7=0000000000000400
      EFER=0000000000000000
      
      Reference SDM 30.3 INVVPID:
      
      Protected Mode Exceptions
      - #UD
        - If not in VMX operation.
        - If the logical processor does not support VPIDs (IA32_VMX_PROCBASED_CTLS2[37]=0).
        - If the logical processor supports VPIDs (IA32_VMX_PROCBASED_CTLS2[37]=1) but does
          not support the INVVPID instruction (IA32_VMX_EPT_VPID_CAP[32]=0).
      
      So we should check both VPID enable bit in vmx exec control and INVVPID support bit
      in vmx capability MSRs to enable VPID. This patch adds the guarantee to not enable
      VPID if either INVVPID or single-context/all-context invalidation is not exposed in
      vmx capability MSRs.
      Reviewed-by: NDavid Hildenbrand <david@redhat.com>
      Reviewed-by: NJim Mattson <jmattson@google.com>
      Cc: Paolo Bonzini <pbonzini@redhat.com>
      Cc: Radim Krčmář <rkrcmar@redhat.com>
      Signed-off-by: NWanpeng Li <wanpeng.li@hotmail.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      08d839c4
    • W
      KVM: nVMX: Fix nested VPID vmx exec control · 63cb6d5f
      Wanpeng Li 提交于
      This can be reproduced by running kvm-unit-tests/vmx.flat on L0 w/ vpid disabled.
      
      Test suite: VPID
      Unhandled exception 6 #UD at ip 00000000004051a6
      error_code=0000      rflags=00010047      cs=00000008
      rax=0000000000000000 rcx=0000000000000001 rdx=0000000000000047 rbx=0000000000402f79
      rbp=0000000000456240 rsi=0000000000000001 rdi=0000000000000000
      r8=000000000000000a  r9=00000000000003f8 r10=0000000080010011 r11=0000000000000000
      r12=0000000000000003 r13=0000000000000708 r14=0000000000000000 r15=0000000000000000
      cr0=0000000080010031 cr2=0000000000000000 cr3=0000000007fff000 cr4=0000000000002020
      cr8=0000000000000000
      STACK: @4051a6 40523e 400f7f 402059 40028f
      
      We should hide and forbid VPID in L1 if it is disabled on L0. However, nested VPID
      enable bit is set unconditionally during setup nested vmx exec controls though VPID
      is not exposed through nested VMX capablity. This patch fixes it by don't set nested
      VPID enable bit if it is disabled on L0.
      
      Cc: Paolo Bonzini <pbonzini@redhat.com>
      Cc: Radim Krčmář <rkrcmar@redhat.com>
      Cc: stable@vger.kernel.org
      Fixes: 5c614b35 (KVM: nVMX: nested VPID emulation)
      Signed-off-by: NWanpeng Li <wanpeng.li@hotmail.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      63cb6d5f
    • J
      kvm: vmx: Flush TLB when the APIC-access address changes · fb6c8198
      Jim Mattson 提交于
      Quoting from the Intel SDM, volume 3, section 28.3.3.4: Guidelines for
      Use of the INVEPT Instruction:
      
      If EPT was in use on a logical processor at one time with EPTP X, it
      is recommended that software use the INVEPT instruction with the
      "single-context" INVEPT type and with EPTP X in the INVEPT descriptor
      before a VM entry on the same logical processor that enables EPT with
      EPTP X and either (a) the "virtualize APIC accesses" VM-execution
      control was changed from 0 to 1; or (b) the value of the APIC-access
      address was changed.
      
      In the nested case, the burden falls on L1, unless L0 enables EPT in
      vmcs02 when L1 doesn't enable EPT in vmcs12.
      Signed-off-by: NJim Mattson <jmattson@google.com>
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      fb6c8198
  7. 20 3月, 2017 2 次提交
  8. 09 3月, 2017 1 次提交
    • R
      KVM: nVMX: do not warn when MSR bitmap address is not backed · 05d8d346
      Radim Krčmář 提交于
      Before trying to do nested_get_page() in nested_vmx_merge_msr_bitmap(),
      we have already checked that the MSR bitmap address is valid (4k aligned
      and within physical limits).  SDM doesn't specify what happens if the
      there is no memory mapped at the valid address, but Intel CPUs treat the
      situation as if the bitmap was configured to trap all MSRs.
      
      KVM already does that by returning false and a correct handling doesn't
      need the guest-trigerrable warning that was reported by syzkaller:
      (The warning was originally there to catch some possible bugs in nVMX.)
      
        ------------[ cut here ]------------
        WARNING: CPU: 0 PID: 7832 at arch/x86/kvm/vmx.c:9709
        nested_vmx_merge_msr_bitmap arch/x86/kvm/vmx.c:9709 [inline]
        WARNING: CPU: 0 PID: 7832 at arch/x86/kvm/vmx.c:9709
        nested_get_vmcs12_pages+0xfb6/0x15c0 arch/x86/kvm/vmx.c:9640
        Kernel panic - not syncing: panic_on_warn set ...
        CPU: 0 PID: 7832 Comm: syz-executor1 Not tainted 4.10.0+ #229
        Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
        Call Trace:
         __dump_stack lib/dump_stack.c:15 [inline]
         dump_stack+0x2ee/0x3ef lib/dump_stack.c:51
         panic+0x1fb/0x412 kernel/panic.c:179
         __warn+0x1c4/0x1e0 kernel/panic.c:540
         warn_slowpath_null+0x2c/0x40 kernel/panic.c:583
         nested_vmx_merge_msr_bitmap arch/x86/kvm/vmx.c:9709 [inline]
         nested_get_vmcs12_pages+0xfb6/0x15c0 arch/x86/kvm/vmx.c:9640
         enter_vmx_non_root_mode arch/x86/kvm/vmx.c:10471 [inline]
         nested_vmx_run+0x6186/0xaab0 arch/x86/kvm/vmx.c:10561
         handle_vmlaunch+0x1a/0x20 arch/x86/kvm/vmx.c:7312
         vmx_handle_exit+0xfc0/0x3f00 arch/x86/kvm/vmx.c:8526
         vcpu_enter_guest arch/x86/kvm/x86.c:6982 [inline]
         vcpu_run arch/x86/kvm/x86.c:7044 [inline]
         kvm_arch_vcpu_ioctl_run+0x1418/0x4840 arch/x86/kvm/x86.c:7205
         kvm_vcpu_ioctl+0x673/0x1120 arch/x86/kvm/../../../virt/kvm/kvm_main.c:2570
      Reported-by: NDmitry Vyukov <dvyukov@google.com>
      Reviewed-by: NJim Mattson <jmattson@google.com>
      [Jim Mattson explained the bare metal behavior: "I believe this behavior
       would be documented in the chipset data sheet rather than the SDM,
       since the chipset returns all 1s for an unclaimed read."]
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      05d8d346
  9. 07 3月, 2017 2 次提交
    • W
      KVM: nVMX: reset nested_run_pending if the vCPU is going to be reset · 2f707d97
      Wanpeng Li 提交于
      Reported by syzkaller:
      
          WARNING: CPU: 1 PID: 27742 at arch/x86/kvm/vmx.c:11029
          nested_vmx_vmexit+0x5c35/0x74d0 arch/x86/kvm/vmx.c:11029
          CPU: 1 PID: 27742 Comm: a.out Not tainted 4.10.0+ #229
          Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
          Call Trace:
           __dump_stack lib/dump_stack.c:15 [inline]
           dump_stack+0x2ee/0x3ef lib/dump_stack.c:51
           panic+0x1fb/0x412 kernel/panic.c:179
           __warn+0x1c4/0x1e0 kernel/panic.c:540
           warn_slowpath_null+0x2c/0x40 kernel/panic.c:583
           nested_vmx_vmexit+0x5c35/0x74d0 arch/x86/kvm/vmx.c:11029
           vmx_leave_nested arch/x86/kvm/vmx.c:11136 [inline]
           vmx_set_msr+0x1565/0x1910 arch/x86/kvm/vmx.c:3324
           kvm_set_msr+0xd4/0x170 arch/x86/kvm/x86.c:1099
           do_set_msr+0x11e/0x190 arch/x86/kvm/x86.c:1128
           __msr_io arch/x86/kvm/x86.c:2577 [inline]
           msr_io+0x24b/0x450 arch/x86/kvm/x86.c:2614
           kvm_arch_vcpu_ioctl+0x35b/0x46a0 arch/x86/kvm/x86.c:3497
           kvm_vcpu_ioctl+0x232/0x1120 arch/x86/kvm/../../../virt/kvm/kvm_main.c:2721
           vfs_ioctl fs/ioctl.c:43 [inline]
           do_vfs_ioctl+0x1bf/0x1790 fs/ioctl.c:683
           SYSC_ioctl fs/ioctl.c:698 [inline]
           SyS_ioctl+0x8f/0xc0 fs/ioctl.c:689
           entry_SYSCALL_64_fastpath+0x1f/0xc2
      
      The syzkaller folks reported a nested_run_pending warning during userspace
      clear VMX capability which is exposed to L1 before.
      
      The warning gets thrown while doing
      
      (*(uint32_t*)0x20aecfe8 = (uint32_t)0x1);
      (*(uint32_t*)0x20aecfec = (uint32_t)0x0);
      (*(uint32_t*)0x20aecff0 = (uint32_t)0x3a);
      (*(uint32_t*)0x20aecff4 = (uint32_t)0x0);
      (*(uint64_t*)0x20aecff8 = (uint64_t)0x0);
      r[29] = syscall(__NR_ioctl, r[4], 0x4008ae89ul,
      		0x20aecfe8ul, 0, 0, 0, 0, 0, 0);
      
      i.e. KVM_SET_MSR ioctl with
      
      struct kvm_msrs {
      	.nmsrs = 1,
      		.pad = 0,
      		.entries = {
      			{.index = MSR_IA32_FEATURE_CONTROL,
      			 .reserved = 0,
      			 .data = 0}
      		}
      }
      
      The VMLANCH/VMRESUME emulation should be stopped since the CPU is going to
      reset here. This patch resets the nested_run_pending since the CPU is going
      to be reset hence there should be nothing pending.
      Reported-by: NDmitry Vyukov <dvyukov@google.com>
      Suggested-by: NRadim Krčmář <rkrcmar@redhat.com>
      Cc: Paolo Bonzini <pbonzini@redhat.com>
      Cc: Radim Krčmář <rkrcmar@redhat.com>
      Cc: Dmitry Vyukov <dvyukov@google.com>
      Cc: David Hildenbrand <david@redhat.com>
      Signed-off-by: NWanpeng Li <wanpeng.li@hotmail.com>
      Reviewed-by: NDavid Hildenbrand <david@redhat.com>
      Reviewed-by: NJim Mattson <jmattson@google.com>
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      2f707d97
    • J
      kvm: nVMX: VMCLEAR should not cause the vCPU to shut down · 587d7e72
      Jim Mattson 提交于
      VMCLEAR should silently ignore a failure to clear the launch state of
      the VMCS referenced by the operand.
      Signed-off-by: NJim Mattson <jmattson@google.com>
      [Changed "kvm_write_guest(vcpu->kvm" to "kvm_vcpu_write_guest(vcpu".]
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      587d7e72
  10. 02 3月, 2017 2 次提交
    • W
      KVM: nVMX: Fix pending events injection · acc9ab60
      Wanpeng Li 提交于
      L2 fails to boot on a non-APICv box dues to 'commit 0ad3bed6
      ("kvm: nVMX: move nested events check to kvm_vcpu_running")'
      
      KVM internal error. Suberror: 3
      extra data[0]: 800000ef
      extra data[1]: 1
      RAX=0000000000000000 RBX=ffffffff81f36140 RCX=0000000000000000 RDX=0000000000000000
      RSI=0000000000000000 RDI=0000000000000000 RBP=ffff88007c92fe90 RSP=ffff88007c92fe90
      R8 =ffff88007fccdca0 R9 =0000000000000000 R10=00000000fffedb3d R11=0000000000000000
      R12=0000000000000003 R13=0000000000000000 R14=0000000000000000 R15=ffff88007c92c000
      RIP=ffffffff810645e6 RFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
      ES =0000 0000000000000000 ffffffff 00c00000
      CS =0010 0000000000000000 ffffffff 00a09b00 DPL=0 CS64 [-RA]
      SS =0000 0000000000000000 ffffffff 00c00000
      DS =0000 0000000000000000 ffffffff 00c00000
      FS =0000 0000000000000000 ffffffff 00c00000
      GS =0000 ffff88007fcc0000 ffffffff 00c00000
      LDT=0000 0000000000000000 ffffffff 00c00000
      TR =0040 ffff88007fcd4200 00002087 00008b00 DPL=0 TSS64-busy
      GDT=     ffff88007fcc9000 0000007f
      IDT=     ffffffffff578000 00000fff
      CR0=80050033 CR2=00000000ffffffff CR3=0000000001e0a000 CR4=003406e0
      DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
      DR6=00000000fffe0ff0 DR7=0000000000000400
      EFER=0000000000000d01
      
      We should try to reinject previous events if any before trying to inject
      new event if pending. If vmexit is triggered by L2 guest and L0 interested
      in, we should reinject IDT-vectoring info to L2 through vmcs02 if any,
      otherwise, we can consider new IRQs/NMIs which can be injected and call
      nested events callback to switch from L2 to L1 if needed and inject the
      proper vmexit events. However, 'commit 0ad3bed6 ("kvm: nVMX: move
      nested events check to kvm_vcpu_running")' results in the handle events
      order reversely on non-APICv box. This patch fixes it by bailing out for
      pending events and not consider new events in this scenario.
      
      Cc: Paolo Bonzini <pbonzini@redhat.com>
      Cc: Radim Krčmář <rkrcmar@redhat.com>
      Cc: Jan Kiszka <jan.kiszka@siemens.com>
      Signed-off-by: NWanpeng Li <wanpeng.li@hotmail.com>
      Fixes: 0ad3bed6 ("kvm: nVMX: move nested events check to kvm_vcpu_running")
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      acc9ab60
    • J
      x86/kvm/vmx: remove unused variable in segment_base() · 0fce546f
      Jérémy Lefaure 提交于
      The pointer 'struct desc_struct *d' is unused since commit 8c2e41f7
      ("x86/kvm/vmx: Simplify segment_base()") so let's remove it.
      Signed-off-by: NJérémy Lefaure <jeremy.lefaure@lse.epita.fr>
      Reviewed-by: NDavid Hildenbrand <david@redhat.com>
      Signed-off-by: NRadim Krčmář <rkrcmar@redhat.com>
      0fce546f
  11. 21 2月, 2017 6 次提交
  12. 17 2月, 2017 2 次提交
  13. 15 2月, 2017 10 次提交
    • J
      kvm: nVMX: Refactor nested_vmx_run() · 858e25c0
      Jim Mattson 提交于
      Nested_vmx_run is split into two parts: the part that handles the
      VMLAUNCH/VMRESUME instruction, and the part that modifies the vcpu state
      to transition from VMX root mode to VMX non-root mode. The latter will
      be used when restoring the checkpointed state of a vCPU that was in VMX
      operation when a snapshot was taken.
      Signed-off-by: NJim Mattson <jmattson@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      858e25c0
    • J
      kvm: nVMX: Split VMCS checks from nested_vmx_run() · ca0bde28
      Jim Mattson 提交于
      The checks performed on the contents of the vmcs12 are extracted from
      nested_vmx_run so that they can be used to validate a vmcs12 that has
      been restored from a checkpoint.
      Signed-off-by: NJim Mattson <jmattson@google.com>
      [Change prepare_vmcs02 and nested_vmx_load_cr3's last argument to u32,
       to match check_vmentry_postreqs.  Update comments for singlestep
       handling. - Paolo]
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      ca0bde28
    • J
      kvm: nVMX: Refactor nested_get_vmcs12_pages() · 6beb7bd5
      Jim Mattson 提交于
      Perform the checks on vmcs12 state early, but defer the gpa->hpa lookups
      until after prepare_vmcs02. Later, when we restore the checkpointed
      state of a vCPU in guest mode, we will not be able to do the gpa->hpa
      lookups when the restore is done.
      Signed-off-by: NJim Mattson <jmattson@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      6beb7bd5
    • J
      kvm: nVMX: Refactor handle_vmptrld() · a8bc284e
      Jim Mattson 提交于
      Handle_vmptrld is split into two parts: the part that handles the
      VMPTRLD instruction, and the part that establishes the current VMCS
      pointer.  The latter will be used when restoring the checkpointed state
      of a vCPU that had a valid VMCS pointer when a snapshot was taken.
      Signed-off-by: NJim Mattson <jmattson@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      a8bc284e
    • J
      kvm: nVMX: Refactor handle_vmon() · e29acc55
      Jim Mattson 提交于
      Handle_vmon is split into two parts: the part that handles the VMXON
      instruction, and the part that modifies the vcpu state to transition
      from legacy mode to VMX operation. The latter will be used when
      restoring the checkpointed state of a vCPU that was in VMX operation
      when a snapshot was taken.
      Signed-off-by: NJim Mattson <jmattson@google.com>
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      e29acc55
    • J
      kvm: nVMX: Prepare for checkpointing L2 state · cf8b84f4
      Jim Mattson 提交于
      Split prepare_vmcs12 into two parts: the part that stores the current L2
      guest state and the part that sets up the exit information fields. The
      former will be used when checkpointing the vCPU's VMX state.
      
      Modify prepare_vmcs02 so that it can construct a vmcs02 midway through
      L2 execution, using the checkpointed L2 guest state saved into the
      cached vmcs12 above.
      Signed-off-by: NJim Mattson <jmattson@google.com>
      [Rebasing: add from_vmentry argument to prepare_vmcs02 instead of using
       vmx->nested.nested_run_pending, because it is no longer 1 at the
       point prepare_vmcs02 is called. - Paolo]
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      cf8b84f4
    • P
      kvm: x86: do not use KVM_REQ_EVENT for APICv interrupt injection · b95234c8
      Paolo Bonzini 提交于
      Since bf9f6ac8 ("KVM: Update Posted-Interrupts Descriptor when vCPU
      is blocked", 2015-09-18) the posted interrupt descriptor is checked
      unconditionally for PIR.ON.  Therefore we don't need KVM_REQ_EVENT to
      trigger the scan and, if NMIs or SMIs are not involved, we can avoid
      the complicated event injection path.
      
      Calling kvm_vcpu_kick if PIR.ON=1 is also useless, though it has been
      there since APICv was introduced.
      
      However, without the KVM_REQ_EVENT safety net KVM needs to be much
      more careful about races between vmx_deliver_posted_interrupt and
      vcpu_enter_guest.  First, the IPI for posted interrupts may be issued
      between setting vcpu->mode = IN_GUEST_MODE and disabling interrupts.
      If that happens, kvm_trigger_posted_interrupt returns true, but
      smp_kvm_posted_intr_ipi doesn't do anything about it.  The guest is
      entered with PIR.ON, but the posted interrupt IPI has not been sent
      and the interrupt is only delivered to the guest on the next vmentry
      (if any).  To fix this, disable interrupts before setting vcpu->mode.
      This ensures that the IPI is delayed until the guest enters non-root mode;
      it is then trapped by the processor causing the interrupt to be injected.
      
      Second, the IPI may be issued between kvm_x86_ops->sync_pir_to_irr(vcpu)
      and vcpu->mode = IN_GUEST_MODE.  In this case, kvm_vcpu_kick is called
      but it (correctly) doesn't do anything because it sees vcpu->mode ==
      OUTSIDE_GUEST_MODE.  Again, the guest is entered with PIR.ON but no
      posted interrupt IPI is pending; this time, the fix for this is to move
      the RVI update after IN_GUEST_MODE.
      
      Both issues were mostly masked by the liberal usage of KVM_REQ_EVENT,
      though the second could actually happen with VT-d posted interrupts.
      In both race scenarios KVM_REQ_EVENT would cancel guest entry, resulting
      in another vmentry which would inject the interrupt.
      
      This saves about 300 cycles on the self_ipi_* tests of vmexit.flat.
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      b95234c8
    • P
      KVM: x86: do not scan IRR twice on APICv vmentry · 76dfafd5
      Paolo Bonzini 提交于
      Calls to apic_find_highest_irr are scanning IRR twice, once
      in vmx_sync_pir_from_irr and once in apic_search_irr.  Change
      sync_pir_from_irr to get the new maximum IRR from kvm_apic_update_irr;
      now that it does the computation, it can also do the RVI write.
      
      In order to avoid complications in svm.c, make the callback optional.
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      76dfafd5
    • P
      KVM: x86: preparatory changes for APICv cleanups · 810e6def
      Paolo Bonzini 提交于
      Add return value to __kvm_apic_update_irr/kvm_apic_update_irr.
      Move vmx_sync_pir_to_irr around.
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      810e6def
    • P
      KVM: vmx: clear pending interrupts on KVM_SET_LAPIC · 967235d3
      Paolo Bonzini 提交于
      Pending interrupts might be in the PI descriptor when the
      LAPIC is restored from an external state; we do not want
      them to be injected.
      Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
      967235d3