iommu/vt-d: Fixes for v5.17-rc2
Subsystems (2)
Lu Baolu
maintainercover iommu/vt-d: Fixes for v5.17-rc2
Hi Joerg,
Two fixes are queued for v5.17. They aim to fix:
- Fix PCI bus rescan device hot add;
- Fix potential memory leak in intel_setup_irq_remapping().
Please consider them for the iommu/fix branch.
Best regards,
Lu Baolu
Guoqing Jiang (1):
iommu/vt-d: Fix potential memory leak in intel_setup_irq_remapping()
Jacob Pan (1):
iommu/vt-d: Fix PCI bus rescan device hot add
include/linux/iommu.h | 1 + drivers/iommu/intel/dmar.c | 71 +++++++++++++++++++++-------- drivers/iommu/intel/irq_remapping.c | 13 ++++-- drivers/iommu/iommu.c | 1 + 4 files changed, 64 insertions(+), 22 deletions(-)
Signature · 6 lines
2.25.1 _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
Lu Baolu
maintainerPATCH 1/2 iommu/vt-d: Fix PCI bus rescan device hot add
From: Jacob Pan <[email protected]>
During PCI bus rescan, adding new devices involve two notifiers.
1. dmar_pci_bus_notifier()
2. iommu_bus_notifier()
The current code sets #1 as low priority (INT_MIN) which resulted in #2 being invoked first. The result is that struct device pointer cannot be found in DRHD search for the new device's DMAR/IOMMU. Subsequently, the device is put under the "catch-all" IOMMU instead of the correct one.
This could cause system hang when device TLB invalidation is sent to the wrong IOMMU. Invalidation timeout error and hard lockup have been observed.
On the reverse direction for device removal, the order should be #2-#1 such that DMAR cleanup is done after IOMMU.
This patch fixes the issue by setting proper priorities for dmar_pci_bus_notifier around IOMMU bus notifier. DRHD search for a new device will find the correct IOMMU. The order with this patch is the following:
1. dmar_pci_bus_add_dev()
2. iommu_probe_device()
3. iommu_release_device()
4. dmar_pci_bus_remove_dev()
--- include/linux/iommu.h | 1 + drivers/iommu/intel/dmar.c | 71 ++++++++++++++++++++++++++++---------- drivers/iommu/iommu.c | 1 + 3 files changed, 54 insertions(+), 19 deletions(-)
include/linux/iommu.h +1 -0
@@ -403,6 +403,7 @@ static inline void iommu_iotlb_gather_init(struct iommu_iotlb_gather *gather) }; } +#define IOMMU_BUS_NOTIFY_PRIORITY 0#define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1/* Device added */ #define IOMMU_GROUP_NOTIFY_DEL_DEVICE 2/* Pre Device removed */ #define IOMMU_GROUP_NOTIFY_BIND_DRIVER 3/* Pre Driver bind */
drivers/iommu/intel/dmar.c +52 -19
117 lines not on this page · raw message
drivers/iommu/iommu.c +1 -0
@@ -1841,6 +1841,7 @@ static int iommu_bus_init(struct bus_type *bus, const struct iommu_ops *ops)return -ENOMEM ; nb->notifier_call = iommu_bus_notifier; + nb->priority =IOMMU_BUS_NOTIFY_PRIORITY ; err =bus_register_notifier (bus, nb);if (err)
Signature · 6 lines
2.25.1 _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
Joerg Roedel
maintainerRe: [PATCH 1/2] iommu/vt-d: Fix PCI bus rescan device hot add
Hi Jacob, Baolu,
Quoted 7 lines · Lu Baolu
During PCI bus rescan, adding new devices involve two notifiers.
1.dmar_pci_bus_notifier()
2.iommu_bus_notifier()
The current code sets #1 as low priority (INT_MIN) which resulted in #2 being invoked first. The result is that struct device pointer cannot be found in DRHD search for the new device's DMAR/IOMMU. Subsequently, the device is put under the "catch-all" IOMMU instead of the correct one.
There are actually iommu_ops pointers invoked from iommu_bus_notifier() into IOMMU driver code. Can those be used to enforce the ordering in a more reliable way?
Regards,
Joerg
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Robin Murphy
reviewerRe: [PATCH 1/2] iommu/vt-d: Fix PCI bus rescan device hot add
Quoted 11 lines · Joerg Roedel
Hi Jacob, Baolu,
Quoted 7 lines · Lu Baolu
During PCI bus rescan, adding new devices involve two notifiers.
1.dmar_pci_bus_notifier()
2.iommu_bus_notifier()
The current code sets #1 as low priority (INT_MIN) which resulted in #2 being invoked first. The result is that struct device pointer cannot be found in DRHD search for the new device's DMAR/IOMMU. Subsequently, the device is put under the "catch-all" IOMMU instead of the correct one.
Quoted 3 lines
There are actually
iommu_opspointers invoked fromiommu_bus_notifier()into IOMMU driver code. Can those be used to enforce the ordering in a more reliable way?
Indeed I very nearly asked whether we couldn't just call these from intel_iommu_{probe,release}_device() directly, but it looks like they also interact with the interrupt remapping stuff which can be built independently of the IOMMU API :(
Robin.
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Joerg Roedel
maintainerRe: [PATCH 1/2] iommu/vt-d: Fix PCI bus rescan device hot add
Quoted 4 lines · Robin Murphy
Indeed I very nearly asked whether we couldn't just call these from intel_iommu_{probe,release}_device() directly, but it looks like they also interact with the interrupt remapping stuff which can be built independently of the IOMMU API :(
Okay, but having two notifiers is still ugly. Can we only register a notifier when IRQ-remapping is used without IOMMU-API? In this case a single notifier be sufficient.
Regards,
Joerg
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 1/2] iommu/vt-d: Fix PCI bus rescan device hot add
Hi Joerg,
Quoted 10 lines · Joerg Roedel
Quoted 4 lines · Robin Murphy
Indeed I very nearly asked whether we couldn't just call these from intel_iommu_{probe,release}_device() directly, but it looks like they also interact with the interrupt remapping stuff which can be built independently of the IOMMU API :(
Okay, but having two notifiers is still ugly. Can we only register a notifier when IRQ-remapping is used without IOMMU-API? In this case a single notifier be sufficient.
Do you mean having an IRQ remapping notifier regardless IOMMU-API is enabled, right?
It make sense, I will give it a try.
Quoted 7 lines
Regards,
Joerg
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Thanks,
Jacob
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Joerg Roedel
maintainerRe: [PATCH 1/2] iommu/vt-d: Fix PCI bus rescan device hot add
Quoted 3 lines · Jacob Pan
Do you mean having an IRQ remapping notifier regardless IOMMU-API is enabled, right?
It make sense, I will give it a try.
Yeah, that would be best. I really don't like to use two notifiers just to work around ordering issues.
Regards,
Joerg
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 1/2] iommu/vt-d: Fix PCI bus rescan device hot add
Hi Joerg,
Quoted 8 lines · Joerg Roedel
Quoted 3 lines · Jacob Pan
Do you mean having an IRQ remapping notifier regardless IOMMU-API is enabled, right?
It make sense, I will give it a try.Yeah, that would be best. I really don't like to use two notifiers just to work around ordering issues.
Another option Ashok and I discussed is that we can make DMAR cache persist (which should be for explicitly listed devices in each DRHD) across PCI remove-rescan cycle, then we don't need the DMAR PCI bus notifier at all.
This bug only impacts RCIEP device hotplug, which is not the most reasonable use case, we have the space to look into a proper fix.
Quoted 3 lines
Regards,
Joerg
Thanks,
Jacob
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Joerg Roedel
maintainerRe: [PATCH 1/2] iommu/vt-d: Fix PCI bus rescan device hot add
Hi Jacob,
Quoted 6 lines · Jacob Pan
Another option Ashok and I discussed is that we can make DMAR cache persist (which should be for explicitly listed devices in each DRHD) across PCI remove-rescan cycle, then we don't need the DMAR PCI bus notifier at all.
This bug only impacts RCIEP device hotplug, which is not the most reasonable use case, we have the space to look into a proper fix.
Even better if you can make the notifier obsolete. Looking forward to the fix.
Regards,
Joerg
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 1/2] iommu/vt-d: Fix PCI bus rescan device hot add
In reply to Joerg RoedelHi Joerg,
Quoted 11 lines · Joerg Roedel
Hi Jacob, Baolu,
Quoted 7 lines · Lu Baolu
During PCI bus rescan, adding new devices involve two notifiers.
1.dmar_pci_bus_notifier()
2.iommu_bus_notifier()
The current code sets #1 as low priority (INT_MIN) which resulted in #2 being invoked first. The result is that struct device pointer cannot be found in DRHD search for the new device's DMAR/IOMMU. Subsequently, the device is put under the "catch-all" IOMMU instead of the correct one.
Quoted 4 lines
There are actually
iommu_opspointers invoked fromiommu_bus_notifier()into IOMMU driver code. Can those be used to enforce the ordering in a more reliable way?
The race condition is between PCI/ACPI and IOMMU subsystems, I don't see how having IOMMU internal ops can solve the external race. Perhaps we should merge into one notifier to have direct control of the ordering, is that what you are suggesting? It seems to be a good albeit larger clean-up I can look into.
Thanks,
Jacob
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu
Lu Baolu
maintainerPATCH 2/2 iommu/vt-d: Fix potential memory leak in intel_setup_irq_remapping()
In reply to Lu BaoluFrom: Guoqing Jiang <[email protected]>
After commit e3beca48a45b ("irqdomain/treewide: Keep firmware node unconditionally allocated"). For tear down scenario, fn is only freed after fail to allocate ir_domain, though it also should be freed in case dmar_enable_qi returns error.
Besides free fn, irq_domain and ir_msi_domain need to be removed as well if intel_setup_irq_remapping fails to enable queued invalidation.
Improve the rewinding path by add out_free_ir_domain and out_free_fwnode lables per Baolu's suggestion.
--- drivers/iommu/intel/irq_remapping.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/iommu/intel/irq_remapping.c +10 -3
@@ -569,9 +569,8 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu) fn, &intel_ir_domain_ops, iommu);if (!iommu->ir_domain) { -irq_domain_free_fwnode (fn);pr_err ("IR%d: failed to allocate irqdomain\n" , iommu->seq_id); - goto out_free_bitmap; + goto out_free_fwnode; } iommu->ir_msi_domain = arch_create_remap_msi_irq_domain(iommu->ir_domain,
@@ -595,7 +594,7 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu)if (dmar_enable_qi (iommu)) {pr_err ("Failed to enable queued invalidation\n" ); - goto out_free_bitmap; + goto out_free_ir_domain; } }
@@ -619,6 +618,14 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu)return 0 ; +out_free_ir_domain: +if (iommu->ir_msi_domain) +irq_domain_remove (iommu->ir_msi_domain); + iommu->ir_msi_domain =NULL ; +irq_domain_remove (iommu->ir_domain); + iommu->ir_domain =NULL ; +out_free_fwnode: +irq_domain_free_fwnode (fn); out_free_bitmap:bitmap_free (bitmap); out_free_pages:
Signature · 6 lines
2.25.1 _______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 2/2] iommu/vt-d: Fix potential memory leak in intel_setup_irq_remapping()
Quoted 13 lines · Lu Baolu
From: Guoqing Jiang <[email protected]>
After commit
e3beca48a45b("irqdomain/treewide: Keep firmware node unconditionally allocated"). For tear down scenario, fn is only freed after fail to allocateir_domain, though it also should be freed in casedmar_enable_qireturns error.Besides free fn,
irq_domainandir_msi_domainneed to be removed as well ifintel_setup_irq_remappingfails to enable queued invalidation.Improve the rewinding path by add
out_free_ir_domainandout_free_fwnodelables per Baolu's suggestion.
Quoted 8 lines
Fixes e3beca48a45b ("irqdomain/treewide: Keep firmware node unconditionally allocated")Suggested-by Lu Baolu <[email protected]>Signed-off-by Guoqing Jiang <[email protected]>Signed-off-by Lu Baolu <[email protected]>--- drivers/iommu/intel/irq_remapping.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
Applied this one, thanks.
_______________________________________________
iommu mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/iommu