1 - Bypass the IOMMU for DMA.
unset - Use value of CONFIG_IOMMU_DEFAULT_PASSTHROUGH.
+ iommu.debug_pagealloc=
+ [KNL,EARLY] When CONFIG_IOMMU_DEBUG_PAGEALLOC is set, this
+ parameter enables the feature at boot time. By default, it
+ is disabled and the system behaves the same way as a kernel
+ built without CONFIG_IOMMU_DEBUG_PAGEALLOC.
+ Format: { "0" | "1" }
+ 0 - Sanitizer disabled.
+ 1 - Sanitizer enabled, expect runtime overhead.
+
io7= [HW] IO7 for Marvel-based Alpha systems
See comment before marvel_specify_io7 in
arch/alpha/kernel/core_marvel.c.
Say Y here if you want to use the multimedia devices listed above.
+config IOMMU_DEBUG_PAGEALLOC
+ bool "Debug IOMMU mappings against page allocations"
+ depends on DEBUG_PAGEALLOC && IOMMU_API && PAGE_EXTENSION
+ help
+ This enables a consistency check between the kernel page allocator and
+ the IOMMU subsystem. It verifies that pages being allocated or freed
+ are not currently mapped in any IOMMU domain.
+
+ This helps detect DMA use-after-free bugs where a driver frees a page
+ but forgets to unmap it from the IOMMU, potentially allowing a device
+ to overwrite memory that the kernel has repurposed.
+
+ These checks are best-effort and may not detect all problems.
+
+ Due to performance overhead, this feature is disabled by default.
+ You must enable "iommu.debug_pagealloc" from the kernel command
+ line to activate the runtime checks.
+
+ If unsure, say N.
endif # IOMMU_SUPPORT
source "drivers/iommu/generic_pt/Kconfig"
obj-$(CONFIG_IOMMU_IOPF) += io-pgfault.o
obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o
obj-$(CONFIG_APPLE_DART) += apple-dart.o
+obj-$(CONFIG_IOMMU_DEBUG_PAGEALLOC) += iommu-debug-pagealloc.o
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2025 - Google Inc
+ * Author: Mostafa Saleh <smostafa@google.com>
+ * IOMMU API debug page alloc sanitizer
+ */
+#include <linux/atomic.h>
+#include <linux/iommu-debug-pagealloc.h>
+#include <linux/kernel.h>
+#include <linux/page_ext.h>
+
+static bool needed;
+
+struct iommu_debug_metadata {
+ atomic_t ref;
+};
+
+static __init bool need_iommu_debug(void)
+{
+ return needed;
+}
+
+struct page_ext_operations page_iommu_debug_ops = {
+ .size = sizeof(struct iommu_debug_metadata),
+ .need = need_iommu_debug,
+};
+
+static int __init iommu_debug_pagealloc(char *str)
+{
+ return kstrtobool(str, &needed);
+}
+early_param("iommu.debug_pagealloc", iommu_debug_pagealloc);
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2025 - Google Inc
+ * Author: Mostafa Saleh <smostafa@google.com>
+ * IOMMU API debug page alloc sanitizer
+ */
+
+#ifndef __LINUX_IOMMU_DEBUG_PAGEALLOC_H
+#define __LINUX_IOMMU_DEBUG_PAGEALLOC_H
+
+#ifdef CONFIG_IOMMU_DEBUG_PAGEALLOC
+
+extern struct page_ext_operations page_iommu_debug_ops;
+
+#endif /* CONFIG_IOMMU_DEBUG_PAGEALLOC */
+
+#endif /* __LINUX_IOMMU_DEBUG_PAGEALLOC_H */
#include <linux/page_table_check.h>
#include <linux/rcupdate.h>
#include <linux/pgalloc_tag.h>
+#include <linux/iommu-debug-pagealloc.h>
/*
* struct page extension
#ifdef CONFIG_PAGE_TABLE_CHECK
&page_table_check_ops,
#endif
+#ifdef CONFIG_IOMMU_DEBUG_PAGEALLOC
+ &page_iommu_debug_ops,
+#endif
};
unsigned long page_ext_size;