1. 13 May, 2020 23 commits
  2. 08 May, 2020 5 commits
    • Suravee Suthikulpanit's avatar
      KVM: SVM: Disable AVIC before setting V_IRQ · 7d611233
      Suravee Suthikulpanit authored
      The commit 64b5bd27 ("KVM: nSVM: ignore L1 interrupt window
      while running L2 with V_INTR_MASKING=1") introduced a WARN_ON,
      which checks if AVIC is enabled when trying to set V_IRQ
      in the VMCB for enabling irq window.
      
      The following warning is triggered because the requesting vcpu
      (to deactivate AVIC) does not get to process APICv update request
      for itself until the next #vmexit.
      
      WARNING: CPU: 0 PID: 118232 at arch/x86/kvm/svm/svm.c:1372 enable_irq_window+0x6a/0xa0 [kvm_amd]
       RIP: 0010:enable_irq_window+0x6a/0xa0 [kvm_amd]
       Call Trace:
        kvm_arch_vcpu_ioctl_run+0x6e3/0x1b50 [kvm]
        ? kvm_vm_ioctl_irq_line+0x27/0x40 [kvm]
        ? _copy_to_user+0x26/0x30
        ? kvm_vm_ioctl+0xb3e/0xd90 [kvm]
        ? set_next_entity+0x78/0xc0
        kvm_vcpu_ioctl+0x236/0x610 [kvm]
        ksys_ioctl+0x8a/0xc0
        __x64_sys_ioctl+0x1a/0x20
        do_syscall_64+0x58/0x210
        entry_SYSCALL_64_after_hwframe+0x44/0xa9
      
      Fixes by sending APICV update request to all other vcpus, and
      immediately update APIC for itself.
      Signed-off-by: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
      Link: https://lkml.org/lkml/2020/5/2/167
      Fixes: 64b5bd27 ("KVM: nSVM: ignore L1 interrupt window while running L2 with V_INTR_MASKING=1")
      Message-Id: <1588818939-54264-1-git-send-email-suravee.suthikulpanit@amd.com>
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      7d611233
    • Suravee Suthikulpanit's avatar
      KVM: Introduce kvm_make_all_cpus_request_except() · 54163a34
      Suravee Suthikulpanit authored
      This allows making request to all other vcpus except the one
      specified in the parameter.
      Signed-off-by: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
      Message-Id: <1588771076-73790-2-git-send-email-suravee.suthikulpanit@amd.com>
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      54163a34
    • Paolo Bonzini's avatar
      KVM: VMX: pass correct DR6 for GD userspace exit · 45981ded
      Paolo Bonzini authored
      When KVM_EXIT_DEBUG is raised for the disabled-breakpoints case (DR7.GD),
      DR6 was incorrectly copied from the value in the VM.  Instead,
      DR6.BD should be set in order to catch this case.
      
      On AMD this does not need any special code because the processor triggers
      a #DB exception that is intercepted.  However, the testcase would fail
      without the previous patch because both DR6.BS and DR6.BD would be set.
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      45981ded
    • Paolo Bonzini's avatar
      KVM: x86, SVM: isolate vcpu->arch.dr6 from vmcb->save.dr6 · d67668e9
      Paolo Bonzini authored
      There are two issues with KVM_EXIT_DEBUG on AMD, whose root cause is the
      different handling of DR6 on intercepted #DB exceptions on Intel and AMD.
      
      On Intel, #DB exceptions transmit the DR6 value via the exit qualification
      field of the VMCS, and the exit qualification only contains the description
      of the precise event that caused a vmexit.
      
      On AMD, instead the DR6 field of the VMCB is filled in as if the #DB exception
      was to be injected into the guest.  This has two effects when guest debugging
      is in use:
      
      * the guest DR6 is clobbered
      
      * the kvm_run->debug.arch.dr6 field can accumulate more debug events, rather
      than just the last one that happened (the testcase in the next patch covers
      this issue).
      
      This patch fixes both issues by emulating, so to speak, the Intel behavior
      on AMD processors.  The important observation is that (after the previous
      patches) the VMCB value of DR6 is only ever observable from the guest is
      KVM_DEBUGREG_WONT_EXIT is set.  Therefore we can actually set vmcb->save.dr6
      to any value we want as long as KVM_DEBUGREG_WONT_EXIT is clear, which it
      will be if guest debugging is enabled.
      
      Therefore it is possible to enter the guest with an all-zero DR6,
      reconstruct the #DB payload from the DR6 we get at exit time, and let
      kvm_deliver_exception_payload move the newly set bits into vcpu->arch.dr6.
      Some extra bits may be included in the payload if KVM_DEBUGREG_WONT_EXIT
      is set, but this is harmless.
      
      This may not be the most optimized way to deal with this, but it is
      simple and, being confined within SVM code, it gets rid of the set_dr6
      callback and kvm_update_dr6.
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      d67668e9
    • Paolo Bonzini's avatar
      KVM: SVM: keep DR6 synchronized with vcpu->arch.dr6 · 5679b803
      Paolo Bonzini authored
      kvm_x86_ops.set_dr6 is only ever called with vcpu->arch.dr6 as the
      second argument.  Ensure that the VMCB value is synchronized to
      vcpu->arch.dr6 on #DB (both "normal" and nested) and nested vmentry, so
      that the current value of DR6 is always available in vcpu->arch.dr6.
      The get_dr6 callback can just access vcpu->arch.dr6 and becomes redundant.
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      5679b803
  3. 07 May, 2020 6 commits
  4. 06 May, 2020 4 commits
  5. 04 May, 2020 2 commits
    • Paolo Bonzini's avatar
      kvm: ioapic: Restrict lazy EOI update to edge-triggered interrupts · 8be8f932
      Paolo Bonzini authored
      Commit f458d039 ("kvm: ioapic: Lazy update IOAPIC EOI") introduces
      the following infinite loop:
      
      BUG: stack guard page was hit at 000000008f595917 \
      (stack is 00000000bdefe5a4..00000000ae2b06f5)
      kernel stack overflow (double-fault): 0000 [#1] SMP NOPTI
      RIP: 0010:kvm_set_irq+0x51/0x160 [kvm]
      Call Trace:
       irqfd_resampler_ack+0x32/0x90 [kvm]
       kvm_notify_acked_irq+0x62/0xd0 [kvm]
       kvm_ioapic_update_eoi_one.isra.0+0x30/0x120 [kvm]
       ioapic_set_irq+0x20e/0x240 [kvm]
       kvm_ioapic_set_irq+0x5c/0x80 [kvm]
       kvm_set_irq+0xbb/0x160 [kvm]
       ? kvm_hv_set_sint+0x20/0x20 [kvm]
       irqfd_resampler_ack+0x32/0x90 [kvm]
       kvm_notify_acked_irq+0x62/0xd0 [kvm]
       kvm_ioapic_update_eoi_one.isra.0+0x30/0x120 [kvm]
       ioapic_set_irq+0x20e/0x240 [kvm]
       kvm_ioapic_set_irq+0x5c/0x80 [kvm]
       kvm_set_irq+0xbb/0x160 [kvm]
       ? kvm_hv_set_sint+0x20/0x20 [kvm]
      ....
      
      The re-entrancy happens because the irq state is the OR of
      the interrupt state and the resamplefd state.  That is, we don't
      want to show the state as 0 until we've had a chance to set the
      resamplefd.  But if the interrupt has _not_ gone low then
      ioapic_set_irq is invoked again, causing an infinite loop.
      
      This can only happen for a level-triggered interrupt, otherwise
      irqfd_inject would immediately set the KVM_USERSPACE_IRQ_SOURCE_ID high
      and then low.  Fortunately, in the case of level-triggered interrupts the VMEXIT already happens because
      TMR is set.  Thus, fix the bug by restricting the lazy invocation
      of the ack notifier to edge-triggered interrupts, the only ones that
      need it.
      Tested-by: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
      Reported-by: borisvk@bstnet.org
      Suggested-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      Link: https://www.spinics.net/lists/kvm/msg213512.html
      Fixes: f458d039 ("kvm: ioapic: Lazy update IOAPIC EOI")
      Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=207489Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      8be8f932
    • Suravee Suthikulpanit's avatar
      KVM: x86: Fixes posted interrupt check for IRQs delivery modes · 637543a8
      Suravee Suthikulpanit authored
      Current logic incorrectly uses the enum ioapic_irq_destination_types
      to check the posted interrupt destination types. However, the value was
      set using APIC_DM_XXX macros, which are left-shifted by 8 bits.
      
      Fixes by using the APIC_DM_FIXED and APIC_DM_LOWEST instead.
      
      Fixes: (fdcf7562 'KVM: x86: Disable posted interrupts for non-standard IRQs delivery modes')
      Cc: Alexander Graf <graf@amazon.com>
      Signed-off-by: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
      Message-Id: <1586239989-58305-1-git-send-email-suravee.suthikulpanit@amd.com>
      Reviewed-by: default avatarMaxim Levitsky <mlevitsk@redhat.com>
      Tested-by: default avatarMaxim Levitsky <mlevitsk@redhat.com>
      Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      637543a8