diff options
| author | Alejandro Jimenez <alejandro.j.jimenez@oracle.com> | 2025-09-19 21:35:06 +0000 |
|---|---|---|
| committer | Michael S. Tsirkin <mst@redhat.com> | 2025-10-05 16:13:01 -0400 |
| commit | 1221c4a44902ed6162b06b30b7fcc245c39c2006 (patch) | |
| tree | f1f0a756ea4212301c47a1f60f6551271140af16 | |
| parent | 63e39ec114d51c15f2b76709e874bef5bbd413cb (diff) | |
| download | focaccia-qemu-1221c4a44902ed6162b06b30b7fcc245c39c2006.tar.gz focaccia-qemu-1221c4a44902ed6162b06b30b7fcc245c39c2006.zip | |
amd_iommu: Add replay callback
A replay() method is necessary to efficiently synchronize the host page tables after VFIO registers a notifier for IOMMU events. It is called to ensure that existing mappings from an IOMMU memory region are "replayed" to a specified notifier, initializing or updating the shadow page tables on the host. Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Message-ID: <20250919213515.917111-14-alejandro.j.jimenez@oracle.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
| -rw-r--r-- | hw/i386/amd_iommu.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index 497f18c540..9027f7c054 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -918,6 +918,29 @@ static void amdvi_address_space_unmap_all(AMDVIState *s) } } +/* + * For every translation present in the IOMMU, construct IOMMUTLBEntry data + * and pass it as parameter to notifier callback. + */ +static void amdvi_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n) +{ + AMDVIAddressSpace *as = container_of(iommu_mr, AMDVIAddressSpace, iommu); + uint64_t dte[4] = { 0 }; + + if (!(n->notifier_flags & IOMMU_NOTIFIER_MAP)) { + return; + } + + if (amdvi_as_to_dte(as, dte)) { + return; + } + + /* Dropping all mappings for the address space. Also clears the IOVA tree */ + amdvi_address_space_unmap(as, n); + + amdvi_sync_shadow_page_table_range(as, &dte[0], 0, UINT64_MAX, false); +} + /* log error without aborting since linux seems to be using reserved bits */ static void amdvi_inval_devtab_entry(AMDVIState *s, uint64_t *cmd) { @@ -2364,6 +2387,7 @@ static void amdvi_iommu_memory_region_class_init(ObjectClass *klass, imrc->translate = amdvi_translate; imrc->notify_flag_changed = amdvi_iommu_notify_flag_changed; + imrc->replay = amdvi_iommu_replay; } static const TypeInfo amdvi_iommu_memory_region_info = { |