From nobody Fri Apr 17 04:48:15 2026 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.202]) (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 CC4E9366DCB for ; Mon, 23 Feb 2026 18:40:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771872027; cv=none; b=K9aPMmp0qjn6ZL7Zad2lG3wievQb3pQXSAreTOTGrQMhaho7kW036vbEdnNlzl8R1DPJSXpPh1cdsLx3qpZt1Bq8CBUsh8LXJOuOjNN7XJVofRaIvwraNqjfeLRbBWBI4yVVvS5u6HpalPvXzNuFnQyeLGxU23xBBi3Jj9oFMSg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771872027; c=relaxed/simple; bh=PEW60uE6mf0oWwEUpjKiIai0CeHDPntrzOKJY99hrv4=; h=Date:Mime-Version:Message-ID:Subject:From:To:Cc:Content-Type; b=J+M72X3KXWVHm7kXvWnqcQVW2Bpoth7O1yReFhkK7suHvq8eQwdhwTWpShhfMv/4aq2OBsIVRqmMK6risxw+UtspkuZRRnJWxOLtIk78S8ih/qArUySlDOTr/nH/jWSz0aaUb0ZrIXvii/EGJaRs6r2uBRF+MN29iPc2WzOwkqw= 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=rmVWSese; arc=none smtp.client-ip=209.85.214.202 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="rmVWSese" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-2ad147cdf07so49744185ad.2 for ; Mon, 23 Feb 2026 10:40:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1771872024; x=1772476824; darn=vger.kernel.org; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=hr64EFuXq0VWSV0H6j2gO6901ICKZlFpt5P+iy1UzFE=; b=rmVWSeseJAHTvUi3Wp7cohmiaQ4y+9oHiqfoDILA6RtyLUgYYX1p6qYxWJJNivfJ3y EnXCdsIHGDhoRT6ABcGC1Fc9t9/UCaW52EBV1JMShMZ6M6P7hyIZrMa8j+G/ZJyoULmJ Wv3kbHWChjR68jkGmdeQLs7XoXOizOdOo6IeBjCcF9jl+UmED1cd/6J8REVe2UW6ZbxI dC+G9ooKz2HXBTI+MUkfqnsV8cyYs1lYq9bn6AbAQZJeXQiXSkDqayGZ8t0oSpgV3Emf wAWSYRNjL6hmQ9EkfCoZqmvP3sXnTe5ZBLuUAr4NWBTdAIBg2sH8WKvVvq4Tfh3Bp1DZ 6MXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771872024; x=1772476824; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=hr64EFuXq0VWSV0H6j2gO6901ICKZlFpt5P+iy1UzFE=; b=BiFlq76Ugaio6+OGngQY2GbdmomyJk/l3vQd5fIi2CaUBhdsRckkz5mMEfepJKmaqh phN78wPdHQsaNZW/J8lz9zGq9HfBjCVz0sl4bx/sz40eC9EQWpfmOBMSyN/tJ8GScIHB OPQi2OdaKZCRkWllk3Q3yftSwSI32R1MU2tTfROa4JbECaySlfNHc7GY5em6PRX8opIZ zboJfUI5hCyMjSfz+CU60CRF1TjyspXZY4lHbMdKbIxz0ECKiLHT8Q1BZlU5Ue3SAXcz KBc6h+zEVLNXG4E6glvIgQjqoD35LHoepXIJbJnTlJuc+NQUmMUwWMUZHeLsbgJfLJFF pfow== X-Forwarded-Encrypted: i=1; AJvYcCUulOCfLxLE139ALtbmfpfvhxlasUoIg2B4707I3xZPiUKyo++10L5wLDGtrRBvlVJYba6OWC4uPbq/A9k=@vger.kernel.org X-Gm-Message-State: AOJu0YxJSFeAxVNx1CJUaDdWGZK2qdkQDiGmGc+q5f4gffvxCNHooCbM +Z6kxPYB9cA1fbEVbXXstF/eFdaE+Gi/j9lOeIifU5+w85syRYS/YEWnj8yuRPWnuOjMwz5lLtG EvyAaS1lkcMgosQ== X-Received: from pllx13.prod.google.com ([2002:a17:902:7c0d:b0:2a9:5b1d:9c8a]) (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:d4d2:b0:2aa:d287:6949 with SMTP id d9443c01a7336-2ad74457070mr85524915ad.5.1771872023851; Mon, 23 Feb 2026 10:40:23 -0800 (PST) Date: Mon, 23 Feb 2026 18:40:16 +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.53.0.371.g1d285c8824-goog Message-ID: <20260223184017.688212-1-dmatlack@google.com> Subject: [PATCH] PCI: Disable ATS via quirk before notifying IOMMU drivers From: David Matlack To: Bjorn Helgaas Cc: Alexander Lobakin , Andy Shevchenko , Bartosz Pawlowski , David Woodhouse , linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, Lu Baolu , Raghavendra Rao Ananta , David Matlack Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Ensure that PCI devices that have ATS disabled via quirk have it disabled before IOMMU drivers are notified about the device. Otherwise the IOMMU driver will see that the device has ATS enabled during probing and then later it will get disabled. This fixes at least one bug in the Intel IOMMU driver where it adds the device to an rbtree because it sees ATS is enabled, but then ATS gets disabled via quirk. When the device is destroyed (e.g. hot-unplug, VF destruction, etc.) the driver sees that ATS is disabled and does not remove it from the rbtree. This inevitably leads to a use-after-free and corruption of the rbtree. Fix this by disabling ATS via quirk during "early" fixups instead of "final" fixups. Fixes: a18615b1cfc0 ("PCI: Disable ATS for specific Intel IPU E2000 devices= ") Closes: https://lore.kernel.org/linux-iommu/aYUQ_HkDJU9kjsUl@google.com/ Cc: Raghavendra Rao Ananta Cc: David Woodhouse Cc: Lu Baolu Signed-off-by: David Matlack --- drivers/pci/ats.c | 3 +++ drivers/pci/quirks.c | 50 ++++++++++++++++++++++---------------------- include/linux/pci.h | 1 + 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index ec6c8dbdc5e9..85306198c232 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c @@ -24,6 +24,9 @@ void pci_ats_init(struct pci_dev *dev) if (pci_ats_disabled()) return; =20 + if (dev->no_ats) + return; + pos =3D pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS); if (!pos) return; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 48946cca4be7..2c7e11830e45 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -5653,7 +5653,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x= 0422, quirk_no_ext_tags); static void quirk_no_ats(struct pci_dev *pdev) { pci_info(pdev, "disabling ATS\n"); - pdev->ats_cap =3D 0; + pdev->no_ats =3D 1; } =20 /* @@ -5676,25 +5676,25 @@ static void quirk_amd_harvest_no_ats(struct pci_dev= *pdev) } =20 /* AMD Stoney platform GPU */ -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x98e4, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x98e4, quirk_amd_harvest_no_at= s); /* AMD Iceland dGPU */ -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x6900, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x6900, quirk_amd_harvest_no_at= s); /* AMD Navi10 dGPU */ -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7310, quirk_amd_harvest_no_at= s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7312, quirk_amd_harvest_no_at= s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7318, quirk_amd_harvest_no_at= s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7319, quirk_amd_harvest_no_at= s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731a, quirk_amd_harvest_no_at= s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731b, quirk_amd_harvest_no_at= s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731e, quirk_amd_harvest_no_at= s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x731f, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x7310, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x7312, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x7318, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x7319, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x731a, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x731b, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x731e, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x731f, quirk_amd_harvest_no_at= s); /* AMD Navi14 dGPU */ -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7340, quirk_amd_harvest_no_at= s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7341, quirk_amd_harvest_no_at= s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7347, quirk_amd_harvest_no_at= s); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x734f, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x7340, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x7341, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x7347, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x734f, quirk_amd_harvest_no_at= s); /* AMD Raven platform iGPU */ -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x15d8, quirk_amd_harvest_no_at= s); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, 0x15d8, quirk_amd_harvest_no_at= s); =20 /* * Intel IPU E2000 revisions before C0 implement incorrect endianness @@ -5705,15 +5705,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_EARLY(PCI_VENDOR_ID_INTEL, 0x1451, quirk_intel_e2000_no_= ats); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1452, quirk_intel_e2000_no_= ats); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1453, quirk_intel_e2000_no_= ats); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1454, quirk_intel_e2000_no_= ats); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1455, quirk_intel_e2000_no_= ats); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_= ats); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1459, quirk_intel_e2000_no_= ats); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x145a, quirk_intel_e2000_no_= ats); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x145c, quirk_intel_e2000_no_= ats); #endif /* CONFIG_PCI_ATS */ =20 /* Freescale PCIe doesn't support MSI in RC mode */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 1c270f1d5123..5880942bba65 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -537,6 +537,7 @@ struct pci_dev { struct pci_sriov *sriov; /* PF: SR-IOV info */ struct pci_dev *physfn; /* VF: related PF */ }; + unsigned int no_ats:1; /* ATS disabled via quirk */ u16 ats_cap; /* ATS Capability offset */ u8 ats_stu; /* ATS Smallest Translation Unit */ #endif base-commit: a95f71ad3e2e224277508e006580c333d0a5fe36 --=20 2.53.0.371.g1d285c8824-goog