[PATCH 3/8] iommu/vt-d: Require CMPXCHG16B for PASID support

Lu Baolu posted 8 patches 1 month ago
[PATCH 3/8] iommu/vt-d: Require CMPXCHG16B for PASID support
Posted by Lu Baolu 1 month ago
The Intel IOMMU driver is moving toward using the generic entry_sync
library for PASID table entry updates. This library requires 128-bit
atomic write operations (cmpxchg128) to update 512-bit PASID entries in
atomic quanta, ensuring the hardware never observes a torn entry.

On x86_64, 128-bit atomicity is provided by the CMPXCHG16B instruction.
Update the driver to:

1. Limit INTEL_IOMMU to X86_64, as 128-bit atomic operations are not
   available on 32-bit x86.
2. Gate pasid_supported() on the presence of X86_FEATURE_CX16.
3. Provide a boot-time warning if a PASID-capable IOMMU is detected on
   a CPU lacking the required instruction.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/iommu/intel/Kconfig | 2 +-
 drivers/iommu/intel/iommu.h | 3 ++-
 drivers/iommu/intel/iommu.c | 4 ++++
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/intel/Kconfig b/drivers/iommu/intel/Kconfig
index 7fa31b9d4ef4..fee7fea9dfcb 100644
--- a/drivers/iommu/intel/Kconfig
+++ b/drivers/iommu/intel/Kconfig
@@ -11,7 +11,7 @@ config DMAR_DEBUG
 
 config INTEL_IOMMU
 	bool "Support for Intel IOMMU using DMA Remapping Devices"
-	depends on PCI_MSI && ACPI && X86
+	depends on PCI_MSI && ACPI && X86_64
 	select IOMMU_API
 	select GENERIC_PT
 	select IOMMU_PT
diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
index 599913fb65d5..54b58d01d0cb 100644
--- a/drivers/iommu/intel/iommu.h
+++ b/drivers/iommu/intel/iommu.h
@@ -535,7 +535,8 @@ enum {
 
 #define sm_supported(iommu)	(intel_iommu_sm && ecap_smts((iommu)->ecap))
 #define pasid_supported(iommu)	(sm_supported(iommu) &&			\
-				 ecap_pasid((iommu)->ecap))
+				 ecap_pasid((iommu)->ecap) &&		\
+				 boot_cpu_has(X86_FEATURE_CX16))
 #define ssads_supported(iommu) (sm_supported(iommu) &&                 \
 				ecap_slads((iommu)->ecap) &&           \
 				ecap_smpwc(iommu->ecap))
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index ef7613b177b9..5369526e89d0 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2647,6 +2647,10 @@ int __init intel_iommu_init(void)
 			pr_info_once("IOMMU batching disallowed due to virtualization\n");
 			iommu_set_dma_strict();
 		}
+
+		if (ecap_pasid(iommu->ecap) && !boot_cpu_has(X86_FEATURE_CX16))
+			pr_info_once("PASID disabled due to lack of CMPXCHG16B support.\n");
+
 		iommu_device_sysfs_add(&iommu->iommu, NULL,
 				       intel_iommu_groups,
 				       "%s", iommu->name);
-- 
2.43.0
Re: [PATCH 3/8] iommu/vt-d: Require CMPXCHG16B for PASID support
Posted by Jason Gunthorpe 1 month ago
On Mon, Mar 09, 2026 at 02:06:43PM +0800, Lu Baolu wrote:
> The Intel IOMMU driver is moving toward using the generic entry_sync
> library for PASID table entry updates. This library requires 128-bit
> atomic write operations (cmpxchg128) to update 512-bit PASID entries in
> atomic quanta, ensuring the hardware never observes a torn entry.
> 
> On x86_64, 128-bit atomicity is provided by the CMPXCHG16B instruction.
> Update the driver to:
> 
> 1. Limit INTEL_IOMMU to X86_64, as 128-bit atomic operations are not
>    available on 32-bit x86.
> 2. Gate pasid_supported() on the presence of X86_FEATURE_CX16.
> 3. Provide a boot-time warning if a PASID-capable IOMMU is detected on
>    a CPU lacking the required instruction.

This is fine, but it also occured to me that we could change the
writer somewhat to just detect what the update granual is and fall
back to 64 bit in this case. So everything still works, it just does
non-present alot more often.

Jason
Re: [PATCH 3/8] iommu/vt-d: Require CMPXCHG16B for PASID support
Posted by Baolu Lu 4 weeks ago
On 3/9/26 21:42, Jason Gunthorpe wrote:
> On Mon, Mar 09, 2026 at 02:06:43PM +0800, Lu Baolu wrote:
>> The Intel IOMMU driver is moving toward using the generic entry_sync
>> library for PASID table entry updates. This library requires 128-bit
>> atomic write operations (cmpxchg128) to update 512-bit PASID entries in
>> atomic quanta, ensuring the hardware never observes a torn entry.
>>
>> On x86_64, 128-bit atomicity is provided by the CMPXCHG16B instruction.
>> Update the driver to:
>>
>> 1. Limit INTEL_IOMMU to X86_64, as 128-bit atomic operations are not
>>     available on 32-bit x86.
>> 2. Gate pasid_supported() on the presence of X86_FEATURE_CX16.
>> 3. Provide a boot-time warning if a PASID-capable IOMMU is detected on
>>     a CPU lacking the required instruction.
> This is fine, but it also occured to me that we could change the
> writer somewhat to just detect what the update granual is and fall
> back to 64 bit in this case. So everything still works, it just does
> non-present alot more often.

That's a good point. Though I don't expect many real-world use cases for
PASID on platforms lacking CX16, making the entry_sync library and the
driver adaptive would make the infrastructure more robust. I will look
into supporting a 64-bit fallback.

Thanks,
baolu