• Lu Baolu's avatar
    iommu/vt-d: Use rcu_lock in get_resv_regions · bf638a65
    Lu Baolu authored
    Commit 5f64ce54 ("iommu/vt-d: Duplicate iommu_resv_region objects
    per device list") converted rcu_lock in get_resv_regions to
    dmar_global_lock to allow sleeping in iommu_alloc_resv_region(). This
    introduced possible recursive locking if get_resv_regions is called from
    within a section where intel_iommu_init() already holds dmar_global_lock.
    
    Especially, after commit 57365a04 ("iommu: Move bus setup to IOMMU
    device registration"), below lockdep splats could always be seen.
    
     ============================================
     WARNING: possible recursive locking detected
     6.0.0-rc4+ #325 Tainted: G          I
     --------------------------------------------
     swapper/0/1 is trying to acquire lock:
     ffffffffa8a18c90 (dmar_global_lock){++++}-{3:3}, at:
     intel_iommu_get_resv_regions+0x25/0x270
    
     but task is already holding lock:
     ffffffffa8a18c90 (dmar_global_lock){++++}-{3:3}, at:
     intel_iommu_init+0x36d/0x6ea
    
     ...
    
     Call Trace:
      <TASK>
      dump_stack_lvl+0x48/0x5f
      __lock_acquire.cold.73+0xad/0x2bb
      lock_acquire+0xc2/0x2e0
      ? intel_iommu_get_resv_regions+0x25/0x270
      ? lock_is_held_type+0x9d/0x110
      down_read+0x42/0x150
      ? intel_iommu_get_resv_regions+0x25/0x270
      intel_iommu_get_resv_regions+0x25/0x270
      iommu_create_device_direct_mappings.isra.28+0x8d/0x1c0
      ? iommu_get_dma_cookie+0x6d/0x90
      bus_iommu_probe+0x19f/0x2e0
      iommu_device_register+0xd4/0x130
      intel_iommu_init+0x3e1/0x6ea
      ? iommu_setup+0x289/0x289
      ? rdinit_setup+0x34/0x34
      pci_iommu_init+0x12/0x3a
      do_one_initcall+0x65/0x320
      ? rdinit_setup+0x34/0x34
      ? rcu_read_lock_sched_held+0x5a/0x80
      kernel_init_freeable+0x28a/0x2f3
      ? rest_init+0x1b0/0x1b0
      kernel_init+0x1a/0x130
      ret_from_fork+0x1f/0x30
      </TASK>
    
    This rolls back dmar_global_lock to rcu_lock in get_resv_regions to avoid
    the lockdep splat.
    
    Fixes: 57365a04 ("iommu: Move bus setup to IOMMU device registration")
    Signed-off-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
    Tested-by: default avatarAlex Williamson <alex.williamson@redhat.com>
    Link: https://lore.kernel.org/r/20220927053109.4053662-3-baolu.lu@linux.intel.comSigned-off-by: default avatarJoerg Roedel <jroedel@suse.de>
    bf638a65
iommu.c 125 KB