git: 45543d3424d4 - main - DMAR: clear dmar_devs[unit] if attach failed

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 21 Aug 2024 15:24:01 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=45543d3424d46f84a5399879e190fc359dcefbd4

commit 45543d3424d46f84a5399879e190fc359dcefbd4
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-08-20 14:41:33 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-08-21 15:23:07 +0000

    DMAR: clear dmar_devs[unit] if attach failed
    
    This should stop attempts to use a unit which was not completely
    initialized, but referenced by ACPI DMAR table during scoped devices
    operions.
    
    PR:     280817
    Sponsored by:   Advanced Micro Devices (AMD)
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D46382
---
 sys/x86/iommu/intel_drv.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/sys/x86/iommu/intel_drv.c b/sys/x86/iommu/intel_drv.c
index 0b25620114cd..636534173715 100644
--- a/sys/x86/iommu/intel_drv.c
+++ b/sys/x86/iommu/intel_drv.c
@@ -422,6 +422,7 @@ dmar_attach(device_t dev)
 	    &unit->reg_rid, RF_ACTIVE);
 	if (unit->regs == NULL) {
 		device_printf(dev, "cannot allocate register window\n");
+		dmar_devs[unit->iommu.unit] = NULL;
 		return (ENOMEM);
 	}
 	unit->hw_ver = dmar_read4(unit, DMAR_VER_REG);
@@ -449,6 +450,7 @@ dmar_attach(device_t dev)
 	error = dmar_alloc_irq(dev, unit, DMAR_INTR_FAULT);
 	if (error != 0) {
 		dmar_release_resources(dev, unit);
+		dmar_devs[unit->iommu.unit] = NULL;
 		return (error);
 	}
 	if (DMAR_HAS_QI(unit)) {
@@ -463,6 +465,7 @@ dmar_attach(device_t dev)
 		error = dmar_alloc_irq(dev, unit, DMAR_INTR_QI);
 		if (error != 0) {
 			dmar_release_resources(dev, unit);
+			dmar_devs[unit->iommu.unit] = NULL;
 			return (error);
 		}
 	}
@@ -496,12 +499,14 @@ dmar_attach(device_t dev)
 	if (error != 0) {
 		DMAR_UNLOCK(unit);
 		dmar_release_resources(dev, unit);
+		dmar_devs[unit->iommu.unit] = NULL;
 		return (error);
 	}
 	error = dmar_inv_ctx_glob(unit);
 	if (error != 0) {
 		DMAR_UNLOCK(unit);
 		dmar_release_resources(dev, unit);
+		dmar_devs[unit->iommu.unit] = NULL;
 		return (error);
 	}
 	if ((unit->hw_ecap & DMAR_ECAP_DI) != 0) {
@@ -509,6 +514,7 @@ dmar_attach(device_t dev)
 		if (error != 0) {
 			DMAR_UNLOCK(unit);
 			dmar_release_resources(dev, unit);
+			dmar_devs[unit->iommu.unit] = NULL;
 			return (error);
 		}
 	}
@@ -517,16 +523,19 @@ dmar_attach(device_t dev)
 	error = dmar_init_fault_log(unit);
 	if (error != 0) {
 		dmar_release_resources(dev, unit);
+		dmar_devs[unit->iommu.unit] = NULL;
 		return (error);
 	}
 	error = dmar_init_qi(unit);
 	if (error != 0) {
 		dmar_release_resources(dev, unit);
+		dmar_devs[unit->iommu.unit] = NULL;
 		return (error);
 	}
 	error = dmar_init_irt(unit);
 	if (error != 0) {
 		dmar_release_resources(dev, unit);
+		dmar_devs[unit->iommu.unit] = NULL;
 		return (error);
 	}
 
@@ -542,6 +551,7 @@ dmar_attach(device_t dev)
 	error = iommu_init_busdma(&unit->iommu);
 	if (error != 0) {
 		dmar_release_resources(dev, unit);
+		dmar_devs[unit->iommu.unit] = NULL;
 		return (error);
 	}
 
@@ -551,6 +561,7 @@ dmar_attach(device_t dev)
 	if (error != 0) {
 		DMAR_UNLOCK(unit);
 		dmar_release_resources(dev, unit);
+		dmar_devs[unit->iommu.unit] = NULL;
 		return (error);
 	}
 	DMAR_UNLOCK(unit);