From nobody Sat Feb 7 21:24:53 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 67434500966 for ; Fri, 9 Jan 2026 17:18:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767979096; cv=none; b=krlDqeqzLu0oxtZODTThOhnJN8TsUro4K1mmmIxRHQkdHhKZZCsHIqqXazH+GxrSqbPFFCvTPQES0ToRuwF/qEB8Gc9HVxKe3cp+qm2RV0uhLhu2O4/+nFJYXCuGyNEltsgYyp4nbAQjz/QYNfY/oHDwnFWLkIoP/g5PqXDAZk8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767979096; c=relaxed/simple; bh=Q41HnTHND56VPHVKcwQtds+kxZQpysksZlYusZI1eY0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=dHMA2V6MWr1fyZ+x1av2y4g+aGGFG27nIjsShOGKrwUugswi01eWK5ysAPR/zAjUVG6+YInhxtl2fUvJECHm8rDnpqeVnUani9rV0QweFhMNKSIwf5oMZY+gMe7nuhNI1y42iGn+qVtY980/vTTb3fxcB72rBSdoQD5aaI7F5Zs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=uPp2a4x3; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="uPp2a4x3" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-4779ecc3cc8so31888175e9.3 for ; Fri, 09 Jan 2026 09:18:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1767979093; x=1768583893; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=yMbvILs8sdDM+X7Y87HU9ypohayabztkjgZL2Mm3bR4=; b=uPp2a4x33xbP+PpB6XJlkhFe5+GZWIveP00OEqa01+hiOost3kzj6eJl0A1rEH8s6B V9TLEbXSuk3c8z8RcbPTCok6/KSEUTLmuGf0m0a9QZEPwYYekJ5gBjwqujJlQXKIifHQ oFz9ZeeoxMj366pR0t0CqB5k89OzD9EAhMmigFGIoSmiQMDLeizNheJ903sW4+FeBOcO pzwHNQp7R2URzwODqIGANTDEMudd+Uw4E80dFWsXb8wd7JODqqtFJAbkBwrMOEm4afFa Ls66lG3I3ulxvxV7bbWw4+f1Z++6n3SFJYn1xNyArxAt6MUowtWw4sb3pOygcZTBjgN6 Um7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767979093; x=1768583893; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=yMbvILs8sdDM+X7Y87HU9ypohayabztkjgZL2Mm3bR4=; b=GEp2KhoA+iN5zkUfZa4aNALkJXFa6gZH25sotiJBgm7kYUnS+i9LzKHYkO1B0ELSLM Js6shvPiACu96ltCAVeLDGOZ4ACLO87ArA9jA1UfbmphixaCcsehAcq14f9Q2hTM+kTc f2jBtcLSSYYCXc9YOtMEFVNHL/LqzXhdVDf0znbHt7/rYbeIpRELEVoD04/iq/vGz3YI 3HyjZu47tuGTfYcxn5OwDl+orMX2YEoNUsX4GFVIg5z3RXTEIxy3+9pFxTEfCoXiWsAj ht7+936W+ELYGPIEJxsMK7IRpi+B0A3dcUFyCEWKshYmKZEh4lYVlpzpM0Ejh6rKyeA+ R7hQ== X-Forwarded-Encrypted: i=1; AJvYcCWYCVnEkGh158ZphHtrvSAV8SF1ccH8/FuICeecvp80JTGsZQ8/oelHMuGJqeggQ4CiJQUkGGC8Pvf2BN0=@vger.kernel.org X-Gm-Message-State: AOJu0YzttrcPf+yP6/J5RLelQZxWYWjf74UJxBhLD5oWnI7/Rs6CBC2f oDfmUHovCYjDliZ37BdSEAmqZCj0KkaIOjx+P6BziaduKTT3FtXuhtqoCs4Lw5q/PzmG83O92hM nsg2+5SlxeELj/g== X-Google-Smtp-Source: AGHT+IFQrKO26j/Md4KslqSM57emYB9l/vej4SFg9X38oEIjTZGmUcvdSgmghLEuHbXJHuTDMuZHlNVKSr6pZw== X-Received: from wrbdr2.prod.google.com ([2002:a5d:5f82:0:b0:430:f6bf:b2c3]) (user=smostafa job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600d:103:b0:47d:403e:9cd5 with SMTP id 5b1f17b1804b1-47d84b1fce2mr91839245e9.11.1767979093084; Fri, 09 Jan 2026 09:18:13 -0800 (PST) Date: Fri, 9 Jan 2026 17:18:02 +0000 In-Reply-To: <20260109171805.901995-1-smostafa@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260109171805.901995-1-smostafa@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260109171805.901995-2-smostafa@google.com> Subject: [PATCH v6 1/4] iommu: Add page_ext for IOMMU_DEBUG_PAGEALLOC From: Mostafa Saleh To: linux-mm@kvack.org, iommu@lists.linux.dev, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org Cc: corbet@lwn.net, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, akpm@linux-foundation.org, vbabka@suse.cz, surenb@google.com, mhocko@suse.com, jackmanb@google.com, hannes@cmpxchg.org, ziy@nvidia.com, david@redhat.com, lorenzo.stoakes@oracle.com, Liam.Howlett@oracle.com, rppt@kernel.org, xiaqinxin@huawei.com, baolu.lu@linux.intel.com, rdunlap@infradead.org, Mostafa Saleh , "David Hildenbrand (Red Hat)" , Pranjal Shrivastava Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a new config IOMMU_DEBUG_PAGEALLOC, which registers new data to page_ext. This config will be used by the IOMMU API to track pages mapped in the IOMMU to catch drivers trying to free kernel memory that they still map in their domains, causing all types of memory corruption. This behaviour is disabled by default and can be enabled using kernel cmdline iommu.debug_pagealloc. Acked-by: David Hildenbrand (Red Hat) Reviewed-by: Pranjal Shrivastava Reviewed-by: Lu Baolu Signed-off-by: Mostafa Saleh --- .../admin-guide/kernel-parameters.txt | 9 ++++++ drivers/iommu/Kconfig | 19 +++++++++++ drivers/iommu/Makefile | 1 + drivers/iommu/iommu-debug-pagealloc.c | 32 +++++++++++++++++++ include/linux/iommu-debug-pagealloc.h | 17 ++++++++++ mm/page_ext.c | 4 +++ 6 files changed, 82 insertions(+) create mode 100644 drivers/iommu/iommu-debug-pagealloc.c create mode 100644 include/linux/iommu-debug-pagealloc.h diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentatio= n/admin-guide/kernel-parameters.txt index a8d0afde7f85..d484d9d8d0a4 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2675,6 +2675,15 @@ Kernel parameters 1 - Bypass the IOMMU for DMA. unset - Use value of CONFIG_IOMMU_DEFAULT_PASSTHROUGH. =20 + iommu.debug_pagealloc=3D + [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=3D [HW] IO7 for Marvel-based Alpha systems See comment before marvel_specify_io7 in arch/alpha/kernel/core_marvel.c. diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 99095645134f..f86262b11416 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -384,6 +384,25 @@ config SPRD_IOMMU =20 Say Y here if you want to use the multimedia devices listed above. =20 +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 =20 source "drivers/iommu/generic_pt/Kconfig" diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 8e8843316c4b..0275821f4ef9 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -36,3 +36,4 @@ obj-$(CONFIG_IOMMU_SVA) +=3D iommu-sva.o obj-$(CONFIG_IOMMU_IOPF) +=3D io-pgfault.o obj-$(CONFIG_SPRD_IOMMU) +=3D sprd-iommu.o obj-$(CONFIG_APPLE_DART) +=3D apple-dart.o +obj-$(CONFIG_IOMMU_DEBUG_PAGEALLOC) +=3D iommu-debug-pagealloc.o diff --git a/drivers/iommu/iommu-debug-pagealloc.c b/drivers/iommu/iommu-de= bug-pagealloc.c new file mode 100644 index 000000000000..4022e9af7f27 --- /dev/null +++ b/drivers/iommu/iommu-debug-pagealloc.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 - Google Inc + * Author: Mostafa Saleh + * IOMMU API debug page alloc sanitizer + */ +#include +#include +#include +#include + +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 =3D { + .size =3D sizeof(struct iommu_debug_metadata), + .need =3D need_iommu_debug, +}; + +static int __init iommu_debug_pagealloc(char *str) +{ + return kstrtobool(str, &needed); +} +early_param("iommu.debug_pagealloc", iommu_debug_pagealloc); diff --git a/include/linux/iommu-debug-pagealloc.h b/include/linux/iommu-de= bug-pagealloc.h new file mode 100644 index 000000000000..83e64d70bf6c --- /dev/null +++ b/include/linux/iommu-debug-pagealloc.h @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 - Google Inc + * Author: Mostafa Saleh + * 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 */ diff --git a/mm/page_ext.c b/mm/page_ext.c index d7396a8970e5..297e4cd8ce90 100644 --- a/mm/page_ext.c +++ b/mm/page_ext.c @@ -11,6 +11,7 @@ #include #include #include +#include =20 /* * struct page extension @@ -89,6 +90,9 @@ static struct page_ext_operations *page_ext_ops[] __initd= ata =3D { #ifdef CONFIG_PAGE_TABLE_CHECK &page_table_check_ops, #endif +#ifdef CONFIG_IOMMU_DEBUG_PAGEALLOC + &page_iommu_debug_ops, +#endif }; =20 unsigned long page_ext_size; --=20 2.52.0.457.g6b5491de43-goog From nobody Sat Feb 7 21:24:53 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3FD8C366543 for ; Fri, 9 Jan 2026 17:18:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767979099; cv=none; b=GEimbHyIkggM5mbdBIrvijI41n7U5ZVhWSppvHnDuCSgjTOkho+GYIfyWnB1u5iF6+CovElIYwUZrlpurBuNTJyWsvtIz9P4vEJBScjOBz/HlYmb6veBT3iFIopo7tOJV5mpOim95ogULwso7PfHSC77qlbQtgrz8Cmth5ebNGg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767979099; c=relaxed/simple; bh=aVLtfsmeLEMhp2ORt1tnvgbLgSD0YJ90dSkoXHBqBTc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=HV25pQylGtE3XLAOW/VjERMIUTf5A/6yrW/5u1SXhCnIHkNRp+8t/23R6T3QCnAtj38On/gHydw3jc980VWdldyzdsaYPGwz6xjBvMy8yxCVVuiHDPS0H6REKsOqABsnEWI7RdX4EvpwDYMkhCV6hXcNB3HVZsTl7WRPRlGEC+c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=o/Y4bPfr; arc=none smtp.client-ip=209.85.128.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="o/Y4bPfr" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-4775d110fabso43034205e9.1 for ; Fri, 09 Jan 2026 09:18:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1767979094; x=1768583894; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=guvkPBegEDYZPDzaTTld5oNSHvfpDoo/mBDTxGLtjdA=; b=o/Y4bPfrBS1jdEjnNYqxX0/zDOTwII5dwTlc8Y6qvDH6RFjeQcteSsdGV7GHosW94g +Z4RCdnXJo1DOz6ZRsfrDLOty0BDutEYqsyxDcdIOLaT4bxM/dSYbPPK302Iu52tXmEk TfVK1dkRZW3jd/mU0VoaBytpnwhw2+GO1/oK2W/TB6GyHKIPgZ5Rhgn6M4rgrLMfONef z41yfWp/DwKDrsME3jkRcuH0VqBrCCNJN2SnK0iFmJxQ/qIllztNb26CkHDEr3thz3Cx kGAaM14Gm2kuMxppYZj2kIOmDsRlgtsnU2e7dUXVqrVSwwI6934N3idHzRKrtArxaF1D BZcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767979094; x=1768583894; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=guvkPBegEDYZPDzaTTld5oNSHvfpDoo/mBDTxGLtjdA=; b=E90QoeNrbPmbT6ASheB7TajxsmfmK60KQ5A6ee1W3spOUIf24PyBTBAGHY1sxQOQpa Uj+lfjhCHt+vDOO0BDGB9GsclCi8bL8EXPUS3Xpg95JAdgvSoac82TGl0MU7yWvnpUI/ rpcI4G9ZUTAQlVcq4QysUkGhF3++lP9WutsaCg0bniojvbcGmkUkME7EooJgn256TqWa hPfP1SeKgvEudfko+UtfSMwVt4aJ2cLmJW3kOQNfuYwPyOP87MBOKhxSnsdmAW9JlyLi D/hRBVIuvnbDtc84mUDycmzX+3wt/fZOvcm8xYi3MRCXPPBfmqXcYFmzSbzx+RfEhR9h 4wqQ== X-Forwarded-Encrypted: i=1; AJvYcCWISPL42Fp6vwy4F3Hg3HEfkI8k0zHpeBLhVNvOI4h4S2UIXv1i/ObdjtB1KmQrDMPxLuMOghzgWqTGdj0=@vger.kernel.org X-Gm-Message-State: AOJu0YyA7LAKbMHkww9QUwHruNYbzjcZetiil1sc2/dk8Wa/vrE5l8vR dAY+guk2vuwhMb16E/zNIg9/R8fREjIcLZ75kuXFdPgBj7QkxKcwNQShY3XWx6W4HGg5evpvlok GsHVnasfg+8Knrg== X-Google-Smtp-Source: AGHT+IEBrg+YqeYEJ2M7D0lJnTSEa6qXe7po9KhFZWeBWPF3GO7tA7upEM5MN29g/F3xM/Fg51UOl4g9PnWT0Q== X-Received: from wmgf14.prod.google.com ([2002:a05:600c:154e:b0:477:9dee:b5d5]) (user=smostafa job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1d19:b0:47d:5089:a476 with SMTP id 5b1f17b1804b1-47d84b386fdmr138392485e9.31.1767979094365; Fri, 09 Jan 2026 09:18:14 -0800 (PST) Date: Fri, 9 Jan 2026 17:18:03 +0000 In-Reply-To: <20260109171805.901995-1-smostafa@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260109171805.901995-1-smostafa@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260109171805.901995-3-smostafa@google.com> Subject: [PATCH v6 2/4] iommu: Add calls for IOMMU_DEBUG_PAGEALLOC From: Mostafa Saleh To: linux-mm@kvack.org, iommu@lists.linux.dev, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org Cc: corbet@lwn.net, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, akpm@linux-foundation.org, vbabka@suse.cz, surenb@google.com, mhocko@suse.com, jackmanb@google.com, hannes@cmpxchg.org, ziy@nvidia.com, david@redhat.com, lorenzo.stoakes@oracle.com, Liam.Howlett@oracle.com, rppt@kernel.org, xiaqinxin@huawei.com, baolu.lu@linux.intel.com, rdunlap@infradead.org, Mostafa Saleh , Samiullah Khawaja , Pranjal Shrivastava Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add calls for the new iommu debug config IOMMU_DEBUG_PAGEALLOC: - iommu_debug_init: Enable the debug mode if configured by the user. - iommu_debug_map: Track iommu pages mapped, using physical address. - iommu_debug_unmap_begin: Track start of iommu unmap operation, with IOVA and size. - iommu_debug_unmap_end: Track the end of unmap operation, passing the actual unmapped size versus the tracked one at unmap_begin. We have to do the unmap_begin/end as once pages are unmapped we lose the information of the physical address. This is racy, but the API is racy by construction as it uses refcounts and doesn't attempt to lock/synchronize with the IOMMU API as that will be costly, meaning that possibility of false negative exists. Reviewed-by: Samiullah Khawaja Reviewed-by: Lu Baolu Reviewed-by: Pranjal Shrivastava Signed-off-by: Mostafa Saleh --- drivers/iommu/iommu-debug-pagealloc.c | 28 +++++++++++++ drivers/iommu/iommu-priv.h | 58 +++++++++++++++++++++++++++ drivers/iommu/iommu.c | 11 ++++- include/linux/iommu-debug-pagealloc.h | 1 + 4 files changed, 96 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/iommu-debug-pagealloc.c b/drivers/iommu/iommu-de= bug-pagealloc.c index 4022e9af7f27..1d343421da98 100644 --- a/drivers/iommu/iommu-debug-pagealloc.c +++ b/drivers/iommu/iommu-debug-pagealloc.c @@ -5,11 +5,15 @@ * IOMMU API debug page alloc sanitizer */ #include +#include #include #include #include =20 +#include "iommu-priv.h" + static bool needed; +DEFINE_STATIC_KEY_FALSE(iommu_debug_initialized); =20 struct iommu_debug_metadata { atomic_t ref; @@ -25,6 +29,30 @@ struct page_ext_operations page_iommu_debug_ops =3D { .need =3D need_iommu_debug, }; =20 +void __iommu_debug_map(struct iommu_domain *domain, phys_addr_t phys, size= _t size) +{ +} + +void __iommu_debug_unmap_begin(struct iommu_domain *domain, + unsigned long iova, size_t size) +{ +} + +void __iommu_debug_unmap_end(struct iommu_domain *domain, + unsigned long iova, size_t size, + size_t unmapped) +{ +} + +void iommu_debug_init(void) +{ + if (!needed) + return; + + pr_info("iommu: Debugging page allocations, expect overhead or disable io= mmu.debug_pagealloc"); + static_branch_enable(&iommu_debug_initialized); +} + static int __init iommu_debug_pagealloc(char *str) { return kstrtobool(str, &needed); diff --git a/drivers/iommu/iommu-priv.h b/drivers/iommu/iommu-priv.h index c95394cd03a7..aaffad5854fc 100644 --- a/drivers/iommu/iommu-priv.h +++ b/drivers/iommu/iommu-priv.h @@ -5,6 +5,7 @@ #define __LINUX_IOMMU_PRIV_H =20 #include +#include #include =20 static inline const struct iommu_ops *dev_iommu_ops(struct device *dev) @@ -65,4 +66,61 @@ static inline int iommufd_sw_msi(struct iommu_domain *do= main, int iommu_replace_device_pasid(struct iommu_domain *domain, struct device *dev, ioasid_t pasid, struct iommu_attach_handle *handle); + +#ifdef CONFIG_IOMMU_DEBUG_PAGEALLOC + +void __iommu_debug_map(struct iommu_domain *domain, phys_addr_t phys, + size_t size); +void __iommu_debug_unmap_begin(struct iommu_domain *domain, + unsigned long iova, size_t size); +void __iommu_debug_unmap_end(struct iommu_domain *domain, + unsigned long iova, size_t size, size_t unmapped); + +static inline void iommu_debug_map(struct iommu_domain *domain, + phys_addr_t phys, size_t size) +{ + if (static_branch_unlikely(&iommu_debug_initialized)) + __iommu_debug_map(domain, phys, size); +} + +static inline void iommu_debug_unmap_begin(struct iommu_domain *domain, + unsigned long iova, size_t size) +{ + if (static_branch_unlikely(&iommu_debug_initialized)) + __iommu_debug_unmap_begin(domain, iova, size); +} + +static inline void iommu_debug_unmap_end(struct iommu_domain *domain, + unsigned long iova, size_t size, + size_t unmapped) +{ + if (static_branch_unlikely(&iommu_debug_initialized)) + __iommu_debug_unmap_end(domain, iova, size, unmapped); +} + +void iommu_debug_init(void); + +#else +static inline void iommu_debug_map(struct iommu_domain *domain, + phys_addr_t phys, size_t size) +{ +} + +static inline void iommu_debug_unmap_begin(struct iommu_domain *domain, + unsigned long iova, size_t size) +{ +} + +static inline void iommu_debug_unmap_end(struct iommu_domain *domain, + unsigned long iova, size_t size, + size_t unmapped) +{ +} + +static inline void iommu_debug_init(void) +{ +} + +#endif /* CONFIG_IOMMU_DEBUG_PAGEALLOC */ + #endif /* __LINUX_IOMMU_PRIV_H */ diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 2ca990dfbb88..01b062575519 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -232,6 +232,8 @@ static int __init iommu_subsys_init(void) if (!nb) return -ENOMEM; =20 + iommu_debug_init(); + for (int i =3D 0; i < ARRAY_SIZE(iommu_buses); i++) { nb[i].notifier_call =3D iommu_bus_notifier; bus_register_notifier(iommu_buses[i], &nb[i]); @@ -2562,10 +2564,12 @@ int iommu_map_nosync(struct iommu_domain *domain, u= nsigned long iova, } =20 /* unroll mapping in case something went wrong */ - if (ret) + if (ret) { iommu_unmap(domain, orig_iova, orig_size - size); - else + } else { trace_map(orig_iova, orig_paddr, orig_size); + iommu_debug_map(domain, orig_paddr, orig_size); + } =20 return ret; } @@ -2627,6 +2631,8 @@ static size_t __iommu_unmap(struct iommu_domain *doma= in, =20 pr_debug("unmap this: iova 0x%lx size 0x%zx\n", iova, size); =20 + iommu_debug_unmap_begin(domain, iova, size); + /* * Keep iterating until we either unmap 'size' bytes (or more) * or we hit an area that isn't mapped. @@ -2647,6 +2653,7 @@ static size_t __iommu_unmap(struct iommu_domain *doma= in, } =20 trace_unmap(orig_iova, size, unmapped); + iommu_debug_unmap_end(domain, orig_iova, size, unmapped); return unmapped; } =20 diff --git a/include/linux/iommu-debug-pagealloc.h b/include/linux/iommu-de= bug-pagealloc.h index 83e64d70bf6c..a439d6815ca1 100644 --- a/include/linux/iommu-debug-pagealloc.h +++ b/include/linux/iommu-debug-pagealloc.h @@ -9,6 +9,7 @@ #define __LINUX_IOMMU_DEBUG_PAGEALLOC_H =20 #ifdef CONFIG_IOMMU_DEBUG_PAGEALLOC +DECLARE_STATIC_KEY_FALSE(iommu_debug_initialized); =20 extern struct page_ext_operations page_iommu_debug_ops; =20 --=20 2.52.0.457.g6b5491de43-goog From nobody Sat Feb 7 21:24:53 2026 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 001D3365A1B for ; Fri, 9 Jan 2026 17:18:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767979101; cv=none; b=axIGiyye4UF9gF9vJZv2iJN2QjTPRsv8gErDA+wRzRZaoesP91VJhKy0w13F6rRuf9duBCEWBJf6qdFicuoP7fF72KxIr5dM06JIEN+F+tBL6U3U/wMsPkR3FzKiUjaXv1ntelaSNWu8pHtGP1vU2oenNQujs+CxjE0Gi/wB7Pw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767979101; c=relaxed/simple; bh=JyxK9DCFit9BHgUZF8EAQgzBS/s8P5HYnNwnkPHg5Qw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=QS2TAPR6tCa/fQSPh79JV7jGNJeXtmO8pkZrb3yhHdYHQ95dXCTdjyWoU+PV7lbvXQeNjYfhz0fWS8NIVr2TCdUvoqVFmjHINYO2f+E2GA5FOopkupgx4PgUc3OyGy+/uYpPUlDhWogE9Xa2zRcpLT9hyjTxYpV9Qh0JG4mYxx8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=NO60K8eD; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="NO60K8eD" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-4775f51ce36so40061095e9.1 for ; Fri, 09 Jan 2026 09:18:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1767979095; x=1768583895; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=rXKfhlVn2c+6UG0/zcj6FymOVg8M3bXQ+ReLnrZOk7w=; b=NO60K8eDiYauSb6F/GQlh/r3oOId3xgHGH71dzI80JnI4d7SgrnuXYeL+RQG9bmILd 0mnoZzuwemwifme8xo0ZzVGxh0UiDfeIcdAhan6G4meQSMPWcIW7513HAXCS8Vuy/LAz A9hKZuW6AxSkc0UUtg4q5W70LIfNdTmXhEsyaChZ2Cxa1A/c4o1e/ROpJGG7L3lR3fGh XZ83lpfW60qqLkKic9VCqNfy6FQXploEvk0n1T8mtDnrOuRP+86S2n+W/NA2IQPjzXjQ fdoJOC/Sw9dk53Ase2a+8GZvUrSK+BJCuMf0/JpADKFaJGXQwPUHGksAB+1P3LM/n/Wt r+2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767979095; x=1768583895; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=rXKfhlVn2c+6UG0/zcj6FymOVg8M3bXQ+ReLnrZOk7w=; b=Wkc1WjM0axF2ArISayyyERvqCBWQV8qKk03bhYVwpx/zft39LRCzRaSo3UltTSQ/+M cRQ4Et9FxZ+LR01XAdxIE8wLjRKVYHipJBNqJMqeIS+bLg65nGU9iXKhFrBASCQQVndy jbg20LfTMYz7iUN1k9QN4wupvW+frRKhyz+++r1ULRQEw7ZFf9IK/RR8csZq9EdP/Uf3 vmAx3FsHgBzG2jeO9DoeLYk2zX0bAOcaUVCiDyUC7rBQEeh04ZsftBf+bshbbgYjUGSj bxBXFQsg7aPPYUGBgj+Q9PDFPhsG9t6Teeuv1vczRqGjTdpiJc9ZgpjOiO0uZV+DBsDK Mu+A== X-Forwarded-Encrypted: i=1; AJvYcCWaQirvc9ZsOFYWTXBdSBdvNoqI0IrR9+WVG+EXlyh+8fdAMeqzh+zDljQqIup4gSCF0SZPRUeD+86If1Q=@vger.kernel.org X-Gm-Message-State: AOJu0Yxrp+79FZDxAjuYdUSVUXFWq20rCyYftuYRqLsCFKbcjLEoW8C6 BWHsiSxDXm/E6t+2XO/+qVUlHgly6QM0MO9B+E3OD12yfZ3JRB/4PrOTs8vBlu7uETEslOTBMu+ WwMequHqaDaUxcA== X-Google-Smtp-Source: AGHT+IFk02O2PK0We+1RMI+gkP8sH7Gfm0sE0Pyah5F14OonFiV3bx+oHBAF9FOQ2GaQcAwCLdJfSABlkCnRwQ== X-Received: from wmbdx10.prod.google.com ([2002:a05:600c:63ca:b0:477:3fdf:4c24]) (user=smostafa job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:46c4:b0:47d:403e:4eaf with SMTP id 5b1f17b1804b1-47d84b18ef7mr134197875e9.10.1767979095241; Fri, 09 Jan 2026 09:18:15 -0800 (PST) Date: Fri, 9 Jan 2026 17:18:04 +0000 In-Reply-To: <20260109171805.901995-1-smostafa@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260109171805.901995-1-smostafa@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260109171805.901995-4-smostafa@google.com> Subject: [PATCH v6 3/4] iommu: debug-pagealloc: Track IOMMU pages From: Mostafa Saleh To: linux-mm@kvack.org, iommu@lists.linux.dev, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org Cc: corbet@lwn.net, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, akpm@linux-foundation.org, vbabka@suse.cz, surenb@google.com, mhocko@suse.com, jackmanb@google.com, hannes@cmpxchg.org, ziy@nvidia.com, david@redhat.com, lorenzo.stoakes@oracle.com, Liam.Howlett@oracle.com, rppt@kernel.org, xiaqinxin@huawei.com, baolu.lu@linux.intel.com, rdunlap@infradead.org, Mostafa Saleh , Samiullah Khawaja Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Using the new calls, use an atomic refcount to track how many times a page is mapped in any of the IOMMUs. For unmap we need to use iova_to_phys() to get the physical address of the pages. We use the smallest supported page size as the granularity of tracking per domain. This is important as it is possible to map pages and unmap them with larger sizes (as in map_sg()) cases. Reviewed-by: Samiullah Khawaja Reviewed-by: Lu Baolu Signed-off-by: Mostafa Saleh Reviewed-by: Pranjal Shrivastava --- drivers/iommu/iommu-debug-pagealloc.c | 84 +++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/drivers/iommu/iommu-debug-pagealloc.c b/drivers/iommu/iommu-de= bug-pagealloc.c index 1d343421da98..9eb49e1230ee 100644 --- a/drivers/iommu/iommu-debug-pagealloc.c +++ b/drivers/iommu/iommu-debug-pagealloc.c @@ -29,19 +29,103 @@ struct page_ext_operations page_iommu_debug_ops =3D { .need =3D need_iommu_debug, }; =20 +static struct page_ext *get_iommu_page_ext(phys_addr_t phys) +{ + struct page *page =3D phys_to_page(phys); + struct page_ext *page_ext =3D page_ext_get(page); + + return page_ext; +} + +static struct iommu_debug_metadata *get_iommu_data(struct page_ext *page_e= xt) +{ + return page_ext_data(page_ext, &page_iommu_debug_ops); +} + +static void iommu_debug_inc_page(phys_addr_t phys) +{ + struct page_ext *page_ext =3D get_iommu_page_ext(phys); + struct iommu_debug_metadata *d =3D get_iommu_data(page_ext); + + WARN_ON(atomic_inc_return_relaxed(&d->ref) <=3D 0); + page_ext_put(page_ext); +} + +static void iommu_debug_dec_page(phys_addr_t phys) +{ + struct page_ext *page_ext =3D get_iommu_page_ext(phys); + struct iommu_debug_metadata *d =3D get_iommu_data(page_ext); + + WARN_ON(atomic_dec_return_relaxed(&d->ref) < 0); + page_ext_put(page_ext); +} + +/* + * IOMMU page size doesn't have to match the CPU page size. So, we use + * the smallest IOMMU page size to refcount the pages in the vmemmap. + * That is important as both map and unmap has to use the same page size + * to update the refcount to avoid double counting the same page. + * And as we can't know from iommu_unmap() what was the original page size + * used for map, we just use the minimum supported one for both. + */ +static size_t iommu_debug_page_size(struct iommu_domain *domain) +{ + return 1UL << __ffs(domain->pgsize_bitmap); +} + void __iommu_debug_map(struct iommu_domain *domain, phys_addr_t phys, size= _t size) { + size_t off, end; + size_t page_size =3D iommu_debug_page_size(domain); + + if (WARN_ON(!phys || check_add_overflow(phys, size, &end))) + return; + + for (off =3D 0 ; off < size ; off +=3D page_size) { + if (!pfn_valid(__phys_to_pfn(phys + off))) + continue; + iommu_debug_inc_page(phys + off); + } +} + +static void __iommu_debug_update_iova(struct iommu_domain *domain, + unsigned long iova, size_t size, bool inc) +{ + size_t off, end; + size_t page_size =3D iommu_debug_page_size(domain); + + if (WARN_ON(check_add_overflow(iova, size, &end))) + return; + + for (off =3D 0 ; off < size ; off +=3D page_size) { + phys_addr_t phys =3D iommu_iova_to_phys(domain, iova + off); + + if (!phys || !pfn_valid(__phys_to_pfn(phys))) + continue; + + if (inc) + iommu_debug_inc_page(phys); + else + iommu_debug_dec_page(phys); + } } =20 void __iommu_debug_unmap_begin(struct iommu_domain *domain, unsigned long iova, size_t size) { + __iommu_debug_update_iova(domain, iova, size, false); } =20 void __iommu_debug_unmap_end(struct iommu_domain *domain, unsigned long iova, size_t size, size_t unmapped) { + if ((unmapped =3D=3D size) || WARN_ON_ONCE(unmapped > size)) + return; + + /* If unmap failed, re-increment the refcount. */ + __iommu_debug_update_iova(domain, iova + unmapped, + size - unmapped, true); } =20 void iommu_debug_init(void) --=20 2.52.0.457.g6b5491de43-goog From nobody Sat Feb 7 21:24:53 2026 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4FBE1366542 for ; Fri, 9 Jan 2026 17:18:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767979103; cv=none; b=KinVSiI20kTacOiYqggpce8EX7nHFkhTasgSovycFh2P1kg+SKW7I4lO6t5IpA42kHv2hlj/blUENIzRi6vFCFOLJaHMpnj8jK+baU4Bx9r7iLC33mfO+eNPlZ+yo38PgnX1NDP+co1vtsJvpf1alVSxBgekgaW4AE3qrG24QuQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767979103; c=relaxed/simple; bh=0zzYxycXQ+kI4IOQMPNP1Taa4EJAWWJz6xTPzxIuMvU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=mK0qWnh7Hn+GXsgalBjS+MHtIUo/vBAEc4IXCJ/x3ge4y0pBeobDOY+49Q3+vPSjFqgRmyw9Z1YSw/G/n4IiwopB00F7UYKA2ICnIIkaWIiOfKya71iowRE/zf9KQxCOXVDwzxpP8/zeFfnjaO0cESUg9L/1i34Fjsx5M/K96b8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=UBfgO45E; arc=none smtp.client-ip=209.85.221.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--smostafa.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="UBfgO45E" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-4310062d97bso3174868f8f.0 for ; Fri, 09 Jan 2026 09:18:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1767979096; x=1768583896; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=Z5ROaQbDPNg/Pz9koleFUeugi8CxogCP+iCj0oWGRhs=; b=UBfgO45E24Mj9EGXvzI6Zb3I9acULzhAuukxorGCmY5GWBIa4+I2QCHM8iZhjpIiRv ETFjH2bxpMfI6oki9pFG6XgyJZffdUIz9iWj7OxCo9XXh4PkOGBvBMhHpYC3DBIMIP+o H3Vgo/tCnkQYHrfPIyU34kWBjTfcX2d7ZgRr0/DPZ2ruGoS8Aa/XcIX8ln6+DESZrkmS IruN39YUiViEx8YM0J96JCiebyGj62edtjmyYum1tP9D38kt8x5M2TwA+ij7sCOX0l0u TdYvPfIfmJq+3o9/kp5vGPg8cBzyYP7xjPCIWc+6a9JwZhSlVUEeiIe/kBg2s5Wq0zVD KhKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1767979096; x=1768583896; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=Z5ROaQbDPNg/Pz9koleFUeugi8CxogCP+iCj0oWGRhs=; b=f1dVudUmxxy/tBGFkzFdIDCQYe8Zb9UUGLg/3RcnIZygabOr5pm5hs+6kPPXhWqfy0 xAmqjIupXu4yTBTScIlckYstve9I7GRCHvlIWUuJRtf6ggZNkQ2FqtemN0K2wgMUY7w3 eq/Shl72yc/r22MK7qnbNhHtGz999Fjl+AES1tlWMchGFb+wKyJYfzK30BPOaPosfYWW crgEUSpDmC8j3srYF/mZ4W66me/T5KTMjuBFsBAZgnqOcFLqxar19xO3EYoWJDc/uP25 IMzrEvr+lqCrlVlOkSGcrHck/9Ufe7lSky2UVRR1dH8s2n4MZkVqUVqlyYNLLG1ep77S Pikg== X-Forwarded-Encrypted: i=1; AJvYcCWdQY6Q1BuHALs2Us5/3/lCXvhLI6VStaCRuPP2f8G9TOlKhUobxTry8RGiVlnWyjwyFtXAEJHAGxj3laI=@vger.kernel.org X-Gm-Message-State: AOJu0YyS8CEtGv46FAw8CS7ff0DDGQNoQVbQeXqohz00uQUCHjlpDuEU cNXgJRId+bkjBKpiE6AwUNsb0btSF0X4gU4rYyZiAy6ju6+wtjbITYB4F4nbDj8n7svWCPW6JVN Sw6bFYWrXFMEg1g== X-Google-Smtp-Source: AGHT+IGOoyMNz9SX5heA0+Ad8u3Mb3ue4F3q3Dm7Zb68ZiR2w+PZXKYiFFyi252YwvzslTXfx08Zaf+yul64YA== X-Received: from wmcq2.prod.google.com ([2002:a05:600c:c102:b0:47b:daaa:51cf]) (user=smostafa job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:458e:b0:47b:e29f:e067 with SMTP id 5b1f17b1804b1-47d84b0b21dmr111247725e9.6.1767979096375; Fri, 09 Jan 2026 09:18:16 -0800 (PST) Date: Fri, 9 Jan 2026 17:18:05 +0000 In-Reply-To: <20260109171805.901995-1-smostafa@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260109171805.901995-1-smostafa@google.com> X-Mailer: git-send-email 2.52.0.457.g6b5491de43-goog Message-ID: <20260109171805.901995-5-smostafa@google.com> Subject: [PATCH v6 4/4] iommu: debug-pagealloc: Check mapped/unmapped kernel memory From: Mostafa Saleh To: linux-mm@kvack.org, iommu@lists.linux.dev, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org Cc: corbet@lwn.net, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, akpm@linux-foundation.org, vbabka@suse.cz, surenb@google.com, mhocko@suse.com, jackmanb@google.com, hannes@cmpxchg.org, ziy@nvidia.com, david@redhat.com, lorenzo.stoakes@oracle.com, Liam.Howlett@oracle.com, rppt@kernel.org, xiaqinxin@huawei.com, baolu.lu@linux.intel.com, rdunlap@infradead.org, Mostafa Saleh , Samiullah Khawaja Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now, as the page_ext holds count of IOMMU mappings, we can use it to assert that any page allocated/freed is indeed not in the IOMMU. The sanitizer doesn=E2=80=99t protect against mapping/unmapping during this period. However, that=E2=80=99s less harmful as the page is not used by the kernel. Reviewed-by: Samiullah Khawaja Reviewed-by: Lu Baolu Signed-off-by: Mostafa Saleh Reviewed-by: Pranjal Shrivastava --- drivers/iommu/iommu-debug-pagealloc.c | 23 +++++++++++++++++++++++ include/linux/iommu-debug-pagealloc.h | 14 ++++++++++++++ include/linux/mm.h | 5 +++++ 3 files changed, 42 insertions(+) diff --git a/drivers/iommu/iommu-debug-pagealloc.c b/drivers/iommu/iommu-de= bug-pagealloc.c index 9eb49e1230ee..c080a38f45a4 100644 --- a/drivers/iommu/iommu-debug-pagealloc.c +++ b/drivers/iommu/iommu-debug-pagealloc.c @@ -9,6 +9,7 @@ #include #include #include +#include =20 #include "iommu-priv.h" =20 @@ -73,6 +74,28 @@ static size_t iommu_debug_page_size(struct iommu_domain = *domain) return 1UL << __ffs(domain->pgsize_bitmap); } =20 +static bool iommu_debug_page_count(const struct page *page) +{ + unsigned int ref; + struct page_ext *page_ext =3D page_ext_get(page); + struct iommu_debug_metadata *d =3D get_iommu_data(page_ext); + + ref =3D atomic_read(&d->ref); + page_ext_put(page_ext); + return ref !=3D 0; +} + +void __iommu_debug_check_unmapped(const struct page *page, int numpages) +{ + while (numpages--) { + if (WARN_ON(iommu_debug_page_count(page))) { + pr_warn("iommu: Detected page leak!\n"); + dump_page_owner(page); + } + page++; + } +} + void __iommu_debug_map(struct iommu_domain *domain, phys_addr_t phys, size= _t size) { size_t off, end; diff --git a/include/linux/iommu-debug-pagealloc.h b/include/linux/iommu-de= bug-pagealloc.h index a439d6815ca1..46c3c1f70150 100644 --- a/include/linux/iommu-debug-pagealloc.h +++ b/include/linux/iommu-debug-pagealloc.h @@ -13,6 +13,20 @@ DECLARE_STATIC_KEY_FALSE(iommu_debug_initialized); =20 extern struct page_ext_operations page_iommu_debug_ops; =20 +void __iommu_debug_check_unmapped(const struct page *page, int numpages); + +static inline void iommu_debug_check_unmapped(const struct page *page, int= numpages) +{ + if (static_branch_unlikely(&iommu_debug_initialized)) + __iommu_debug_check_unmapped(page, numpages); +} + +#else +static inline void iommu_debug_check_unmapped(const struct page *page, + int numpages) +{ +} + #endif /* CONFIG_IOMMU_DEBUG_PAGEALLOC */ =20 #endif /* __LINUX_IOMMU_DEBUG_PAGEALLOC_H */ diff --git a/include/linux/mm.h b/include/linux/mm.h index 6f959d8ca4b4..32205d2a24b2 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -36,6 +36,7 @@ #include #include #include +#include =20 struct mempolicy; struct anon_vma; @@ -4133,12 +4134,16 @@ extern void __kernel_map_pages(struct page *page, i= nt numpages, int enable); #ifdef CONFIG_DEBUG_PAGEALLOC static inline void debug_pagealloc_map_pages(struct page *page, int numpag= es) { + iommu_debug_check_unmapped(page, numpages); + if (debug_pagealloc_enabled_static()) __kernel_map_pages(page, numpages, 1); } =20 static inline void debug_pagealloc_unmap_pages(struct page *page, int nump= ages) { + iommu_debug_check_unmapped(page, numpages); + if (debug_pagealloc_enabled_static()) __kernel_map_pages(page, numpages, 0); } --=20 2.52.0.457.g6b5491de43-goog