summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPranjal Shrivastava <praan@google.com>2026-06-04 09:03:10 +0300
committerJoerg Roedel <joerg.roedel@amd.com>2026-06-04 10:21:50 +0300
commit43bd9e6d5513cb1edbafdeef146a1edc3aaced56 (patch)
treed87c6f5836c86838cf73b87cfec273c3382aa3a9
parentc468814b3fd384225a10f0ad1d6905937e50b233 (diff)
downloadlinux-43bd9e6d5513cb1edbafdeef146a1edc3aaced56.tar.xz
iommu/vt-d: Fix RB-tree corruption in probe error path
The info->node RB-tree member is zero-initialized via kzalloc. If a device does not support ATS, the device_rbtree_insert() call is skipped. If a subsequent probe step fails, the error path jumps to device_rbtree_remove(), which misinterprets the zeroed node as a tree root and corrupts the device RB-tree. Fix this by explicitly initializing the RB-node as empty using RB_CLEAR_NODE() during initialization and guarding the removal with RB_EMPTY_NODE(). Fixes: 4f1492efb495 ("iommu/vt-d: Revert ATS timing change to fix boot failure") Reported-by: sashiko-bot@kernel.org Closes: https://lore.kernel.org/all/20260525205628.CD4431F000E9@smtp.kernel.org/ Suggested-by: Baolu Lu <baolu.lu@linux.intel.com> Signed-off-by: Pranjal Shrivastava <praan@google.com> Link: https://lore.kernel.org/r/20260531170254.60493-2-praan@google.com Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
-rw-r--r--drivers/iommu/intel/iommu.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index c3d18cd77d2f..2702e9aa2241 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -157,7 +157,10 @@ static void device_rbtree_remove(struct device_domain_info *info)
unsigned long flags;
spin_lock_irqsave(&iommu->device_rbtree_lock, flags);
- rb_erase(&info->node, &iommu->device_rbtree);
+ if (!RB_EMPTY_NODE(&info->node)) {
+ rb_erase(&info->node, &iommu->device_rbtree);
+ RB_CLEAR_NODE(&info->node);
+ }
spin_unlock_irqrestore(&iommu->device_rbtree_lock, flags);
}
@@ -3254,6 +3257,7 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
info->dev = dev;
info->iommu = iommu;
+ RB_CLEAR_NODE(&info->node);
if (dev_is_pci(dev)) {
if (ecap_dev_iotlb_support(iommu->ecap) &&
pci_ats_supported(pdev) &&