diff mbox series

[v5,03/10] AMD/IOMMU: don't free shared IRT multiple times

Message ID e8869ce1-afad-c5d1-9f44-2f00384bdb57@suse.com (mailing list archive)
State New, archived
Headers show
Series [v5,01/10] AMD/IOMMU: miscellaneous DTE handling adjustments | expand

Commit Message

Jan Beulich Aug. 6, 2019, 1:08 p.m. UTC
Calling amd_iommu_free_intremap_table() for every IVRS entry is correct
only in per-device-IRT mode. Use a NULL 2nd argument to indicate that
the shared table should be freed, and call the function exactly once in
shared mode.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
v5: New.

Comments

Andrew Cooper Sept. 17, 2019, 12:42 p.m. UTC | #1
On 06/08/2019 14:08, Jan Beulich wrote:
> Calling amd_iommu_free_intremap_table() for every IVRS entry is correct
> only in per-device-IRT mode. Use a NULL 2nd argument to indicate that
> the shared table should be freed, and call the function exactly once in
> shared mode.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>

Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
diff mbox series

Patch

--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -1106,6 +1106,15 @@  static void __init amd_iommu_init_cleanu
  {
      struct amd_iommu *iommu, *next;
  
+    /* free interrupt remapping table */
+    if ( amd_iommu_perdev_intremap )
+        iterate_ivrs_entries(amd_iommu_free_intremap_table);
+    else if ( shared_intremap_table )
+        amd_iommu_free_intremap_table(list_first_entry(&amd_iommu_head,
+                                                       struct amd_iommu,
+                                                       list),
+                                      NULL);
+
      /* free amd iommu list */
      list_for_each_entry_safe ( iommu, next, &amd_iommu_head, list )
      {
@@ -1128,9 +1137,6 @@  static void __init amd_iommu_init_cleanu
          xfree(iommu);
      }
  
-    /* free interrupt remapping table */
-    iterate_ivrs_entries(amd_iommu_free_intremap_table);
-
      /* free device table */
      deallocate_device_table(&device_table);
  
--- a/xen/drivers/passthrough/amd/iommu_intr.c
+++ b/xen/drivers/passthrough/amd/iommu_intr.c
@@ -792,14 +792,23 @@  void amd_iommu_read_msi_from_ire(
  int __init amd_iommu_free_intremap_table(
      const struct amd_iommu *iommu, struct ivrs_mappings *ivrs_mapping)
  {
-    void *tb = ivrs_mapping->intremap_table;
+    void **tblp;
  
-    XFREE(ivrs_mapping->intremap_inuse);
+    if ( ivrs_mapping )
+    {
+        XFREE(ivrs_mapping->intremap_inuse);
+        tblp = &ivrs_mapping->intremap_table;
+    }
+    else
+    {
+        XFREE(shared_intremap_inuse);
+        tblp = &shared_intremap_table;
+    }
  
-    if ( tb )
+    if ( *tblp )
      {
-        __free_amd_iommu_tables(tb, intremap_table_order(iommu));
-        ivrs_mapping->intremap_table = NULL;
+        __free_amd_iommu_tables(*tblp, intremap_table_order(iommu));
+        *tblp = NULL;
      }
  
      return 0;