1. 06 8月, 2019 1 次提交
  2. 22 7月, 2019 4 次提交
    • D
      iommu/vt-d: Check if domain->pgd was allocated · 3ee9eca7
      Dmitry Safonov 提交于
      There is a couple of places where on domain_init() failure domain_exit()
      is called. While currently domain_init() can fail only if
      alloc_pgtable_page() has failed.
      
      Make domain_exit() check if domain->pgd present, before calling
      domain_unmap(), as it theoretically should crash on clearing pte entries
      in dma_pte_clear_level().
      
      Cc: David Woodhouse <dwmw2@infradead.org>
      Cc: Joerg Roedel <joro@8bytes.org>
      Cc: Lu Baolu <baolu.lu@linux.intel.com>
      Cc: iommu@lists.linux-foundation.org
      Signed-off-by: NDmitry Safonov <dima@arista.com>
      Reviewed-by: NLu Baolu <baolu.lu@linux.intel.com>
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      3ee9eca7
    • D
      iommu/vt-d: Don't queue_iova() if there is no flush queue · effa4678
      Dmitry Safonov 提交于
      Intel VT-d driver was reworked to use common deferred flushing
      implementation. Previously there was one global per-cpu flush queue,
      afterwards - one per domain.
      
      Before deferring a flush, the queue should be allocated and initialized.
      
      Currently only domains with IOMMU_DOMAIN_DMA type initialize their flush
      queue. It's probably worth to init it for static or unmanaged domains
      too, but it may be arguable - I'm leaving it to iommu folks.
      
      Prevent queuing an iova flush if the domain doesn't have a queue.
      The defensive check seems to be worth to keep even if queue would be
      initialized for all kinds of domains. And is easy backportable.
      
      On 4.19.43 stable kernel it has a user-visible effect: previously for
      devices in si domain there were crashes, on sata devices:
      
       BUG: spinlock bad magic on CPU#6, swapper/0/1
        lock: 0xffff88844f582008, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0
       CPU: 6 PID: 1 Comm: swapper/0 Not tainted 4.19.43 #1
       Call Trace:
        <IRQ>
        dump_stack+0x61/0x7e
        spin_bug+0x9d/0xa3
        do_raw_spin_lock+0x22/0x8e
        _raw_spin_lock_irqsave+0x32/0x3a
        queue_iova+0x45/0x115
        intel_unmap+0x107/0x113
        intel_unmap_sg+0x6b/0x76
        __ata_qc_complete+0x7f/0x103
        ata_qc_complete+0x9b/0x26a
        ata_qc_complete_multiple+0xd0/0xe3
        ahci_handle_port_interrupt+0x3ee/0x48a
        ahci_handle_port_intr+0x73/0xa9
        ahci_single_level_irq_intr+0x40/0x60
        __handle_irq_event_percpu+0x7f/0x19a
        handle_irq_event_percpu+0x32/0x72
        handle_irq_event+0x38/0x56
        handle_edge_irq+0x102/0x121
        handle_irq+0x147/0x15c
        do_IRQ+0x66/0xf2
        common_interrupt+0xf/0xf
       RIP: 0010:__do_softirq+0x8c/0x2df
      
      The same for usb devices that use ehci-pci:
       BUG: spinlock bad magic on CPU#0, swapper/0/1
        lock: 0xffff88844f402008, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0
       CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.43 #4
       Call Trace:
        <IRQ>
        dump_stack+0x61/0x7e
        spin_bug+0x9d/0xa3
        do_raw_spin_lock+0x22/0x8e
        _raw_spin_lock_irqsave+0x32/0x3a
        queue_iova+0x77/0x145
        intel_unmap+0x107/0x113
        intel_unmap_page+0xe/0x10
        usb_hcd_unmap_urb_setup_for_dma+0x53/0x9d
        usb_hcd_unmap_urb_for_dma+0x17/0x100
        unmap_urb_for_dma+0x22/0x24
        __usb_hcd_giveback_urb+0x51/0xc3
        usb_giveback_urb_bh+0x97/0xde
        tasklet_action_common.isra.4+0x5f/0xa1
        tasklet_action+0x2d/0x30
        __do_softirq+0x138/0x2df
        irq_exit+0x7d/0x8b
        smp_apic_timer_interrupt+0x10f/0x151
        apic_timer_interrupt+0xf/0x20
        </IRQ>
       RIP: 0010:_raw_spin_unlock_irqrestore+0x17/0x39
      
      Cc: David Woodhouse <dwmw2@infradead.org>
      Cc: Joerg Roedel <joro@8bytes.org>
      Cc: Lu Baolu <baolu.lu@linux.intel.com>
      Cc: iommu@lists.linux-foundation.org
      Cc: <stable@vger.kernel.org> # 4.14+
      Fixes: 13cf0174 ("iommu/vt-d: Make use of iova deferred flushing")
      Signed-off-by: NDmitry Safonov <dima@arista.com>
      Reviewed-by: NLu Baolu <baolu.lu@linux.intel.com>
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      effa4678
    • L
      iommu/vt-d: Avoid duplicated pci dma alias consideration · 55752949
      Lu Baolu 提交于
      As we have abandoned the home-made lazy domain allocation
      and delegated the DMA domain life cycle up to the default
      domain mechanism defined in the generic iommu layer, we
      needn't consider pci alias anymore when mapping/unmapping
      the context entries. Without this fix, we see kernel NULL
      pointer dereference during pci device hot-plug test.
      
      Cc: Ashok Raj <ashok.raj@intel.com>
      Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
      Cc: Kevin Tian <kevin.tian@intel.com>
      Fixes: fa954e68 ("iommu/vt-d: Delegate the dma domain to upper layer")
      Signed-off-by: NLu Baolu <baolu.lu@linux.intel.com>
      Reported-and-tested-by: NXu Pengfei <pengfei.xu@intel.com>
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      55752949
    • J
      Revert "iommu/vt-d: Consolidate domain_init() to avoid duplication" · 301e7ee1
      Joerg Roedel 提交于
      This reverts commit 123b2ffc.
      
      This commit reportedly caused boot failures on some systems
      and needs to be reverted for now.
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      301e7ee1
  3. 23 6月, 2019 1 次提交
    • P
      Revert "iommu/vt-d: Fix lock inversion between iommu->lock and device_domain_lock" · 0aafc8ae
      Peter Xu 提交于
      This reverts commit 7560cc3c.
      
      With 5.2.0-rc5 I can easily trigger this with lockdep and iommu=pt:
      
          ======================================================
          WARNING: possible circular locking dependency detected
          5.2.0-rc5 #78 Not tainted
          ------------------------------------------------------
          swapper/0/1 is trying to acquire lock:
          00000000ea2b3beb (&(&iommu->lock)->rlock){+.+.}, at: domain_context_mapping_one+0xa5/0x4e0
          but task is already holding lock:
          00000000a681907b (device_domain_lock){....}, at: domain_context_mapping_one+0x8d/0x4e0
          which lock already depends on the new lock.
          the existing dependency chain (in reverse order) is:
          -> #1 (device_domain_lock){....}:
                 _raw_spin_lock_irqsave+0x3c/0x50
                 dmar_insert_one_dev_info+0xbb/0x510
                 domain_add_dev_info+0x50/0x90
                 dev_prepare_static_identity_mapping+0x30/0x68
                 intel_iommu_init+0xddd/0x1422
                 pci_iommu_init+0x16/0x3f
                 do_one_initcall+0x5d/0x2b4
                 kernel_init_freeable+0x218/0x2c1
                 kernel_init+0xa/0x100
                 ret_from_fork+0x3a/0x50
          -> #0 (&(&iommu->lock)->rlock){+.+.}:
                 lock_acquire+0x9e/0x170
                 _raw_spin_lock+0x25/0x30
                 domain_context_mapping_one+0xa5/0x4e0
                 pci_for_each_dma_alias+0x30/0x140
                 dmar_insert_one_dev_info+0x3b2/0x510
                 domain_add_dev_info+0x50/0x90
                 dev_prepare_static_identity_mapping+0x30/0x68
                 intel_iommu_init+0xddd/0x1422
                 pci_iommu_init+0x16/0x3f
                 do_one_initcall+0x5d/0x2b4
                 kernel_init_freeable+0x218/0x2c1
                 kernel_init+0xa/0x100
                 ret_from_fork+0x3a/0x50
      
          other info that might help us debug this:
           Possible unsafe locking scenario:
                 CPU0                    CPU1
                 ----                    ----
            lock(device_domain_lock);
                                         lock(&(&iommu->lock)->rlock);
                                         lock(device_domain_lock);
            lock(&(&iommu->lock)->rlock);
      
           *** DEADLOCK ***
          2 locks held by swapper/0/1:
           #0: 00000000033eb13d (dmar_global_lock){++++}, at: intel_iommu_init+0x1e0/0x1422
           #1: 00000000a681907b (device_domain_lock){....}, at: domain_context_mapping_one+0x8d/0x4e0
      
          stack backtrace:
          CPU: 2 PID: 1 Comm: swapper/0 Not tainted 5.2.0-rc5 #78
          Hardware name: LENOVO 20KGS35G01/20KGS35G01, BIOS N23ET50W (1.25 ) 06/25/2018
          Call Trace:
           dump_stack+0x85/0xc0
           print_circular_bug.cold.57+0x15c/0x195
           __lock_acquire+0x152a/0x1710
           lock_acquire+0x9e/0x170
           ? domain_context_mapping_one+0xa5/0x4e0
           _raw_spin_lock+0x25/0x30
           ? domain_context_mapping_one+0xa5/0x4e0
           domain_context_mapping_one+0xa5/0x4e0
           ? domain_context_mapping_one+0x4e0/0x4e0
           pci_for_each_dma_alias+0x30/0x140
           dmar_insert_one_dev_info+0x3b2/0x510
           domain_add_dev_info+0x50/0x90
           dev_prepare_static_identity_mapping+0x30/0x68
           intel_iommu_init+0xddd/0x1422
           ? printk+0x58/0x6f
           ? lockdep_hardirqs_on+0xf0/0x180
           ? do_early_param+0x8e/0x8e
           ? e820__memblock_setup+0x63/0x63
           pci_iommu_init+0x16/0x3f
           do_one_initcall+0x5d/0x2b4
           ? do_early_param+0x8e/0x8e
           ? rcu_read_lock_sched_held+0x55/0x60
           ? do_early_param+0x8e/0x8e
           kernel_init_freeable+0x218/0x2c1
           ? rest_init+0x230/0x230
           kernel_init+0xa/0x100
           ret_from_fork+0x3a/0x50
      
      domain_context_mapping_one() is taking device_domain_lock first then
      iommu lock, while dmar_insert_one_dev_info() is doing the reverse.
      
      That should be introduced by commit:
      
      7560cc3c ("iommu/vt-d: Fix lock inversion between iommu->lock and
                    device_domain_lock", 2019-05-27)
      
      So far I still cannot figure out how the previous deadlock was
      triggered (I cannot find iommu lock taken before calling of
      iommu_flush_dev_iotlb()), however I'm pretty sure that that change
      should be incomplete at least because it does not fix all the places
      so we're still taking the locks in different orders, while reverting
      that commit is very clean to me so far that we should always take
      device_domain_lock first then the iommu lock.
      
      We can continue to try to find the real culprit mentioned in
      7560cc3c, but for now I think we should revert it to fix current
      breakage.
      
      CC: Joerg Roedel <joro@8bytes.org>
      CC: Lu Baolu <baolu.lu@linux.intel.com>
      CC: dave.jiang@intel.com
      Signed-off-by: NPeter Xu <peterx@redhat.com>
      Tested-by: NChris Wilson <chris@chris-wilson.co.uk>
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      0aafc8ae
  4. 18 6月, 2019 2 次提交
  5. 12 6月, 2019 12 次提交
  6. 05 6月, 2019 1 次提交
  7. 03 6月, 2019 1 次提交
  8. 02 6月, 2019 1 次提交
  9. 28 5月, 2019 13 次提交
  10. 27 5月, 2019 4 次提交
    • J
      iommu/vt-d: Implement apply_resv_region iommu ops entry · 73bcbdc9
      James Sewart 提交于
      Used by iommu.c before creating identity mappings for reserved
      ranges to ensure dma-ops won't ever remap these ranges.
      Signed-off-by: NJames Sewart <jamessewart@arista.com>
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      73bcbdc9
    • D
      iommu/vt-d: Fix lock inversion between iommu->lock and device_domain_lock · 7560cc3c
      Dave Jiang 提交于
      Lockdep debug reported lock inversion related with the iommu code
      caused by dmar_insert_one_dev_info() grabbing the iommu->lock and
      the device_domain_lock out of order versus the code path in
      iommu_flush_dev_iotlb(). Expanding the scope of the iommu->lock and
      reversing the order of lock acquisition fixes the issue.
      
      [   76.238180] dsa_bus wq0.0: dsa wq wq0.0 disabled
      [   76.248706]
      [   76.250486] ========================================================
      [   76.257113] WARNING: possible irq lock inversion dependency detected
      [   76.263736] 5.1.0-rc5+ #162 Not tainted
      [   76.267854] --------------------------------------------------------
      [   76.274485] systemd-journal/521 just changed the state of lock:
      [   76.280685] 0000000055b330f5 (device_domain_lock){..-.}, at: iommu_flush_dev_iotlb.part.63+0x29/0x90
      [   76.290099] but this lock took another, SOFTIRQ-unsafe lock in the past:
      [   76.297093]  (&(&iommu->lock)->rlock){+.+.}
      [   76.297094]
      [   76.297094]
      [   76.297094] and interrupts could create inverse lock ordering between them.
      [   76.297094]
      [   76.314257]
      [   76.314257] other info that might help us debug this:
      [   76.321448]  Possible interrupt unsafe locking scenario:
      [   76.321448]
      [   76.328907]        CPU0                    CPU1
      [   76.333777]        ----                    ----
      [   76.338642]   lock(&(&iommu->lock)->rlock);
      [   76.343165]                                local_irq_disable();
      [   76.349422]                                lock(device_domain_lock);
      [   76.356116]                                lock(&(&iommu->lock)->rlock);
      [   76.363154]   <Interrupt>
      [   76.366134]     lock(device_domain_lock);
      [   76.370548]
      [   76.370548]  *** DEADLOCK ***
      
      Fixes: 745f2586 ("iommu/vt-d: Simplify function get_domain_for_dev()")
      Signed-off-by: NDave Jiang <dave.jiang@intel.com>
      Reviewed-by: NLu Baolu <baolu.lu@linux.intel.com>
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      7560cc3c
    • S
      iommu/vt-d: Introduce macros useful for dumping DMAR table · cdd3a249
      Sai Praneeth Prakhya 提交于
      A scalable mode DMAR table walk would involve looking at bits in each stage
      of walk, like,
      1. Is PASID enabled in the context entry?
      2. What's the size of PASID directory?
      3. Is the PASID directory entry present?
      4. Is the PASID table entry present?
      5. Number of PASID table entries?
      
      Hence, add these macros that will later be used during this walk.
      Apart from adding new macros, move existing macros (like
      pasid_pde_is_present(), get_pasid_table_from_pde() and pasid_supported())
      to appropriate header files so that they could be reused.
      
      Cc: Joerg Roedel <joro@8bytes.org>
      Cc: Ashok Raj <ashok.raj@intel.com>
      Cc: Lu Baolu <baolu.lu@linux.intel.com>
      Cc: Sohil Mehta <sohil.mehta@intel.com>
      Cc: David Woodhouse <dwmw2@infradead.org>
      Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
      Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
      Reviewed-by: NLu Baolu <baolu.lu@linux.intel.com>
      Reviewed-by: NAndy Shevchenko <andriy.shevchenko@linux.intel.com>
      Signed-off-by: NSai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      cdd3a249
    • L
      iommu/vt-d: Remove unnecessary rcu_read_locks · f780a8dc
      Lukasz Odzioba 提交于
      We use RCU's for rarely updated lists like iommus, rmrr, atsr units.
      
      I'm not sure why domain_remove_dev_info() in domain_exit() was surrounded
      by rcu_read_lock. Lock was present before refactoring in d160aca5,
      but it was related to rcu list, not domain_remove_dev_info function.
      
      dmar_remove_one_dev_info() doesn't touch any of those lists, so it doesn't
      require a lock. In fact it is called 6 times without it anyway.
      
      Fixes: d160aca5 ("iommu/vt-d: Unify domain->iommu attach/detachment")
      Signed-off-by: NLukasz Odzioba <lukasz.odzioba@intel.com>
      Signed-off-by: NJoerg Roedel <jroedel@suse.de>
      f780a8dc