mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
iommu/vt-d: Clear Present bit before tearing down scalable-mode context entry
device_pasid_table_teardown() zeroes the 128-bit scalable-mode context entry with context_clear_entry() while the Present bit is still set. This creates a window where the hardware can fetch a torn entry, with some fields already zeroed while Present is still set, leading to unpredictable behavior or spurious faults. The context-cache invalidation is issued only after the entry has been zeroed, and intel_pasid_free_table() then frees the PASID directory pages, so the IOMMU can keep walking a stale Present=1 entry that points at freed memory. While x86 provides strong write ordering, the compiler may reorder the two 64-bit writes to the entry, and the hardware fetch is not guaranteed to be atomic with respect to multiple CPU writes. Commitc1e4f1dccb("iommu/vt-d: Clear Present bit before tearing down context entry") fixed this exact pattern in domain_context_clear_one() and the copied-context path, but device_pasid_table_teardown() was not converted. Align it with the "Guidance to Software for Invalidations" in the VT-d spec, Section 6.5.3.3, using the same ownership handshake as the sibling fix: clear only the Present bit, flush it to the IOMMU, perform the context-cache invalidation, and only then zero the rest of the entry. Fixes:81e921fd32("iommu/vt-d: Fix NULL domain on device release") Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Assisted-by: Claude:claude-opus-4-7 Link: https://lore.kernel.org/r/20260528025557.3209367-1-michael.bommarito@gmail.com Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
parent
534b5f98ab
commit
f46452c3df
|
|
@ -748,10 +748,12 @@ static void device_pasid_table_teardown(struct device *dev, u8 bus, u8 devfn)
|
|||
}
|
||||
|
||||
did = context_domain_id(context);
|
||||
context_clear_entry(context);
|
||||
context_clear_present(context);
|
||||
__iommu_flush_cache(iommu, context, sizeof(*context));
|
||||
spin_unlock(&iommu->lock);
|
||||
intel_context_flush_no_pasid(info, context, did);
|
||||
context_clear_entry(context);
|
||||
__iommu_flush_cache(iommu, context, sizeof(*context));
|
||||
}
|
||||
|
||||
static int pci_pasid_table_teardown(struct pci_dev *pdev, u16 alias, void *data)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user