[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 12/20] amd_iommu: Unmap all address spaces under the AMD IOMMU
From: |
Alejandro Jimenez |
Subject: |
[PATCH v2 12/20] amd_iommu: Unmap all address spaces under the AMD IOMMU on reset |
Date: |
Fri, 2 May 2025 02:15:57 +0000 |
Support dropping all existing mappings on reset. When the guest kernel
reboots it will create new ones, but other components that run before
the kernel (e.g. OVMF) should not be able to use existing mappings from
the previous boot.
Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
---
hw/i386/amd_iommu.c | 74 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index 4f44ef159ff9..7bcba47a01ba 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -808,6 +808,77 @@ next:
}
}
+/*
+ * Unmap entire range that the notifier registered for i.e. the full AS.
+ *
+ * This is seemingly technically equivalent to directly calling
+ * memory_region_unmap_iommu_notifier_range(), but it allows to check for
+ * notifier boundaries and issue notifications with ranges within those bounds.
+ */
+static void amdvi_address_space_unmap(AMDVIAddressSpace *as, IOMMUNotifier *n)
+{
+
+ hwaddr start = n->start;
+ hwaddr end = n->end;
+ hwaddr remain;
+ DMAMap map;
+
+ assert(start <= end);
+ remain = end - start + 1;
+
+ /*
+ * Divide the notifier range into chunks that are aligned and do not exceed
+ * the notifier boundaries.
+ */
+ while (remain >= AMDVI_PAGE_SIZE) {
+
+ IOMMUTLBEvent event;
+
+ uint64_t mask = dma_aligned_pow2_mask(start, end, 64);
+
+ event.type = IOMMU_NOTIFIER_UNMAP;
+
+ IOMMUTLBEntry entry = {
+ .target_as = &address_space_memory,
+ .iova = start,
+ .translated_addr = 0, /* irrelevant for unmap case */
+ .addr_mask = mask,
+ .perm = IOMMU_NONE,
+ };
+ event.entry = entry;
+
+ /* Call notifier registered for updates on this address space */
+ memory_region_notify_iommu_one(n, &event);
+
+ start += mask + 1;
+ remain -= mask + 1;
+ }
+
+ assert(!remain);
+
+ map.iova = n->start;
+ map.size = n->end - n->start;
+
+ iova_tree_remove(as->iova_tree, map);
+}
+
+/*
+ * For all the address spaces with notifiers registered, unmap the entire range
+ * the notifier registered for i.e. clear all the address spaces managed by the
+ * IOMMU.
+ */
+static void amdvi_address_space_unmap_all(AMDVIState *s)
+{
+ AMDVIAddressSpace *as;
+ IOMMUNotifier *n;
+
+ QLIST_FOREACH(as, &s->amdvi_as_with_notifiers, next) {
+ IOMMU_NOTIFIER_FOREACH(n, &as->iommu) {
+ amdvi_address_space_unmap(as, n);
+ }
+ }
+}
+
/* log error without aborting since linux seems to be using reserved bits */
static void amdvi_inval_devtab_entry(AMDVIState *s, uint64_t *cmd)
{
@@ -2043,6 +2114,9 @@ static void amdvi_sysbus_reset(DeviceState *dev)
msi_reset(&s->pci.dev);
amdvi_init(s);
+
+ /* Discard all mappings on device reset */
+ amdvi_address_space_unmap_all(s);
}
static void amdvi_sysbus_realize(DeviceState *dev, Error **errp)
--
2.43.5
- [PATCH v2 02/20] amd_iommu: Document '-device amd-iommu' common options, (continued)
- [PATCH v2 02/20] amd_iommu: Document '-device amd-iommu' common options, Alejandro Jimenez, 2025/05/01
- [PATCH v2 03/20] amd_iommu: Reorder device and page table helpers, Alejandro Jimenez, 2025/05/01
- [PATCH v2 06/20] amd_iommu: Return an error when unable to read PTE from guest memory, Alejandro Jimenez, 2025/05/01
- [PATCH v2 05/20] amd_iommu: Add helper function to extract the DTE, Alejandro Jimenez, 2025/05/01
- [PATCH v2 04/20] amd_iommu: Helper to decode size of page invalidation command, Alejandro Jimenez, 2025/05/01
- [PATCH v2 10/20] amd_iommu: Sync shadow page tables on page invalidation, Alejandro Jimenez, 2025/05/01
- [PATCH v2 17/20] amd_iommu: Add dma-remap property to AMD vIOMMU device, Alejandro Jimenez, 2025/05/01
- [PATCH v2 07/20] amd_iommu: Add helpers to walk AMD v1 Page Table format, Alejandro Jimenez, 2025/05/01
- [PATCH v2 12/20] amd_iommu: Unmap all address spaces under the AMD IOMMU on reset,
Alejandro Jimenez <=
- [PATCH v2 11/20] amd_iommu: Use iova_tree records to determine large page size on UNMAP, Alejandro Jimenez, 2025/05/01
- [PATCH v2 15/20] amd_iommu: Toggle memory regions based on address translation mode, Alejandro Jimenez, 2025/05/01
- [PATCH v2 08/20] amd_iommu: Add a page walker to sync shadow page tables on invalidation, Alejandro Jimenez, 2025/05/01
- [PATCH v2 19/20] amd_iommu: Do not assume passthrough translation when DTE[TV]=0, Alejandro Jimenez, 2025/05/01
- [PATCH v2 13/20] amd_iommu: Add replay callback, Alejandro Jimenez, 2025/05/01
- [PATCH v2 18/20] amd_iommu: Toggle address translation mode on devtab entry invalidation, Alejandro Jimenez, 2025/05/01