From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 57CEA3BD64B for ; Mon, 17 Aug 2026 20:28:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.72 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786998509; cv=none; b=LCzPWNhJ1Oi63zmHKOcEQJ8sxnus0FLxKShpumjuS4PABr+36WGxnf6WHUv06OzgCm5FqJz3geWhfIHZZaaMiPWvxaQBYcj/wpC3a3c1JAKZCbL8uMpJa3/jx/Was+XSWi4sVkr4astATT+fQtMMCiJDnqYUoCI+6yMchDSKY6A= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786998509; c=relaxed/simple; bh=aDxnhQ6FiqcrfRU/2/AckhUywVbzCjbMdykm/xY9l30=; h=Date:Mime-Version:Message-ID:Subject:From:To:Cc:Content-Type; b=gbkuoA/olTdmgfd4Z6+wAcqJ5y0IPCImizutVz3ZULIFG8UW5HEzMRp0cm+tikmdBJJL1DEeKMycuVRQrGap2NX1Oo7t2XDf7UhhaY4bFiwesaUcHqP3lCr0okvH4SwLKlhrRHdwB/jEYnsiSSQ1kio7UGdwoGwX0vqio+3Lcis= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=cJSORK4A; arc=none smtp.client-ip=209.85.216.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="cJSORK4A" Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-38e1118e4abso6230410a91.0 for ; Mon, 17 Aug 2026 13:28:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1786998508; x=1787603308; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:mime-version:date:from :to:cc:subject:date:message-id:reply-to:content-type; bh=GJW6PilJrU2i+SPmfb2uKwj6iYMQzDWi+W0fuzs5FQk=; b=cJSORK4ADjIukIbqclKWL+MkKyQ2Ko8+2HqR1TLGU+Sx8NIa8LscaIj6DnJjpRJV85 1MfLwKhGiH/5D8C6auDfpzjx1RilVn/W1tjQfOHstvDcSQ29aVH1v82b+lOsoaZadLPe mLVhjLaXsyoFkMOdUHzEt57WPlj2FvKXeU3/8tQIwOiP1ljmgqQGb66HvBxPCN8lTh/G iswD/7bp3Uzg57BE1rI2kszUB4X9g73n/8u7zm5TBkxeKGZUsOHFFdSazVCh3+M9fShy OZPpxAlMns6OCyhzUyMGOSIDuf/2rFmL0K5N+CEbNLvcTSbc9JS+PP5urHK6Nyh3G+AH AWtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786998508; x=1787603308; h=content-type:cc:to:from:subject:message-id:mime-version:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=GJW6PilJrU2i+SPmfb2uKwj6iYMQzDWi+W0fuzs5FQk=; b=LQWtmsKVSw6keNmacNPUf1uhGNKwg9jvClbM8aXCYrZFuoDXllyNQGJW9ynMOsoH8G EJc99v+mR7iWHzUuJjegaTlURGxNxSP6Kkv1xJ3UDYUoY2T7F/e6pUtUQhIHQpeRTOjb DjjzkWNmbkIyxnf+v4z0hBbYTd1l84mu3NoGaGwE9QyJPjZ9q6x7XdgC1Jx3P25pTN1K LRjsnTbpBSVWuWoD1yLBPvuag7vITvAcp5B4qJQDkaXPguKpmKkD6llSjVfF3q03KxT6 pRMK7lA5wF9amPFVA+D8vj1a5rtv+bHd7ijwlOK/KV8VARJ7jXI8mn761msmXzfi7rRp 5wkQ== X-Gm-Message-State: AOJu0YzjSfVUpnhTK4tQ9nT/vWR+K7tl0kR+5mbIPGfg7/eW7iEel4hF W6uGrFVHcLH4BQJhBW3R6pEHfk+5TBLx/ysscIhvpPTs8p1BX7Y8QZk+bbq+cOsp1TCoDaZR4jg noOaoGq4ezVmk1bjcd8Wth4WJu+tZtifeu/IXqXBXgz3lJIvWg0kQ5LC28mb1Dx4jGF7UHTp0h2 woMw0pRWRXG7a9uEmwVLwt8SnHA2MTOU2VkcIcbxSGxX1ycgOUglX5WQ8= X-Received: from pjbnl15.prod.google.com ([2002:a17:90b:384f:b0:38f:a3cc:f600]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a17:90b:5447:b0:393:1cf4:d972 with SMTP id 98e67ed59e1d1-3933b6e6db1mr28510221a91.3.1786998507269; Mon, 17 Aug 2026 13:28:27 -0700 (PDT) Date: Mon, 17 Aug 2026 20:28:23 +0000 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 X-Mailer: git-send-email 2.55.0.699.gb54405d56f-goog Message-ID: <20260817202823.2172548-1-dmatlack@google.com> Subject: [PATCH v4] PCI: Ensure ATS disabled via quirk before notifying IOMMU drivers From: David Matlack To: linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org Cc: Alexander Lobakin , Alex Deucher , Andy Shevchenko , Bartosz Pawlowski , Bjorn Helgaas , "=?UTF-8?q?Christian=20K=C3=B6nig?=" , David Woodhouse , Guchun Chen , Joerg Roedel , Lu Baolu , Raghavendra Rao Ananta , David Matlack , Pranjal Shrivastava Content-Type: text/plain; charset="UTF-8" Ensure that PCI devices always have ATS disable via quirk before IOMMU drivers are notified about the device. Fix this by converting the existing quirks from final to header fixups and changing the quirk logic to set a new no_ats bit in struct pci_dev that prevents pci_dev.ats_cap from ever getting set. Use header fixups instead of early fixups since not enough of struct pci_dev is set up in during early fixups: quirk_amd_harvest_no_ats() needs subsystem_device and subsystem_vendor to be set. This change ensures that pci_ats_supported() always takes quirks into account during iommu_ops.probe_device(), when IOMMU drivers are notified about devices, and that pci_ats_supported() returns the same value when the device is released in iommu_ops.release_device(). The Intel IOMMU driver uses pci_ats_supported() in probe/release to determine whether to add/remove a device from a tracking rbtree. This strict reliance on pci_ats_supported() remaining constant between probe and release was introduced by commit 89436f4f5412 ("iommu/vt-d: Fix WARN_ON in iommu probe path"). Because FINAL quirks evaluate too late (in pci_bus_add_device()), pci_ats_supported() evaluated to true during IOMMU probe but false during release. This mismatch bypassed the rbtree removal upon device release, leading to a later use-after-free. Note that this fix only matters for PCI devices created after IOMMU bus notifiers are set up (e.g. hot-plugged devices and VFs). Fixes: a18615b1cfc0 ("PCI: Disable ATS for specific Intel IPU E2000 devices") Fixes: 9b44b0b09dec ("PCI: Mark AMD Stoney GPU ATS as broken") Fixes: 3f1271b54edc ("PCI: Mark all AMD Navi10 and Navi14 GPU ATS as broken") Closes: https://lore.kernel.org/linux-iommu/aYUQ_HkDJU9kjsUl@google.com/ Reviewed-by: Pranjal Shrivastava Tested-by: Pranjal Shrivastava Signed-off-by: David Matlack --- v4: - Rebase onto tip of Linus' tree - Add Pranjal's Reviewed-by and Tested-by tags v3: https://lore.kernel.org/linux-pci/20260403222750.1215002-1-dmatlack@google.com/ v2: https://lore.kernel.org/linux-pci/20260327211649.3816010-1-dmatlack@google.com/ v1: https://lore.kernel.org/linux-pci/20260223184017.688212-1-dmatlack@google.com/ Cc: Raghavendra Rao Ananta Cc: David Woodhouse Cc: Lu Baolu Cc: Andy Shevchenko drivers/pci/ats.c | 2 +- drivers/pci/quirks.c | 50 ++++++++++++++++++++++---------------------- include/linux/pci.h | 1 + 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index 96efa00d9743..772fb1968f3c 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c @@ -21,7 +21,7 @@ void pci_ats_init(struct pci_dev *dev) { int pos; - if (pci_ats_disabled()) + if (pci_ats_disabled() || dev->no_ats) return; pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index b09f27f7846f..34f1aee744ac 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -5646,7 +5646,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0422, quirk_no_ext_tags); static void quirk_no_ats(struct pci_dev *pdev) { pci_info(pdev, "disabling ATS\n"); - pdev->ats_cap = 0; + pdev->no_ats = 1; } /* @@ -5669,25 +5669,25 @@ static void quirk_amd_harvest_no_ats(struct pci_dev *pdev) } /* AMD Stoney platform GPU */ -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x98e4, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x98e4, quirk_amd_harvest_no_ats); /* AMD Iceland dGPU */ -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x6900, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x6900, quirk_amd_harvest_no_ats); /* AMD Navi10 dGPU */ -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7310, quirk_amd_harvest_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7312, quirk_amd_harvest_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7318, quirk_amd_harvest_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7319, quirk_amd_harvest_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731a, quirk_amd_harvest_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731b, quirk_amd_harvest_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731e, quirk_amd_harvest_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731f, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x7310, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x7312, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x7318, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x7319, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x731a, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x731b, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x731e, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x731f, quirk_amd_harvest_no_ats); /* AMD Navi14 dGPU */ -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7340, quirk_amd_harvest_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7341, quirk_amd_harvest_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7347, quirk_amd_harvest_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x734f, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x7340, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x7341, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x7347, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x734f, quirk_amd_harvest_no_ats); /* AMD Raven platform iGPU */ -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x15d8, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, 0x15d8, quirk_amd_harvest_no_ats); /* * Intel IPU E2000 revisions before C0 implement incorrect endianness @@ -5698,15 +5698,15 @@ static void quirk_intel_e2000_no_ats(struct pci_dev *pdev) if (pdev->revision < 0x20) quirk_no_ats(pdev); } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1451, quirk_intel_e2000_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1452, quirk_intel_e2000_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1453, quirk_intel_e2000_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1454, quirk_intel_e2000_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1455, quirk_intel_e2000_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1459, quirk_intel_e2000_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145a, quirk_intel_e2000_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145c, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1451, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1452, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1453, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1454, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1455, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1459, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x145a, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x145c, quirk_intel_e2000_no_ats); static bool quirk_nvidia_gpu_ats_required(struct pci_dev *pdev) { diff --git a/include/linux/pci.h b/include/linux/pci.h index 64b308b6e61c..393eb77112c9 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -546,6 +546,7 @@ struct pci_dev { }; u16 ats_cap; /* ATS Capability offset */ u8 ats_stu; /* ATS Smallest Translation Unit */ + u8 no_ats:1; /* ATS disabled via quirk */ #endif #ifdef CONFIG_PCI_PRI u16 pri_cap; /* PRI Capability offset */ base-commit: 8d3ae59288f1e7d58d76558a6ee96d533bc5019f -- 2.55.0.699.gb54405d56f-goog