Re: [PATCH] iommu/vt-d: Make DMA-fault page-table dump user-selectable

Baolu Lu <[email protected]> Mon, 27 Jul 2026 10:36:01 +0800
Newsgroups dev.linux.lists.iommu,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On 6/9/26 22:37, Ahmed Abdelraoof wrote:
> From: Ahmed Abdelraoof <[email protected]>
> 
> The page-table dump was gated behind the hidden CONFIG_DMAR_DEBUG
> symbol, only reachable by enabling the full INTEL_IOMMU_DEBUGFS
> interface. That interface is explicitly flagged as not for production
> and exposes far more IOMMU internals than a fault dump needs, so there
> was no way to get this diagnostic from menuconfig on production kernel
> without taking on the rest.
> 
> This patch renames it to CONFIG_DMAR_FAULT_DEBUG with a prompt and help
> text so the fault dump can be enabled on its own, and updates all
> references in iommu.c and dmar.h. INTEL_IOMMU_DEBUGFS still selects it,
> so existing configs are unaffected; no functional change otherwise.

pgtable_walk() is not safe or robust enough to expose in production
environments; that is why it is currently limited to CONFIG_DMAR_DEBUG.

Intel IOMMU hardware walks multiple page-table formats. Some are managed
by the IOMMU subsystem (iommupt), while others are shared with CPU page
tables and managed outside the IOMMU subsystem. In the near future,
there may also be page tables managed by the TDX module in private
memory that the IOMMU driver cannot access.

Another issue is that pgtable_walk() lacks proper locking to protect
against concurrent page-table updates. This makes it fragile and can
potentially lead to UAF issues.

> 
> Signed-off-by: Ahmed Abdelraoof <[email protected]>
> ---
>   drivers/iommu/intel/Kconfig | 11 ++++++++---
>   drivers/iommu/intel/iommu.c |  2 +-
>   include/linux/dmar.h        |  2 +-
>   3 files changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/iommu/intel/Kconfig b/drivers/iommu/intel/Kconfig
> index 5471f814e073..59a05cefa728 100644
> --- a/drivers/iommu/intel/Kconfig
> +++ b/drivers/iommu/intel/Kconfig
> @@ -6,8 +6,13 @@ config DMAR_TABLE
>   config DMAR_PERF
>   	bool
>   
> -config DMAR_DEBUG
> -	bool
> +config DMAR_FAULT_DEBUG
> +	bool "Dump Intel IOMMU page tables on DMA fault"
> +	depends on INTEL_IOMMU
> +	help
> +	  On a DMA Remapping (DMAR) fault, walk the Root / Context /
> +	  PASID / second-level page-table entries for the faulting
> +	  source-id and IOVA and emit them via pr_info.
>   
>   config INTEL_IOMMU
>   	bool "Support for Intel IOMMU using DMA Remapping Devices"
> @@ -39,7 +44,7 @@ config INTEL_IOMMU_DEBUGFS
>   	bool "Export Intel IOMMU internals in Debugfs"
>   	depends on IOMMU_DEBUGFS
>   	select DMAR_PERF
> -	select DMAR_DEBUG
> +	select DMAR_FAULT_DEBUG
>   	help
>   	  !!!WARNING!!!
>   
> diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
> index 4d0e65bc131d..7c28ef700dda 100644
> --- a/drivers/iommu/intel/iommu.c
> +++ b/drivers/iommu/intel/iommu.c
> @@ -549,7 +549,7 @@ static void free_context_table(struct intel_iommu *iommu)
>   	iommu->root_entry = NULL;
>   }
>   
> -#ifdef CONFIG_DMAR_DEBUG
> +#ifdef CONFIG_DMAR_FAULT_DEBUG
>   static void pgtable_walk(struct intel_iommu *iommu, unsigned long pfn,
>   			 u8 bus, u8 devfn, struct dma_pte *parent, int level)
>   {
> diff --git a/include/linux/dmar.h b/include/linux/dmar.h
> index 692b2b445761..199cf01284fe 100644
> --- a/include/linux/dmar.h
> +++ b/include/linux/dmar.h
> @@ -126,7 +126,7 @@ static inline int dmar_res_noop(struct acpi_dmar_header *hdr, void *arg)
>   	return 0;
>   }
>   
> -#ifdef CONFIG_DMAR_DEBUG
> +#ifdef CONFIG_DMAR_FAULT_DEBUG
>   void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
>   			  unsigned long long addr, u32 pasid);
>   #else

Thanks,
baolu