-From c98f5e59e41062856eee569dc3273a8842204f3d Mon Sep 17 00:00:00 2001
+From b8fa99c8234efcb5289dc6f37784fbb4dba6ad05 Mon Sep 17 00:00:00 2001
From: Sasha Levin <sashal@kernel.org>
Date: Thu, 9 May 2024 08:42:20 +0800
Subject: iommu/amd: Fix sysfs leak in iommu init
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- drivers/iommu/amd_iommu_init.c | 9 +++++++++
+ drivers/iommu/amd_iommu_init.c | 9 +++++++++
1 file changed, 9 insertions(+)
-diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
-index 7fb2a5e857b22..ff2d87422595e 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
-@@ -1460,8 +1460,17 @@ static void __init free_pci_segments(void)
- }
+@@ -1409,8 +1409,17 @@ static int __init init_iommu_from_acpi(s
+ return 0;
}
+static void __init free_sysfs(struct amd_iommu *iommu)
static void __init free_iommu_one(struct amd_iommu *iommu)
{
+ free_sysfs(iommu);
- free_cwwb_sem(iommu);
free_command_buffer(iommu);
free_event_buffer(iommu);
---
-2.43.0
-
+ free_ppr_log(iommu);
+++ /dev/null
-From fea787c736dbcda687f5abc30859dc542d730eb8 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 Jul 2022 17:07:52 +0530
-Subject: iommu/amd: Introduce pci segment structure
-
-From: Vasant Hegde <vasant.hegde@amd.com>
-
-[ Upstream commit 404ec4e4c169fb64da6b2a38b471c13ac0897c76 ]
-
-Newer AMD systems can support multiple PCI segments, where each segment
-contains one or more IOMMU instances. However, an IOMMU instance can only
-support a single PCI segment.
-
-Current code assumes that system contains only one pci segment (segment 0)
-and creates global data structures such as device table, rlookup table,
-etc.
-
-Introducing per PCI segment data structure, which contains segment
-specific data structures. This will eventually replace the global
-data structures.
-
-Also update `amd_iommu->pci_seg` variable to point to PCI segment
-structure instead of PCI segment ID.
-
-Co-developed-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
-Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
-Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
-Link: https://lore.kernel.org/r/20220706113825.25582-3-vasant.hegde@amd.com
-Signed-off-by: Joerg Roedel <jroedel@suse.de>
-Stable-dep-of: a295ec52c862 ("iommu/amd: Fix sysfs leak in iommu init")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/iommu/amd_iommu_init.c | 46 ++++++++++++++++++++++++++++++++-
- drivers/iommu/amd_iommu_types.h | 24 ++++++++++++++++-
- 2 files changed, 68 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
-index a9190491f9c3d..7fb2a5e857b22 100644
---- a/drivers/iommu/amd_iommu_init.c
-+++ b/drivers/iommu/amd_iommu_init.c
-@@ -167,6 +167,7 @@ LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings
- we find in ACPI */
- bool amd_iommu_unmap_flush; /* if true, flush on every unmap */
-
-+LIST_HEAD(amd_iommu_pci_seg_list); /* list of all PCI segments */
- LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the
- system */
-
-@@ -1422,6 +1423,43 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
- return 0;
- }
-
-+/* Allocate PCI segment data structure */
-+static struct amd_iommu_pci_seg *__init alloc_pci_segment(u16 id)
-+{
-+ struct amd_iommu_pci_seg *pci_seg;
-+
-+ pci_seg = kzalloc(sizeof(struct amd_iommu_pci_seg), GFP_KERNEL);
-+ if (pci_seg == NULL)
-+ return NULL;
-+
-+ pci_seg->id = id;
-+ list_add_tail(&pci_seg->list, &amd_iommu_pci_seg_list);
-+
-+ return pci_seg;
-+}
-+
-+static struct amd_iommu_pci_seg *__init get_pci_segment(u16 id)
-+{
-+ struct amd_iommu_pci_seg *pci_seg;
-+
-+ for_each_pci_segment(pci_seg) {
-+ if (pci_seg->id == id)
-+ return pci_seg;
-+ }
-+
-+ return alloc_pci_segment(id);
-+}
-+
-+static void __init free_pci_segments(void)
-+{
-+ struct amd_iommu_pci_seg *pci_seg, *next;
-+
-+ for_each_pci_segment_safe(pci_seg, next) {
-+ list_del(&pci_seg->list);
-+ kfree(pci_seg);
-+ }
-+}
-+
- static void __init free_iommu_one(struct amd_iommu *iommu)
- {
- free_cwwb_sem(iommu);
-@@ -1510,8 +1548,14 @@ static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu)
- */
- static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
- {
-+ struct amd_iommu_pci_seg *pci_seg;
- int ret;
-
-+ pci_seg = get_pci_segment(h->pci_seg);
-+ if (pci_seg == NULL)
-+ return -ENOMEM;
-+ iommu->pci_seg = pci_seg;
-+
- raw_spin_lock_init(&iommu->lock);
- iommu->cmd_sem_val = 0;
-
-@@ -1532,7 +1576,6 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
- */
- iommu->devid = h->devid;
- iommu->cap_ptr = h->cap_ptr;
-- iommu->pci_seg = h->pci_seg;
- iommu->mmio_phys = h->mmio_phys;
-
- switch (h->type) {
-@@ -2361,6 +2404,7 @@ static void __init free_iommu_resources(void)
- amd_iommu_dev_table = NULL;
-
- free_iommu_all();
-+ free_pci_segments();
- }
-
- /* SB IOAPIC is always on this device in AMD systems */
-diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
-index af95dfc28870b..27e8c9d110da4 100644
---- a/drivers/iommu/amd_iommu_types.h
-+++ b/drivers/iommu/amd_iommu_types.h
-@@ -431,6 +431,11 @@ extern bool amd_iommu_irq_remap;
- /* kmem_cache to get tables with 128 byte alignement */
- extern struct kmem_cache *amd_iommu_irq_cache;
-
-+/* Make iterating over all pci segment easier */
-+#define for_each_pci_segment(pci_seg) \
-+ list_for_each_entry((pci_seg), &amd_iommu_pci_seg_list, list)
-+#define for_each_pci_segment_safe(pci_seg, next) \
-+ list_for_each_entry_safe((pci_seg), (next), &amd_iommu_pci_seg_list, list)
- /*
- * Make iterating over all IOMMUs easier
- */
-@@ -488,6 +493,17 @@ struct protection_domain {
- unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
- };
-
-+/*
-+ * This structure contains information about one PCI segment in the system.
-+ */
-+struct amd_iommu_pci_seg {
-+ /* List with all PCI segments in the system */
-+ struct list_head list;
-+
-+ /* PCI segment number */
-+ u16 id;
-+};
-+
- /*
- * Structure where we save information about one hardware AMD IOMMU in the
- * system.
-@@ -539,7 +555,7 @@ struct amd_iommu {
- u16 cap_ptr;
-
- /* pci domain of this IOMMU */
-- u16 pci_seg;
-+ struct amd_iommu_pci_seg *pci_seg;
-
- /* start of exclusion range of that IOMMU */
- u64 exclusion_start;
-@@ -666,6 +682,12 @@ extern struct list_head ioapic_map;
- extern struct list_head hpet_map;
- extern struct list_head acpihid_map;
-
-+/*
-+ * List with all PCI segments in the system. This list is not locked because
-+ * it is only written at driver initialization time
-+ */
-+extern struct list_head amd_iommu_pci_seg_list;
-+
- /*
- * List with all IOMMUs in the system. This list is not locked because it is
- * only written and read at driver initialization or suspend time
---
-2.43.0
-
+++ /dev/null
-From a0728242b8666a9c83ea289e2e91620bc6546a01 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 12 Jun 2019 14:52:04 -0700
-Subject: iommu/amd: Move gart fallback to amd_iommu_init
-
-From: Kevin Mitchell <kevmitch@arista.com>
-
-[ Upstream commit bf4bff46eac151c3fd299741d71c4216e45b5d8b ]
-
-The fallback to the GART driver in the case amd_iommu doesn't work was
-executed in a function called free_iommu_resources, which didn't really
-make sense. This was even being called twice if amd_iommu=off was
-specified on the command line.
-
-The only complication is that it needs to be verified that amd_iommu has
-fully relinquished control by calling free_iommu_resources and emptying
-the amd_iommu_list.
-
-Signed-off-by: Kevin Mitchell <kevmitch@arista.com>
-Signed-off-by: Joerg Roedel <jroedel@suse.de>
-Stable-dep-of: a295ec52c862 ("iommu/amd: Fix sysfs leak in iommu init")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/iommu/amd_iommu_init.c | 19 ++++++++++---------
- 1 file changed, 10 insertions(+), 9 deletions(-)
-
-diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
-index efb11ca91dd72..05726f73a859f 100644
---- a/drivers/iommu/amd_iommu_init.c
-+++ b/drivers/iommu/amd_iommu_init.c
-@@ -2343,15 +2343,6 @@ static void __init free_iommu_resources(void)
- amd_iommu_dev_table = NULL;
-
- free_iommu_all();
--
--#ifdef CONFIG_GART_IOMMU
-- /*
-- * We failed to initialize the AMD IOMMU - try fallback to GART
-- * if possible.
-- */
-- gart_iommu_init();
--
--#endif
- }
-
- /* SB IOAPIC is always on this device in AMD systems */
-@@ -2772,6 +2763,16 @@ static int __init amd_iommu_init(void)
- }
- }
-
-+#ifdef CONFIG_GART_IOMMU
-+ if (ret && list_empty(&amd_iommu_list)) {
-+ /*
-+ * We failed to initialize the AMD IOMMU - try fallback
-+ * to GART if possible.
-+ */
-+ gart_iommu_init();
-+ }
-+#endif
-+
- for_each_iommu(iommu)
- amd_iommu_debugfs_setup(iommu);
-
---
-2.43.0
-
+++ /dev/null
-From c249a884850d743ccb851f4b7a6aaceff31adab0 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 23 Sep 2020 12:13:45 +0000
-Subject: iommu/amd: Use 4K page for completion wait write-back semaphore
-
-From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
-
-[ Upstream commit c69d89aff393a212b9635c95990173b48d8bd74d ]
-
-IOMMU SNP support requires the completion wait write-back semaphore to be
-implemented using a 4K-aligned page, where the page address is to be
-programmed into the newly introduced MMIO base/range registers.
-
-This new scheme uses a per-iommu atomic variable to store the current
-semaphore value, which is incremented for every completion wait command.
-
-Since this new scheme is also compatible with non-SNP mode,
-generalize the driver to use 4K page for completion-wait semaphore in
-both modes.
-
-Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
-Cc: Brijesh Singh <brijesh.singh@amd.com>
-Link: https://lore.kernel.org/r/20200923121347.25365-2-suravee.suthikulpanit@amd.com
-Signed-off-by: Joerg Roedel <jroedel@suse.de>
-Stable-dep-of: a295ec52c862 ("iommu/amd: Fix sysfs leak in iommu init")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/iommu/amd_iommu.c | 23 +++++++++++------------
- drivers/iommu/amd_iommu_init.c | 18 ++++++++++++++++++
- drivers/iommu/amd_iommu_types.h | 3 ++-
- 3 files changed, 31 insertions(+), 13 deletions(-)
-
-diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
-index 5d5941aca16ad..e512dfa0e0924 100644
---- a/drivers/iommu/amd_iommu.c
-+++ b/drivers/iommu/amd_iommu.c
-@@ -843,11 +843,11 @@ irqreturn_t amd_iommu_int_handler(int irq, void *data)
- *
- ****************************************************************************/
-
--static int wait_on_sem(volatile u64 *sem)
-+static int wait_on_sem(struct amd_iommu *iommu, u64 data)
- {
- int i = 0;
-
-- while (*sem == 0 && i < LOOP_TIMEOUT) {
-+ while (*iommu->cmd_sem != data && i < LOOP_TIMEOUT) {
- udelay(1);
- i += 1;
- }
-@@ -877,16 +877,16 @@ static void copy_cmd_to_buffer(struct amd_iommu *iommu,
- writel(iommu->cmd_buf_tail, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
- }
-
--static void build_completion_wait(struct iommu_cmd *cmd, u64 address)
-+static void build_completion_wait(struct iommu_cmd *cmd,
-+ struct amd_iommu *iommu,
-+ u64 data)
- {
-- u64 paddr = iommu_virt_to_phys((void *)address);
--
-- WARN_ON(address & 0x7ULL);
-+ u64 paddr = iommu_virt_to_phys((void *)iommu->cmd_sem);
-
- memset(cmd, 0, sizeof(*cmd));
- cmd->data[0] = lower_32_bits(paddr) | CMD_COMPL_WAIT_STORE_MASK;
- cmd->data[1] = upper_32_bits(paddr);
-- cmd->data[2] = 1;
-+ cmd->data[2] = data;
- CMD_SET_TYPE(cmd, CMD_COMPL_WAIT);
- }
-
-@@ -1095,22 +1095,21 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
- struct iommu_cmd cmd;
- unsigned long flags;
- int ret;
-+ u64 data;
-
- if (!iommu->need_sync)
- return 0;
-
--
-- build_completion_wait(&cmd, (u64)&iommu->cmd_sem);
--
- raw_spin_lock_irqsave(&iommu->lock, flags);
-
-- iommu->cmd_sem = 0;
-+ data = ++iommu->cmd_sem_val;
-+ build_completion_wait(&cmd, iommu, data);
-
- ret = __iommu_queue_command_sync(iommu, &cmd, false);
- if (ret)
- goto out_unlock;
-
-- ret = wait_on_sem(&iommu->cmd_sem);
-+ ret = wait_on_sem(iommu, data);
-
- out_unlock:
- raw_spin_unlock_irqrestore(&iommu->lock, flags);
-diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
-index 05726f73a859f..a9190491f9c3d 100644
---- a/drivers/iommu/amd_iommu_init.c
-+++ b/drivers/iommu/amd_iommu_init.c
-@@ -835,6 +835,19 @@ static int iommu_init_ga(struct amd_iommu *iommu)
- return ret;
- }
-
-+static int __init alloc_cwwb_sem(struct amd_iommu *iommu)
-+{
-+ iommu->cmd_sem = (void *)get_zeroed_page(GFP_KERNEL);
-+
-+ return iommu->cmd_sem ? 0 : -ENOMEM;
-+}
-+
-+static void __init free_cwwb_sem(struct amd_iommu *iommu)
-+{
-+ if (iommu->cmd_sem)
-+ free_page((unsigned long)iommu->cmd_sem);
-+}
-+
- static void iommu_enable_xt(struct amd_iommu *iommu)
- {
- #ifdef CONFIG_IRQ_REMAP
-@@ -1411,6 +1424,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
-
- static void __init free_iommu_one(struct amd_iommu *iommu)
- {
-+ free_cwwb_sem(iommu);
- free_command_buffer(iommu);
- free_event_buffer(iommu);
- free_ppr_log(iommu);
-@@ -1499,6 +1513,7 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
- int ret;
-
- raw_spin_lock_init(&iommu->lock);
-+ iommu->cmd_sem_val = 0;
-
- /* Add IOMMU to internal data structures */
- list_add_tail(&iommu->list, &amd_iommu_list);
-@@ -1554,6 +1569,9 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
- if (!iommu->mmio_base)
- return -ENOMEM;
-
-+ if (alloc_cwwb_sem(iommu))
-+ return -ENOMEM;
-+
- if (alloc_command_buffer(iommu))
- return -ENOMEM;
-
-diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
-index 0948c425d6528..af95dfc28870b 100644
---- a/drivers/iommu/amd_iommu_types.h
-+++ b/drivers/iommu/amd_iommu_types.h
-@@ -601,7 +601,8 @@ struct amd_iommu {
- #endif
-
- u32 flags;
-- volatile u64 __aligned(8) cmd_sem;
-+ volatile u64 *cmd_sem;
-+ u64 cmd_sem_val;
-
- #ifdef CONFIG_AMD_IOMMU_DEBUGFS
- /* DebugFS Info */
---
-2.43.0
-
input-try-trimming-too-long-modalias-strings.patch
xsk-validate-user-input-for-xdp_-umem-completion-_fill_ring.patch
hid-core-remove-unnecessary-warn_on-in-implement.patch
-iommu-amd-move-gart-fallback-to-amd_iommu_init.patch
-iommu-amd-use-4k-page-for-completion-wait-write-back.patch
-iommu-amd-introduce-pci-segment-structure.patch
iommu-amd-fix-sysfs-leak-in-iommu-init.patch
liquidio-adjust-a-null-pointer-handling-path-in-lio_.patch
drm-bridge-panel-fix-runtime-warning-on-panel-bridge.patch