Skip to content

Commit

Permalink
Revert "iommu/vt-d: Fix possible recursive locking in intel_iommu_ini…
Browse files Browse the repository at this point in the history
…t()"

commit 7ebb5f8 upstream.

This reverts commit 9cd4f14.

Some issues were reported on the original commit. Some thunderbolt devices
don't work anymore due to the following DMA fault.

DMAR: DRHD: handling fault status reg 2
DMAR: [INTR-REMAP] Request device [09:00.0] fault index 0x8080
      [fault reason 0x25]
      Blocked a compatibility format interrupt request

Bring it back for now to avoid functional regression.

Fixes: 9cd4f14 ("iommu/vt-d: Fix possible recursive locking in intel_iommu_init()")
Link: https://lore.kernel.org/linux-iommu/485A6EA5-6D58-42EA-B298-8571E97422DE@getmailspring.com/
Link: https://bugzilla.kernel.org/show_bug.cgi?id=216497
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: <stable@vger.kernel.org> # 5.19.x
Reported-and-tested-by: George Hilliard <thirtythreeforty@gmail.com>
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Link: https://lore.kernel.org/r/20220920081701.3453504-1-baolu.lu@linux.intel.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Lu Baolu authored and Greg Kroah-Hartman committed Sep 23, 2022
1 parent 36371c3 commit 4d8637f
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 12 deletions.
7 changes: 0 additions & 7 deletions drivers/iommu/intel/dmar.c
Original file line number Diff line number Diff line change
Expand Up @@ -2368,13 +2368,6 @@ static int dmar_device_hotplug(acpi_handle handle, bool insert)
if (!dmar_in_use())
return 0;

/*
* It's unlikely that any I/O board is hot added before the IOMMU
* subsystem is initialized.
*/
if (IS_ENABLED(CONFIG_INTEL_IOMMU) && !intel_iommu_enabled)
return -EOPNOTSUPP;

if (dmar_detect_dsm(handle, DMAR_DSM_FUNC_DRHD)) {
tmp = handle;
} else {
Expand Down
27 changes: 25 additions & 2 deletions drivers/iommu/intel/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -3133,7 +3133,13 @@ static int __init init_dmars(void)

#ifdef CONFIG_INTEL_IOMMU_SVM
if (pasid_supported(iommu) && ecap_prs(iommu->ecap)) {
/*
* Call dmar_alloc_hwirq() with dmar_global_lock held,
* could cause possible lock race condition.
*/
up_write(&dmar_global_lock);
ret = intel_svm_enable_prq(iommu);
down_write(&dmar_global_lock);
if (ret)
goto free_iommu;
}
Expand Down Expand Up @@ -4039,6 +4045,7 @@ int __init intel_iommu_init(void)
force_on = (!intel_iommu_tboot_noforce && tboot_force_iommu()) ||
platform_optin_force_iommu();

down_write(&dmar_global_lock);
if (dmar_table_init()) {
if (force_on)
panic("tboot: Failed to initialize DMAR table\n");
Expand All @@ -4051,6 +4058,16 @@ int __init intel_iommu_init(void)
goto out_free_dmar;
}

up_write(&dmar_global_lock);

/*
* The bus notifier takes the dmar_global_lock, so lockdep will
* complain later when we register it under the lock.
*/
dmar_register_bus_notifier();

down_write(&dmar_global_lock);

if (!no_iommu)
intel_iommu_debugfs_init();

Expand Down Expand Up @@ -4098,9 +4115,11 @@ int __init intel_iommu_init(void)
pr_err("Initialization failed\n");
goto out_free_dmar;
}
up_write(&dmar_global_lock);

init_iommu_pm_ops();

down_read(&dmar_global_lock);
for_each_active_iommu(iommu, drhd) {
/*
* The flush queue implementation does not perform
Expand All @@ -4118,11 +4137,13 @@ int __init intel_iommu_init(void)
"%s", iommu->name);
iommu_device_register(&iommu->iommu, &intel_iommu_ops, NULL);
}
up_read(&dmar_global_lock);

bus_set_iommu(&pci_bus_type, &intel_iommu_ops);
if (si_domain && !hw_pass_through)
register_memory_notifier(&intel_iommu_memory_nb);

down_read(&dmar_global_lock);
if (probe_acpi_namespace_devices())
pr_warn("ACPI name space devices didn't probe correctly\n");

Expand All @@ -4133,15 +4154,17 @@ int __init intel_iommu_init(void)

iommu_disable_protect_mem_regions(iommu);
}
up_read(&dmar_global_lock);

intel_iommu_enabled = 1;
dmar_register_bus_notifier();
pr_info("Intel(R) Virtualization Technology for Directed I/O\n");

intel_iommu_enabled = 1;

return 0;

out_free_dmar:
intel_iommu_free_dmars();
up_write(&dmar_global_lock);
return ret;
}

Expand Down
4 changes: 1 addition & 3 deletions include/linux/dmar.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ struct dmar_pci_notify_info {

extern struct rw_semaphore dmar_global_lock;
extern struct list_head dmar_drhd_units;
extern int intel_iommu_enabled;

#define for_each_drhd_unit(drhd) \
list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \
Expand All @@ -93,8 +92,7 @@ extern int intel_iommu_enabled;
static inline bool dmar_rcu_check(void)
{
return rwsem_is_locked(&dmar_global_lock) ||
system_state == SYSTEM_BOOTING ||
(IS_ENABLED(CONFIG_INTEL_IOMMU) && !intel_iommu_enabled);
system_state == SYSTEM_BOOTING;
}

#define dmar_rcu_dereference(p) rcu_dereference_check((p), dmar_rcu_check())
Expand Down

0 comments on commit 4d8637f

Please sign in to comment.