Date: Sat, 08 Aug 2026 07:22:53 +0000 From: Kevin Bowling <kbowling@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 42d54a8fd466 - main - vmm: Tear down the IOMMU before AMD-Vi detach Message-ID: <6a76d94d.428b0.788486bd@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=42d54a8fd4665b97f56f91f450e310c61d4aee2c commit 42d54a8fd4665b97f56f91f450e310c61d4aee2c Author: Kevin Bowling <kbowling@FreeBSD.org> AuthorDate: 2026-08-06 11:06:00 +0000 Commit: Kevin Bowling <kbowling@FreeBSD.org> CommitDate: 2026-08-08 07:22:48 +0000 vmm: Tear down the IOMMU before AMD-Vi detach Register the vmm module handler after both the bundled device drivers and SMP. On platforms without EARLY_AP_STARTUP, SI_SUB_SMP follows SI_SUB_DRIVERS; using the later subsystem preserves the smp_rendezvous() requirement. The resulting reverse unload order performs IOMMU cleanup while every IVHD softc remains valid. Refuse an independent IVHD detach while translation state remains initialized. MFC after: 2 weeks --- sys/amd64/vmm/amd/ivrs_drv.c | 14 +++++++++----- sys/amd64/vmm/io/iommu.c | 12 ++++++++++-- sys/amd64/vmm/io/iommu.h | 1 + sys/dev/vmm/vmm_dev.c | 10 ++++++++-- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/sys/amd64/vmm/amd/ivrs_drv.c b/sys/amd64/vmm/amd/ivrs_drv.c index 85171a5d51be..125c49839d9f 100644 --- a/sys/amd64/vmm/amd/ivrs_drv.c +++ b/sys/amd64/vmm/amd/ivrs_drv.c @@ -711,15 +711,19 @@ ivhd_detach(device_t dev) { struct amdvi_softc *softc; + /* + * amdvi_disable() and domain teardown require every IVHD softc. The + * vmm module handler normally performs that cleanup before the IVHD + * driver is unloaded. Refuse an out-of-order detach rather than leave + * enabled translation hardware referring to resources freed below. + */ + if (iommu_is_initialized()) + return (EBUSY); + softc = device_get_softc(dev); amdvi_teardown_hw(softc); free(softc->dev_cfg, M_DEVBUF); - - /* - * XXX: delete the device. - * don't allow detach, return EBUSY. - */ return (0); } diff --git a/sys/amd64/vmm/io/iommu.c b/sys/amd64/vmm/io/iommu.c index 9fc612244699..71d3cb9ab883 100644 --- a/sys/amd64/vmm/io/iommu.c +++ b/sys/amd64/vmm/io/iommu.c @@ -194,7 +194,7 @@ iommu_init(void) if (error) return; - iommu_avail = 1; + atomic_store_rel_int(&iommu_avail, 1); /* * Create a domain for the devices owned by the host @@ -205,7 +205,7 @@ iommu_init(void) printf("iommu_init: unable to create a host domain"); IOMMU_CLEANUP(); ops = NULL; - iommu_avail = 0; + atomic_store_rel_int(&iommu_avail, 0); return; } @@ -268,6 +268,7 @@ iommu_cleanup_int(bool iommu_disable) IOMMU_DESTROY_DOMAIN(host_domain); host_domain = NULL; IOMMU_CLEANUP(); + atomic_store_rel_int(&iommu_avail, 0); } void @@ -276,6 +277,13 @@ iommu_cleanup(void) iommu_cleanup_int(true); } +bool +iommu_is_initialized(void) +{ + + return (atomic_load_acq_int(&iommu_avail) != 0); +} + void * iommu_create_domain(vm_paddr_t maxaddr) { diff --git a/sys/amd64/vmm/io/iommu.h b/sys/amd64/vmm/io/iommu.h index 5294a9d92a6b..3224b4884e9a 100644 --- a/sys/amd64/vmm/io/iommu.h +++ b/sys/amd64/vmm/io/iommu.h @@ -62,6 +62,7 @@ extern const struct iommu_ops iommu_ops_intel; extern const struct iommu_ops iommu_ops_amd; void iommu_cleanup(void); +bool iommu_is_initialized(void); void *iommu_host_domain(void); void *iommu_create_domain(vm_paddr_t maxaddr); void iommu_destroy_domain(void *dom); diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c index a2775023838a..21cbd06ae2d0 100644 --- a/sys/dev/vmm/vmm_dev.c +++ b/sys/dev/vmm/vmm_dev.c @@ -1301,9 +1301,15 @@ static moduledata_t vmm_kmod = { * * - Initialization requires smp_rendezvous() and therefore must happen * after SMP is fully functional (after SI_SUB_SMP). - * - vmm device initialization requires an initialized devfs. + * - vmm device initialization requires an initialized devfs + * (SI_SUB_DRIVERS is after SI_SUB_DEVFS). + * - On amd64, vmm.ko also contains device drivers such as ppt and AMD-Vi/IVHD. + * Load this module handler after SI_SUB_DRIVERS so reverse-order unload runs + * iommu_cleanup() before those drivers detach. AMD-Vi disable still needs + * the IVHD softcs, and ivhd_detach() refuses while the IOMMU is initialized. */ -DECLARE_MODULE(vmm, vmm_kmod, MAX(SI_SUB_SMP, SI_SUB_DEVFS) + 1, SI_ORDER_ANY); +DECLARE_MODULE(vmm, vmm_kmod, MAX(SI_SUB_DRIVERS, SI_SUB_SMP) + 1, + SI_ORDER_ANY); MODULE_VERSION(vmm, 1); static inthome | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a76d94d.428b0.788486bd>
