The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH v3 00/26] Introduce meminspect
@ 2026-07-08  5:31 Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 01/26] kernel: " Mukesh Ojha
                   ` (27 more replies)
  0 siblings, 28 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

First of all, I want to thank Eugene for his excellent work on this
series. What began as the Qualcomm Minidump driver from me has now
evolved into meminspect. He also presented meminspect at Linux
Plumbers 2025.

Video of the recording is available here for anyone interested:
https://www.youtube.com/watch?v=aDZv4-kOLSc

Introduction: Memory inspection mechanism

meminspect is a mechanism which allows the kernel to mark specific
memory areas for memory dumping or specific inspection, statistics,
usage.  Once regions are marked, meminspect keeps an internal list with
the regions in a dedicated table.  Further, these regions can be
accessed using specific API by any interested driver.  Regions being
marked beforehand, when the system is up and running, there is no need
nor dependency on a panic handler, or a working kernel that can dump the
debug information.  meminspect can be primarily used for debugging. The
approach is feasible to work when pstore, kdump, or another mechanism do
not. Pstore relies on persistent storage, a dedicated RAM area or
flash, which has the disadvantage of having the memory reserved all the
time, or another specific non volatile memory. Some devices cannot keep
the RAM contents on reboot so ramoops does not work. Some devices do not
allow kexec to run another kernel to debug the crashed one.  For such
devices, that have another mechanism to help debugging, like firmware,
meminspect is a viable solution.

meminspect can create a core image, similar with /proc/vmcore, with only
the registered regions included. This can be loaded into crash tool/gdb
and analyzed. This happens if CRASH_DUMP=y.  To have this working,
specific information from the kernel is registered, and this is done at
meminspect init time, no need for the meminspect users to do anything.

This version of the meminspect patch series includes two drivers that
make use of it: one is the Qualcomm Minidump, and the other one is the
Debug Kinfo backend for Android devices, reworked from this source here:
https://android.googlesource.com/kernel/common/+/refs/heads/android-mainline/drivers/android/debug_kinfo.c
written originally by Jone Chou <jonechou@google.com>

Tested on Qualcomm SA8775P (Lemans EVK) on next-20260707 with the
minidump backend: kernel crash dump regions correctly captured
via firmware.

This series introduces a new cross-subsystem framework and, to
avoid merge ordering issues, I suggest the entire series be taken
via the mm tree. Subsystem maintainers for touched files have
been CC'd; I request an Acked-by from them if the respective
patches look fine from their side.

Alternatively, the qcom backend patches (22-24) can be deferred
to Bjorn's qcom tree in a follow-on series once the core
meminspect framework lands.

*** How to use meminspect with minidump backend on Qualcomm platform guide ***

Prerequisites:
Crash tool compiled with target=ARM64.

Target kernel must be built with: CONFIG_DEBUG_INFO_REDUCED=n;
this will have vmlinux include all the debugging information
needed for the crash tool and CONFIG_MEMINSPECT,
CONFIG_CRASH_DUMP, and the driver CONFIG_QCOM_MINIDUMP.
Kernel arguments: Kernel firmware must be set to mode 'mini' by kernel
module parameter like this : qcom_scm.download_mode=mini

After the kernel boots and the minidump module is loaded,
everything is ready for a possible crash. Upon triggering a
forced kernel crash, the target board will wait in download mode,
where QDL (https://github.com/linux-msm/qdl) running on the host
connected to the target (here, Lemans EVK) can be used to collect
minidump.elf from the target device onto the host.

Currently, --minimal mode is being used to get dmesg log from
crashed device.

Without --minimal mode, the crash tool needs to be patched to
not crash on missing symbols and needs to be tuned, which I am
currently working on in parallel.

crash> log
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x514f0014]
[    0.000000] Linux version 7.0.0-rc3-next-20260309-00028-g528b3c656121 (@21e3bca4168f) (aarch64-linux-gnu-gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #5 SMP PREEMPT Tue Mar 10 18:18:41 UTC 2026

*** Debug Kinfo backend driver ***
I need help with the testing of this driver, Anyone who actually wants
to test this, feel free to reply to the patch. we have also written a
simple DT binding for the driver.

Thanks in advance for the review, and apologies if I missed addressing any comment.

-Mukesh

Changes in v3: https://lore.kernel.org/lkml/20260311-minidump-v2-v2-0-f91cedc6f99e@oss.qualcomm.com/
- Addressed most of doc. comments and binding and 0-day kernel
  test robot warning.
- Add timekeeping: Register tk_data into meminspect
- fixed some of the bugs identified during testing.
- Fix missing return before dev_err_probe() in qcom_md_probe(); all
  three error paths (SMEM lookup, table validation, table init) now
  correctly abort probe on failure
- Fix meminspect_traverse() kernel-doc: @priv description corrected
- Fix meminspect.rst: replace stale MEMINSPECT_ITERATOR_CB type name
  with the actual meminspect_iter_cb_t typedef
- Add kernel-doc for meminspect_iter_cb_t typedef
- Lot of code formating and style change as per coding standard.

Changes in v2: https://lore.kernel.org/lkml/20251119154427.1033475-1-eugen.hristev@linaro.org/
 - Fixed doc warnings
 - Fixed kernel-test robot warnings.
 - Took Mike suggestion to remove mark inspect flag for dynamic memory.
 - Added R-b for printk patch.
 - Modified some commit messages for clarity.
 - corrected binding change for debug-kinfo as per Rob suggestion.

Changelog for meminspect v1:
- rename to meminspect
- start on top of v2 actually, with the section and all.
- remove the backend thing, change the API to access the table
- move everything to kernel/
- add dependency to CRASH_DUMP instead of a separate knob
- move the minidump driver to soc/qcom
- integrate the meminspect better into memblock by using a new memblock flag
- minor fixes : use dev_err_probe everywhere, rearrange variable declarations,
remove some useless code, etc.

Changelog for RFC v3:
- V2 available here : https://lore.kernel.org/all/20250724135512.518487-1-eugen.hristev@linaro.org/
- Removed the .section as requested by David Hildenbrand.
- Moved all kmemdump registration(when possible) to vmcoreinfo.
- Because of this, some of the variables that I was registering had to be non-static
so I had to modify this as per David Hildenbrand suggestion.
- Fixed minor things in the Kinfo driver: one field was broken, fixed some
compiler warnings, fixed the copyright and remove some useless includes.
- Moved the whole kmemdump from drivers/debug into mm/ and Kconfigs into mm/Kconfig.debug
and it's now available in kernel hacking, as per Randy Dunlap review
- Reworked some of the Documentation as per review from Jon Corbet

Changelog for RFC v2:
- V1 available here: https://lore.kernel.org/lkml/20250422113156.575971-1-eugen.hristev@linaro.org/
- Reworked the whole minidump implementation based on suggestions from Thomas Gleixner.
This means new API, macros, new way to store the regions inside kmemdump
(ditched the IDR, moved to static allocation, have a static default backend, etc)
- Reworked qcom_minidump driver based on review from Bjorn Andersson
- Reworked printk log buffer registration based on review from Petr Mladek.

---
Eugen Hristev (21):
      kernel: Introduce meminspect
      init/version: Annotate static information into meminspect
      mm/percpu: Annotate static information into meminspect
      cpu: Annotate static information into meminspect
      genirq/irqdesc: Annotate static information into meminspect
      timers: Annotate static information into meminspect
      kernel/fork: Annotate static information into meminspect
      mm/page_alloc: Annotate static information into meminspect
      mm/show_mem: Annotate static information into meminspect
      mm/swapfile: Annotate static information into meminspect
      kernel/vmcore_info: Register dynamic information into meminspect
      kernel/configs: Register dynamic information into meminspect
      mm/init-mm: Annotate static information into meminspect
      panic: Annotate static information into meminspect
      kallsyms: Annotate static information into meminspect
      mm/mm_init: Annotate static information into meminspect
      sched/core: Annotate runqueues into meminspect
      remoteproc: qcom: Move minidump data structures into its own header
      soc: qcom: Add minidump backend driver
      soc: qcom: smem: Add minidump platform device
      meminspect: Add debug kinfo compatible driver

Mukesh Ojha (5):
      timekeeping: Register tk_data into meminspect
      mm/numa: Register node data information into meminspect
      mm/sparse: Register information into meminspect
      printk: Register information into meminspect
      dt-bindings: reserved-memory: Add Google Kinfo Pixel reserved memory

 Documentation/dev-tools/index.rst                  |   1 +
 Documentation/dev-tools/meminspect.rst             | 144 +++++++
 .../reserved-memory/google,debug-kinfo.yaml        |  48 +++
 MAINTAINERS                                        |  16 +
 drivers/of/platform.c                              |   1 +
 drivers/remoteproc/qcom_common.c                   |  55 +--
 drivers/soc/qcom/Kconfig                           |  13 +
 drivers/soc/qcom/Makefile                          |   1 +
 drivers/soc/qcom/minidump.c                        | 271 ++++++++++++
 drivers/soc/qcom/smem.c                            |  10 +
 include/asm-generic/vmlinux.lds.h                  |  13 +
 include/linux/meminspect.h                         | 271 ++++++++++++
 include/linux/soc/qcom/minidump.h                  |  70 +++
 init/Kconfig                                       |   1 +
 init/version-timestamp.c                           |   3 +
 init/version.c                                     |   3 +
 kernel/Makefile                                    |   1 +
 kernel/configs.c                                   |   6 +
 kernel/cpu.c                                       |   5 +
 kernel/fork.c                                      |   3 +
 kernel/irq/irqdesc.c                               |   2 +
 kernel/kallsyms.c                                  |   9 +
 kernel/meminspect/Kconfig                          |  29 ++
 kernel/meminspect/Makefile                         |   4 +
 kernel/meminspect/kinfo.c                          | 257 +++++++++++
 kernel/meminspect/meminspect.c                     | 474 +++++++++++++++++++++
 kernel/panic.c                                     |   4 +
 kernel/printk/printk.c                             |  12 +
 kernel/sched/core.c                                |   2 +
 kernel/time/timekeeping.c                          |   2 +
 kernel/time/timer.c                                |   2 +
 kernel/vmcore_info.c                               |   4 +
 mm/init-mm.c                                       |  12 +
 mm/mm_init.c                                       |   2 +
 mm/numa.c                                          |   2 +
 mm/page_alloc.c                                    |   2 +
 mm/percpu.c                                        |   5 +
 mm/show_mem.c                                      |   2 +
 mm/sparse.c                                        |   3 +
 mm/swapfile.c                                      |   2 +
 40 files changed, 1713 insertions(+), 54 deletions(-)
---
base-commit: 5c73cd9f0819c1c44e373e3dabb68318b1de1a12
change-id: 20260708-meminspect-v3-76dd8166c4f1

Best regards,
-- 
-Mukesh Ojha


^ permalink raw reply	[flat|nested] 46+ messages in thread

* [PATCH v3 01/26] kernel: Introduce meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  7:38   ` Lorenzo Stoakes
  2026-07-08  5:31 ` [PATCH v3 02/26] init/version: Annotate static information into meminspect Mukesh Ojha
                   ` (26 subsequent siblings)
  27 siblings, 1 reply; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Memory inspection mechanism allows registration of a specific
memory area (or object) for later inspection purposes. Ranges are
added into an inspection table, which can be requested and
analyzed by specific drivers. Drivers would interface with any
hardware mechanism that will allow inspection of the data,
including but not limited to: dumping for debugging, creating a
core dump, analysis, or statistical information. Drivers can
register a notifier to know when new objects are registered, or
to traverse an existing inspection table. The inspection table is
created ahead of time such that it can be later used regardless
of the state of the kernel (running, frozen, crashed, or any
particular state).

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 Documentation/dev-tools/index.rst      |   1 +
 Documentation/dev-tools/meminspect.rst | 144 ++++++++++
 MAINTAINERS                            |   9 +
 include/asm-generic/vmlinux.lds.h      |  13 +
 include/linux/meminspect.h             | 270 +++++++++++++++++++
 init/Kconfig                           |   1 +
 kernel/Makefile                        |   1 +
 kernel/meminspect/Kconfig              |  18 ++
 kernel/meminspect/Makefile             |   3 +
 kernel/meminspect/meminspect.c         | 474 +++++++++++++++++++++++++++++++++
 10 files changed, 934 insertions(+)

diff --git a/Documentation/dev-tools/index.rst b/Documentation/dev-tools/index.rst
index 59cbb77b33ff..ea2989ca1566 100644
--- a/Documentation/dev-tools/index.rst
+++ b/Documentation/dev-tools/index.rst
@@ -40,3 +40,4 @@ Documentation/process/debugging/index.rst
    autofdo
    propeller
    container
+   meminspect
diff --git a/Documentation/dev-tools/meminspect.rst b/Documentation/dev-tools/meminspect.rst
new file mode 100644
index 000000000000..4ca10e33e4fd
--- /dev/null
+++ b/Documentation/dev-tools/meminspect.rst
@@ -0,0 +1,144 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==========
+meminspect
+==========
+
+This document provides information about the meminspect feature.
+
+Overview
+========
+
+meminspect is a mechanism that allows the kernel to register a chunk of
+memory into a table, to be used at a later time for a specific
+inspection purpose like debugging, memory dumping or statistics.
+
+meminspect allows drivers to traverse the inspection table on demand,
+or to register a notifier to be called whenever a new entry is being added
+or removed.
+
+The reasoning for meminspect is also to minimize the required information
+in case of a kernel problem. For example a traditional debug method involves
+dumping the whole kernel memory and then inspecting it. Meminspect allows the
+users to select which memory is of interest, in order to help this specific
+use case in production, where memory and connectivity are limited.
+
+Although the kernel has multiple internal mechanisms, meminspect fits
+a particular model which is not covered by the others.
+
+meminspect Internals
+====================
+
+API
+---
+
+Static memory can be registered at compile time, by instructing the compiler
+to create a separate section with annotation info.
+For each such annotated memory (variables usually), a dedicated struct
+is created with the required information.
+To achieve this goal, some basic APIs are available:
+
+* MEMINSPECT_ENTRY(idx, sym, sz)
+  is the basic macro that takes an ID, the symbol, and a size.
+
+To make it easier, some wrappers are also defined
+
+* MEMINSPECT_SIMPLE_ENTRY(sym)
+  uses the dedicated MEMINSPECT_ID_##sym with a size equal to sizeof(sym)
+
+* MEMINSPECT_NAMED_ENTRY(name, sym)
+  is a simple entry that has an id that cannot be derived from the sym,
+  so a name has to be provided
+
+* MEMINSPECT_AREA_ENTRY(sym, sz)
+  registers sym, but with the size given as sz, useful for e.g.
+  arrays which do not have a fixed size at compile time.
+
+For dynamically allocated memory, or for other cases, the following APIs
+are defined::
+
+  meminspect_register_id_pa(enum meminspect_uid id, phys_addr_t zone,
+                            size_t size, unsigned int type);
+
+which takes the ID and the physical address.
+
+Similarly there are variations:
+
+ * meminspect_register_pa() omits the ID
+ * meminspect_register_id_va() requires the ID but takes a virtual address
+ * meminspect_register_va() omits the ID and requires a virtual address
+
+If the ID is not given, the next available dynamic ID is allocated.
+
+To unregister a dynamic entry, some APIs are defined:
+ * meminspect_unregister_pa(phys_addr_t zone, size_t size);
+ * meminspect_unregister_id(enum meminspect_uid id);
+ * meminspect_unregister_va(va, size);
+
+All of the above have a lock variant that ensures the lock on the table
+is taken.
+
+
+meminspect drivers
+------------------
+
+Drivers are free to traverse the table by using a dedicated function::
+
+ meminspect_traverse(void *priv, meminspect_iter_cb_t cb)
+
+The callback is called for each entry in the table.
+
+Drivers can also register a notifier with meminspect_notifier_register()
+and unregister with meminspect_notifier_unregister() to be called when a new
+entry is added or removed.
+
+Data structures
+---------------
+
+The regions are stored in a simple fixed size array. It avoids
+memory allocation overhead. This is not performance critical nor does
+allocating a few hundred entries create a memory consumption problem.
+
+The static variables registered into meminspect are annotated into
+a dedicated .inspect_table memory section. This is then walked by meminspect
+at a later time and each variable is then copied to the whole inspect table.
+
+meminspect Initialization
+-------------------------
+
+At any time, meminspect is ready to accept region registration
+from any part of the kernel. The table does not require any initialization.
+In case CONFIG_CRASH_DUMP is enabled, meminspect creates an ELF header
+corresponding to a core dump image, in which each region is added as a
+program header. In this scenario, the first region is this ELF header, and
+the second region is the vmcoreinfo ELF note.
+By using this mechanism, all the meminspect table, if dumped, can be
+concatenated to obtain a core image that is loadable with the `crash` tool.
+
+meminspect example
+==================
+
+A simple scenario for meminspect is the following:
+The kernel registers the linux_banner variable into meminspect with
+a simple annotation like::
+
+  MEMINSPECT_SIMPLE_ENTRY(linux_banner);
+
+The meminspect late initcall will parse the compile-time table
+and copy the entry information into the inspection table.
+At a later point, any interested driver can call the traverse function to
+find out all entries in the table.
+A specific driver will then note into a specific table the address of the
+banner and the size of it.
+The specific table is then written to a shared memory area that can be
+read by upper level firmware.
+When the kernel freezes (hypothetically), the kernel will no longer feed
+the watchdog. The watchdog will trigger a higher exception level interrupt
+which will be handled by the upper level firmware. This firmware will then
+read the shared memory table and find an entry with the start and size of
+the banner. It will then copy it for debugging purpose. The upper level
+firmware will then be able to provide useful debugging information,
+like in this example, the banner.
+
+As seen here, meminspect facilitates the interaction between the kernel
+and a specific firmware.
diff --git a/MAINTAINERS b/MAINTAINERS
index c3f72058a2f2..fdad8ef377c8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16892,6 +16892,15 @@ F:	arch/*/include/asm/sync_core.h
 F:	include/uapi/linux/membarrier.h
 F:	kernel/sched/membarrier.c
 
+MEMINSPECT
+M:	Eugen Hristev <eugen.hristev@linaro.org>
+M:	Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+F:	Documentation/dev-tools/meminspect.rst
+F:	include/linux/meminspect.h
+F:	kernel/meminspect/*
+
 MEMBLOCK AND MEMORY MANAGEMENT INITIALIZATION
 M:	Mike Rapoport <rppt@kernel.org>
 L:	linux-mm@kvack.org
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 5659f4b5a125..3122ddf5517a 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -506,6 +506,8 @@
 	FW_LOADER_BUILT_IN_DATA						\
 	TRACEDATA							\
 									\
+	MEMINSPECT_TABLE						\
+									\
 	PRINTK_INDEX							\
 									\
 	/* Kernel symbol table */					\
@@ -904,6 +906,17 @@
 #define TRACEDATA
 #endif
 
+#ifdef CONFIG_MEMINSPECT
+#define MEMINSPECT_TABLE						\
+	. = ALIGN(8);							\
+	.inspect_table : AT(ADDR(.inspect_table) - LOAD_OFFSET) {	\
+		BOUNDED_SECTION_POST_LABEL(.inspect_table,		\
+					   __inspect_table, , _end)	\
+	}
+#else
+#define MEMINSPECT_TABLE
+#endif
+
 #ifdef CONFIG_PRINTK_INDEX
 #define PRINTK_INDEX							\
 	.printk_index : AT(ADDR(.printk_index) - LOAD_OFFSET) {		\
diff --git a/include/linux/meminspect.h b/include/linux/meminspect.h
new file mode 100644
index 000000000000..a9eb93c6ea2f
--- /dev/null
+++ b/include/linux/meminspect.h
@@ -0,0 +1,270 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _MEMINSPECT_H
+#define _MEMINSPECT_H
+
+#include <asm/page.h>
+#include <linux/notifier.h>
+
+enum meminspect_uid {
+	MEMINSPECT_ID_NONE = 0,
+	MEMINSPECT_ID_ELF,
+	MEMINSPECT_ID_VMCOREINFO,
+	MEMINSPECT_ID_CONFIG,
+	MEMINSPECT_ID__totalram_pages,
+	MEMINSPECT_ID___cpu_possible_mask,
+	MEMINSPECT_ID___cpu_present_mask,
+	MEMINSPECT_ID___cpu_online_mask,
+	MEMINSPECT_ID___cpu_active_mask,
+	MEMINSPECT_ID_mem_section,
+	MEMINSPECT_ID_jiffies_64,
+	MEMINSPECT_ID_linux_banner,
+	MEMINSPECT_ID_nr_threads,
+	MEMINSPECT_ID_total_nr_irqs,
+	MEMINSPECT_ID_tainted_mask,
+	MEMINSPECT_ID_taint_flags,
+	MEMINSPECT_ID_node_states,
+	MEMINSPECT_ID___per_cpu_offset,
+	MEMINSPECT_ID_nr_swapfiles,
+	MEMINSPECT_ID_init_uts_ns,
+	MEMINSPECT_ID_printk_rb_static,
+	MEMINSPECT_ID_printk_rb_dynamic,
+	MEMINSPECT_ID_prb,
+	MEMINSPECT_ID_prb_descs,
+	MEMINSPECT_ID_prb_infos,
+	MEMINSPECT_ID_prb_data,
+	MEMINSPECT_ID_clear_seq,
+	MEMINSPECT_ID_high_memory,
+	MEMINSPECT_ID_init_mm,
+	MEMINSPECT_ID__sinittext,
+	MEMINSPECT_ID__einittext,
+	MEMINSPECT_ID__end,
+	MEMINSPECT_ID__text,
+	MEMINSPECT_ID__stext,
+	MEMINSPECT_ID__etext,
+	MEMINSPECT_ID_kallsyms_num_syms,
+	MEMINSPECT_ID_kallsyms_offsets,
+	MEMINSPECT_ID_kallsyms_names,
+	MEMINSPECT_ID_kallsyms_token_table,
+	MEMINSPECT_ID_kallsyms_token_index,
+	MEMINSPECT_ID_kallsyms_markers,
+	MEMINSPECT_ID_kallsyms_seqs_of_names,
+	MEMINSPECT_ID_swapper_pg_dir,
+	MEMINSPECT_ID_DYNAMIC,
+	MEMINSPECT_ID_MAX = 201,
+};
+
+#define MEMINSPECT_TYPE_REGULAR		0
+
+#define MEMINSPECT_NOTIFIER_ADD		0
+#define MEMINSPECT_NOTIFIER_REMOVE	1
+
+/**
+ * struct inspect_entry - memory inspect entry information
+ * @id: unique id for this entry
+ * @va: virtual address for the memory (pointer)
+ * @pa: physical address for the memory
+ * @size: size of the memory area of this entry
+ * @type: type of the entry (class)
+ */
+struct inspect_entry {
+	enum meminspect_uid	id;
+	void			*va;
+	phys_addr_t		pa;
+	size_t			size;
+	unsigned int		type;
+};
+
+/**
+ * typedef meminspect_iter_cb_t - Iterator callback for meminspect traversal
+ * @priv: private data passed through from the caller of meminspect_traverse()
+ * @ie:   pointer to the current inspect_entry; read-only, table lock held
+ *
+ * The table lock is held by the caller; the callback must not call any
+ * meminspect_table_lock() or meminspect_table_unlock() variants.
+ */
+typedef void (*meminspect_iter_cb_t)(void *priv, const struct inspect_entry *ie);
+
+#ifdef CONFIG_MEMINSPECT
+/* .inspect_table section table markers*/
+extern const struct inspect_entry __inspect_table[];
+extern const struct inspect_entry __inspect_table_end[];
+
+/*
+ * Annotate a static variable into inspection table.
+ * Can be called multiple times for the same ID, in which case
+ * multiple table entries will be created
+ */
+#define MEMINSPECT_ENTRY(idx, sym, sz)						\
+	static const struct inspect_entry __UNIQUE_ID(__inspect_entry_##idx)	\
+	__used __section(".inspect_table") = {					\
+		.id = idx,							\
+		.va = (void *)&(sym),						\
+		.size = (sz),							\
+	}
+/*
+ * A simple entry is just a variable, the size of the entry is the variable size
+ * The variable can also be a pointer, the pointer itself is being added in this
+ * case.
+ */
+#define MEMINSPECT_SIMPLE_ENTRY(sym)	\
+	MEMINSPECT_ENTRY(MEMINSPECT_ID_##sym, sym, sizeof(sym))
+/*
+ * In the case when `sym` is not a variable, but a member of a struct e.g.,
+ * and we cannot derive a name from it, a name must be provided.
+ */
+#define MEMINSPECT_NAMED_ENTRY(name, sym)	\
+	MEMINSPECT_ENTRY(MEMINSPECT_ID_##name, sym, sizeof(sym))
+/*
+ * Create a more complex entry, by registering an arbitrary memory starting
+ * at sym. The size is provided as a parameter.
+ * This is used e.g. when the symbol is a start of an unknown sized array.
+ */
+#define MEMINSPECT_AREA_ENTRY(sym, sz) \
+	MEMINSPECT_ENTRY(MEMINSPECT_ID_##sym, sym, sz)
+
+/* Iterate through .inspect_table section entries */
+#define for_each_meminspect_entry(__entry)		\
+	for (__entry = __inspect_table;			\
+	     __entry < __inspect_table_end;		\
+	     __entry++)
+
+#else
+#define MEMINSPECT_ENTRY(...)
+#define MEMINSPECT_SIMPLE_ENTRY(...)
+#define MEMINSPECT_NAMED_ENTRY(...)
+#define MEMINSPECT_AREA_ENTRY(...)
+#endif
+
+#ifdef CONFIG_MEMINSPECT
+
+/*
+ * Dynamic helpers to register entries.
+ * These do not lock the table, so use with caution.
+ */
+void meminspect_register_id_pa(enum meminspect_uid id, phys_addr_t zone,
+			       size_t size, unsigned int type);
+void meminspect_table_lock(void);
+void meminspect_table_unlock(void);
+
+#define meminspect_register_pa(...) \
+	meminspect_register_id_pa(MEMINSPECT_ID_DYNAMIC, __VA_ARGS__, MEMINSPECT_TYPE_REGULAR)
+
+#define meminspect_register_id_va(id, va, size) \
+	meminspect_register_id_pa(id, virt_to_phys(va), size, MEMINSPECT_TYPE_REGULAR)
+
+#define meminspect_register_va(...) \
+	meminspect_register_id_va(MEMINSPECT_ID_DYNAMIC, __VA_ARGS__)
+
+void meminspect_unregister_pa(phys_addr_t zone, size_t size);
+void meminspect_unregister_id(enum meminspect_uid id);
+
+#define meminspect_unregister_va(va, size) \
+	meminspect_unregister_pa(virt_to_phys(va), size)
+
+void meminspect_traverse(void *priv, meminspect_iter_cb_t cb);
+
+/*
+ * Producers, or registrators, are advised to use the locked API below
+ */
+#define meminspect_lock_register_pa(...)			\
+	do {							\
+		meminspect_table_lock();			\
+		meminspect_register_pa(__VA_ARGS__);		\
+		meminspect_table_unlock();			\
+	} while (0)
+
+#define meminspect_lock_register_id_va(...)			\
+	do {							\
+		meminspect_table_lock();			\
+		meminspect_register_id_va(__VA_ARGS__);		\
+		meminspect_table_unlock();			\
+	} while (0)
+
+#define meminspect_lock_register_va(...)			\
+	do {							\
+		meminspect_table_lock();			\
+		meminspect_register_va(__VA_ARGS__);		\
+		meminspect_table_unlock();			\
+	} while (0)
+
+#define meminspect_lock_unregister_pa(...)			\
+	do {							\
+		meminspect_table_lock();			\
+		meminspect_unregister_pa(__VA_ARGS__);		\
+		meminspect_table_unlock();			\
+	} while (0)
+
+#define meminspect_lock_unregister_va(...)			\
+	do {							\
+		meminspect_table_lock();			\
+		meminspect_unregister_va(__VA_ARGS__);		\
+		meminspect_table_unlock();			\
+	} while (0)
+
+#define meminspect_lock_unregister_id(...)			\
+	do {							\
+		meminspect_table_lock();			\
+		meminspect_unregister_id(__VA_ARGS__);		\
+		meminspect_table_unlock();			\
+	} while (0)
+
+#define meminspect_lock_traverse(...)				\
+	do {							\
+		meminspect_table_lock();			\
+		meminspect_traverse(__VA_ARGS__);		\
+		meminspect_table_unlock();			\
+	} while (0)
+
+int meminspect_notifier_register(struct notifier_block *n);
+int meminspect_notifier_unregister(struct notifier_block *n);
+
+#else
+static inline void meminspect_register_id_pa(enum meminspect_uid id,
+					     phys_addr_t zone,
+					     size_t size, unsigned int type)
+{
+}
+
+static inline void meminspect_table_lock(void)
+{
+}
+
+static inline void meminspect_table_unlock(void)
+{
+}
+
+static inline void meminspect_unregister_pa(phys_addr_t zone, size_t size)
+{
+}
+
+static inline void meminspect_unregister_id(enum meminspect_uid id)
+{
+}
+
+static inline void meminspect_traverse(void *priv, meminspect_iter_cb_t cb)
+{
+}
+
+static inline int meminspect_notifier_register(struct notifier_block *n)
+{
+	return 0;
+}
+
+static inline int meminspect_notifier_unregister(struct notifier_block *n)
+{
+	return 0;
+}
+
+#define meminspect_register_pa(...)		do { } while (0)
+#define meminspect_register_id_va(...)		do { } while (0)
+#define meminspect_register_va(...)		do { } while (0)
+#define meminspect_lock_register_pa(...)	do { } while (0)
+#define meminspect_lock_register_va(...)	do { } while (0)
+#define meminspect_lock_register_id_va(...)	do { } while (0)
+#define meminspect_lock_traverse(...)		do { } while (0)
+#define meminspect_lock_unregister_va(...)	do { } while (0)
+#define meminspect_lock_unregister_pa(...)	do { } while (0)
+#define meminspect_lock_unregister_id(...)	do { } while (0)
+#endif
+
+#endif
diff --git a/init/Kconfig b/init/Kconfig
index fa42fb264c9c..adbe607b7b62 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -2294,6 +2294,7 @@ config TRACEPOINTS
 source "kernel/Kconfig.kexec"
 
 source "kernel/liveupdate/Kconfig"
+source "kernel/meminspect/Kconfig"
 
 endmenu		# General setup
 
diff --git a/kernel/Makefile b/kernel/Makefile
index 1e1a31673577..7c74a4f94a81 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -52,6 +52,7 @@ obj-y += locking/
 obj-y += power/
 obj-y += printk/
 obj-y += irq/
+obj-y += meminspect/
 obj-y += rcu/
 obj-y += livepatch/
 obj-y += liveupdate/
diff --git a/kernel/meminspect/Kconfig b/kernel/meminspect/Kconfig
new file mode 100644
index 000000000000..18ff511ad4cf
--- /dev/null
+++ b/kernel/meminspect/Kconfig
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config MEMINSPECT
+	bool "Allow the kernel to register memory regions for inspection purpose"
+	depends on !CRASH_DUMP || DMA_CMA
+	help
+	  Inspection mechanism allows registration of a specific memory
+	  area (or object) for later inspection purposes. Ranges are added
+	  into an inspection table, which can be requested and analyzed by
+	  specific drivers. Drivers would interface any hardware mechanism
+	  that will allow inspection of the data, including but not limited
+	  to: dumping for debugging, creating a coredump, analysis, or
+	  statistical information.  The inspection table is created ahead
+	  of time such that it can be later used regardless of the state of
+	  the kernel (running, frozen, crashed, or any particular state).
+
+	  Note that modules using this feature must be rebuilt if this
+	  option changes.
diff --git a/kernel/meminspect/Makefile b/kernel/meminspect/Makefile
new file mode 100644
index 000000000000..09fd55e6d9cf
--- /dev/null
+++ b/kernel/meminspect/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_MEMINSPECT) += meminspect.o
diff --git a/kernel/meminspect/meminspect.c b/kernel/meminspect/meminspect.c
new file mode 100644
index 000000000000..d9d38f484f1f
--- /dev/null
+++ b/kernel/meminspect/meminspect.c
@@ -0,0 +1,474 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/crash_core.h>
+#include <linux/dma-map-ops.h>
+#include <linux/errno.h>
+#include <linux/meminspect.h>
+#include <linux/notifier.h>
+#include <linux/vmcore_info.h>
+
+static DEFINE_MUTEX(meminspect_lock);
+static struct inspect_entry inspect_entries[MEMINSPECT_ID_MAX];
+
+static ATOMIC_NOTIFIER_HEAD(meminspect_notifier_list);
+
+#ifdef CONFIG_CRASH_DUMP
+
+#define CORE_STR "CORE"
+
+static struct elfhdr *ehdr;
+static size_t elf_offset;
+static bool elf_hdr_ready;
+
+static void append_kcore_note(char *notes, size_t *i, const char *name,
+			      unsigned int type, const void *desc,
+			      size_t descsz)
+{
+	struct elf_note *note = (struct elf_note *)&notes[*i];
+
+	note->n_namesz = strlen(name) + 1;
+	note->n_descsz = descsz;
+	note->n_type = type;
+	*i += sizeof(*note);
+	memcpy(&notes[*i], name, note->n_namesz);
+	*i = ALIGN(*i + note->n_namesz, 4);
+	memcpy(&notes[*i], desc, descsz);
+	*i = ALIGN(*i + descsz, 4);
+}
+
+static void append_kcore_note_nodesc(char *notes, size_t *i, const char *name,
+				     unsigned int type, size_t descsz)
+{
+	struct elf_note *note = (struct elf_note *)&notes[*i];
+
+	note->n_namesz = strlen(name) + 1;
+	note->n_descsz = descsz;
+	note->n_type = type;
+	*i += sizeof(*note);
+	memcpy(&notes[*i], name, note->n_namesz);
+	*i = ALIGN(*i + note->n_namesz, 4);
+}
+
+static struct elf_phdr *elf_phdr_entry_addr(struct elfhdr *ehdr, int idx)
+{
+	struct elf_phdr *ephdr = (struct elf_phdr *)((size_t)ehdr + ehdr->e_phoff);
+
+	return &ephdr[idx];
+}
+
+static int clear_elfheader(const struct inspect_entry *e)
+{
+	struct elf_phdr *phdr;
+	struct elf_phdr *tmp_phdr;
+	unsigned int phidx;
+	unsigned int i;
+
+	for (i = 0; i < ehdr->e_phnum; i++) {
+		phdr = elf_phdr_entry_addr(ehdr, i);
+		if (phdr->p_paddr == e->pa &&
+		    phdr->p_memsz == ALIGN(e->size, 4))
+			break;
+	}
+
+	if (i == ehdr->e_phnum) {
+		pr_debug("Cannot find program header entry in elf\n");
+		return -EINVAL;
+	}
+
+	phidx = i;
+
+	/* Clear program header */
+	tmp_phdr = elf_phdr_entry_addr(ehdr, phidx);
+	for (i = phidx; i < ehdr->e_phnum - 1; i++) {
+		tmp_phdr = elf_phdr_entry_addr(ehdr, i + 1);
+		phdr = elf_phdr_entry_addr(ehdr, i);
+		memcpy(phdr, tmp_phdr, sizeof(*phdr));
+		phdr->p_offset = phdr->p_offset - ALIGN(e->size, 4);
+	}
+	memset(tmp_phdr, 0, sizeof(*tmp_phdr));
+	ehdr->e_phnum--;
+
+	elf_offset -= ALIGN(e->size, 4);
+
+	return 0;
+}
+
+static void update_elfheader(const struct inspect_entry *e)
+{
+	struct elf_phdr *phdr;
+
+	phdr = elf_phdr_entry_addr(ehdr, ehdr->e_phnum++);
+
+	phdr->p_type = PT_LOAD;
+	phdr->p_offset = elf_offset;
+	phdr->p_vaddr = (elf_addr_t)e->va;
+	if (e->pa)
+		phdr->p_paddr = (elf_addr_t)e->pa;
+	else
+		phdr->p_paddr = (elf_addr_t)virt_to_phys(e->va);
+
+	phdr->p_filesz = ALIGN(e->size, 4);
+	phdr->p_memsz = ALIGN(e->size, 4);
+	phdr->p_flags = PF_R | PF_W;
+	elf_offset += ALIGN(e->size, 4);
+}
+
+/*
+ * This function prepares the elf header for the coredump image.
+ * Initially there is a single program header for the elf NOTE.
+ * The note contains the usual core dump information, and the vmcoreinfo.
+ */
+static int init_elfheader(void)
+{
+	struct elf_phdr *phdr;
+	void *notes;
+	unsigned int elfh_size, buf_sz;
+	unsigned int phdr_off;
+	size_t note_len, i = 0;
+	struct page *p;
+
+	struct elf_prstatus prstatus = {};
+	struct elf_prpsinfo prpsinfo = {
+		.pr_sname = 'R',
+		.pr_fname = "vmlinux",
+	};
+
+	/*
+	 * Header buffer contains:
+	 * ELF header, Note entry with PR status, PR ps info, and vmcoreinfo.
+	 * Also, MEMINSPECT_ID_MAX program headers.
+	 */
+	elfh_size = sizeof(*ehdr);
+	elfh_size += sizeof(struct elf_prstatus);
+	elfh_size += sizeof(struct elf_prpsinfo);
+	elfh_size += sizeof(VMCOREINFO_NOTE_NAME);
+	elfh_size += ALIGN(vmcoreinfo_size, 4);
+	elfh_size += (sizeof(*phdr)) * (MEMINSPECT_ID_MAX);
+
+	elfh_size = ALIGN(elfh_size, 4);
+
+	/* Length of the note is made of :
+	 * 3 elf notes structs (prstatus, prpsinfo, vmcoreinfo)
+	 * 3 notes names (2 core strings, 1 vmcoreinfo name)
+	 * sizeof each note
+	 */
+	note_len = (3 * sizeof(struct elf_note) +
+		    2 * ALIGN(sizeof(CORE_STR), 4) +
+		    VMCOREINFO_NOTE_NAME_BYTES +
+		    ALIGN(sizeof(struct elf_prstatus), 4) +
+		    ALIGN(sizeof(struct elf_prpsinfo), 4) +
+		    ALIGN(vmcoreinfo_size, 4));
+
+	buf_sz = elfh_size + note_len - ALIGN(vmcoreinfo_size, 4);
+
+	/* Never freed */
+	p = dma_alloc_from_contiguous(NULL, buf_sz >> PAGE_SHIFT,
+				      get_order(buf_sz), true);
+	if (!p)
+		return -ENOMEM;
+
+	ehdr = dma_common_contiguous_remap(p, buf_sz,
+					   pgprot_decrypted(pgprot_dmacoherent(PAGE_KERNEL)),
+					   __builtin_return_address(0));
+	if (!ehdr) {
+		dma_release_from_contiguous(NULL, p, buf_sz >> PAGE_SHIFT);
+		return -ENOMEM;
+	}
+
+	memset(ehdr, 0, elfh_size);
+
+	/* Assign Program headers offset, it's right after the elf header. */
+	phdr = (struct elf_phdr *)(ehdr + 1);
+	phdr_off = sizeof(*ehdr);
+
+	memcpy(ehdr->e_ident, ELFMAG, SELFMAG);
+	ehdr->e_ident[EI_CLASS] = ELF_CLASS;
+	ehdr->e_ident[EI_DATA] = ELF_DATA;
+	ehdr->e_ident[EI_VERSION] = EV_CURRENT;
+	ehdr->e_ident[EI_OSABI] = ELF_OSABI;
+	ehdr->e_type = ET_CORE;
+	ehdr->e_machine = ELF_ARCH;
+	ehdr->e_version = EV_CURRENT;
+	ehdr->e_ehsize = sizeof(*ehdr);
+	ehdr->e_phentsize = sizeof(*phdr);
+
+	elf_offset = elfh_size;
+
+	notes = (void *)(((char *)ehdr) + elf_offset);
+
+	/* we have a single program header now */
+	ehdr->e_phnum = 1;
+
+	phdr->p_type = PT_NOTE;
+	phdr->p_offset = elf_offset;
+	phdr->p_filesz = note_len;
+
+	/* advance elf offset */
+	elf_offset += note_len;
+
+	strscpy(prpsinfo.pr_psargs, saved_command_line,
+		sizeof(prpsinfo.pr_psargs));
+
+	append_kcore_note(notes, &i, CORE_STR, NT_PRSTATUS, &prstatus,
+			  sizeof(prstatus));
+	append_kcore_note(notes, &i, CORE_STR, NT_PRPSINFO, &prpsinfo,
+			  sizeof(prpsinfo));
+	append_kcore_note_nodesc(notes, &i, VMCOREINFO_NOTE_NAME, 0,
+				 ALIGN(vmcoreinfo_size, 4));
+
+	ehdr->e_phoff = phdr_off;
+
+	/* This is the first coredump region, the ELF header */
+	meminspect_register_id_pa(MEMINSPECT_ID_ELF, page_to_phys(p),
+				  buf_sz, MEMINSPECT_TYPE_REGULAR);
+
+	/*
+	 * The second region is the vmcoreinfo, which goes right after.
+	 * It's being registered through vmcoreinfo.
+	 */
+
+	return 0;
+}
+#endif
+
+/**
+ * meminspect_unregister_id() - Unregister region from inspection table.
+ * @id: region's id in the table
+ *
+ * Return: None
+ */
+void meminspect_unregister_id(enum meminspect_uid id)
+{
+	struct inspect_entry *e;
+
+	WARN_ON(!mutex_is_locked(&meminspect_lock));
+
+	e = &inspect_entries[id];
+	if (!e->id)
+		return;
+
+	atomic_notifier_call_chain(&meminspect_notifier_list,
+				   MEMINSPECT_NOTIFIER_REMOVE, e);
+#ifdef CONFIG_CRASH_DUMP
+	if (elf_hdr_ready)
+		clear_elfheader(e);
+#endif
+	memset(e, 0, sizeof(*e));
+}
+EXPORT_SYMBOL_GPL(meminspect_unregister_id);
+
+/**
+ * meminspect_unregister_pa() - Unregister region from inspection table.
+ * @pa: Physical address of the memory region to remove
+ * @size: Size of the memory region to remove
+ *
+ * Return: None
+ */
+void meminspect_unregister_pa(phys_addr_t pa, size_t size)
+{
+	struct inspect_entry *e;
+	enum meminspect_uid i;
+
+	WARN_ON(!mutex_is_locked(&meminspect_lock));
+
+	for (i = MEMINSPECT_ID_ELF; i < MEMINSPECT_ID_MAX; i++) {
+		e = &inspect_entries[i];
+		if (e->pa != pa)
+			continue;
+		if (e->size != size)
+			continue;
+		meminspect_unregister_id(e->id);
+		return;
+	}
+}
+EXPORT_SYMBOL_GPL(meminspect_unregister_pa);
+
+/**
+ * meminspect_register_id_pa() - Register region into inspection table
+ *		 with given ID and physical address.
+ * @req_id: Requested unique meminspect_uid that identifies the region
+ *	This can be MEMINSPECT_ID_DYNAMIC, in which case the function will
+ *	find an unused ID and register with it.
+ * @pa: physical address of the memory region
+ * @size: region size
+ * @type: region type
+ *
+ * Return: None
+ */
+void meminspect_register_id_pa(enum meminspect_uid req_id, phys_addr_t pa,
+			       size_t size, unsigned int type)
+{
+	struct inspect_entry *e;
+	enum meminspect_uid uid = req_id;
+
+	WARN_ON(!mutex_is_locked(&meminspect_lock));
+
+	if (uid <= MEMINSPECT_ID_NONE || uid >= MEMINSPECT_ID_MAX)
+		return;
+
+	if (uid == MEMINSPECT_ID_DYNAMIC)
+		while (uid < MEMINSPECT_ID_MAX) {
+			if (!inspect_entries[uid].id)
+				break;
+			uid++;
+		}
+
+	if (uid == MEMINSPECT_ID_MAX)
+		return;
+
+	e = &inspect_entries[uid];
+
+	if (e->id)
+		meminspect_unregister_id(e->id);
+
+	e->pa = pa;
+	e->va = phys_to_virt(pa);
+	e->size = size;
+	e->id = uid;
+	e->type = type;
+#ifdef CONFIG_CRASH_DUMP
+	if (elf_hdr_ready)
+		update_elfheader(e);
+#endif
+	atomic_notifier_call_chain(&meminspect_notifier_list,
+				   MEMINSPECT_NOTIFIER_ADD, e);
+}
+EXPORT_SYMBOL_GPL(meminspect_register_id_pa);
+
+/**
+ * meminspect_table_lock() - Lock the mutex on the inspection table
+ *
+ * Return: None
+ */
+void meminspect_table_lock(void)
+{
+	mutex_lock(&meminspect_lock);
+}
+EXPORT_SYMBOL_GPL(meminspect_table_lock);
+
+/**
+ * meminspect_table_unlock() - Unlock the mutex on the inspection table
+ *
+ * Return: None
+ */
+void meminspect_table_unlock(void)
+{
+	mutex_unlock(&meminspect_lock);
+}
+EXPORT_SYMBOL_GPL(meminspect_table_unlock);
+
+/**
+ * meminspect_traverse() - Traverse the meminspect table and call the
+ *		callback function for each valid entry.
+ * @priv: private data to be passed to the callback
+ * @cb: meminspect iterator callback that should be called for each entry
+ *
+ * Return: None
+ */
+void meminspect_traverse(void *priv, meminspect_iter_cb_t cb)
+{
+	const struct inspect_entry *e;
+	int i;
+
+	WARN_ON(!mutex_is_locked(&meminspect_lock));
+
+	for (i = MEMINSPECT_ID_ELF; i < MEMINSPECT_ID_MAX; i++) {
+		e = &inspect_entries[i];
+		if (e->id)
+			cb(priv, e);
+	}
+}
+EXPORT_SYMBOL_GPL(meminspect_traverse);
+
+/**
+ * meminspect_notifier_register() - Register a notifier to meminspect table
+ * @n: notifier block to register. This will be called whenever an entry
+ *		is being added or removed.
+ *
+ * Return: errno
+ */
+int meminspect_notifier_register(struct notifier_block *n)
+{
+	return atomic_notifier_chain_register(&meminspect_notifier_list, n);
+}
+EXPORT_SYMBOL_GPL(meminspect_notifier_register);
+
+/**
+ * meminspect_notifier_unregister() - Unregister a previously registered
+ *		notifier from meminspect table.
+ * @n: notifier block to unregister.
+ *
+ * Return: errno
+ */
+int meminspect_notifier_unregister(struct notifier_block *n)
+{
+	return atomic_notifier_chain_unregister(&meminspect_notifier_list, n);
+}
+EXPORT_SYMBOL_GPL(meminspect_notifier_unregister);
+
+#ifdef CONFIG_CRASH_DUMP
+static int __init meminspect_prepare_crashdump(void)
+{
+	const struct inspect_entry *e;
+	int ret;
+	enum meminspect_uid i;
+
+	ret = init_elfheader();
+
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Some regions may have been registered very early.
+	 * Update the elf header for all existing regions,
+	 * except for MEMINSPECT_ID_ELF and MEMINSPECT_ID_VMCOREINFO,
+	 * those are included in the ELF header upon its creation.
+	 */
+	for (i = MEMINSPECT_ID_VMCOREINFO + 1; i < MEMINSPECT_ID_MAX; i++) {
+		e = &inspect_entries[i];
+		if (e->id)
+			update_elfheader(e);
+	}
+
+	elf_hdr_ready = true;
+
+	return 0;
+}
+#endif
+
+static int __init meminspect_prepare_table(void)
+{
+	const struct inspect_entry *e;
+	enum meminspect_uid i;
+	int ret;
+
+	meminspect_table_lock();
+	/*
+	 * First, copy all entries from the compiler built table
+	 * In case some entries are registered multiple times,
+	 * the last chronological entry will be stored.
+	 * Previously registered entries will be dropped.
+	 */
+	for_each_meminspect_entry(e) {
+		inspect_entries[e->id] = *e;
+		if (!inspect_entries[e->id].pa && inspect_entries[e->id].va)
+			inspect_entries[e->id].pa = virt_to_phys(inspect_entries[e->id].va);
+	}
+#ifdef CONFIG_CRASH_DUMP
+	ret = meminspect_prepare_crashdump();
+	if (ret)
+		pr_warn("meminspect: failed to prepare crashdump ELF header: %d\n", ret);
+#endif
+	/* if we have early notifiers registered, call them now */
+	for (i = MEMINSPECT_ID_ELF; i < MEMINSPECT_ID_MAX; i++)
+		if (inspect_entries[i].id)
+			atomic_notifier_call_chain(&meminspect_notifier_list,
+						   MEMINSPECT_NOTIFIER_ADD,
+						   &inspect_entries[i]);
+	meminspect_table_unlock();
+
+	pr_debug("Memory inspection table initialized\n");
+
+	return 0;
+}
+late_initcall(meminspect_prepare_table);

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 02/26] init/version: Annotate static information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 01/26] kernel: " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 03/26] mm/percpu: " Mukesh Ojha
                   ` (25 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate vital static information into inspection table:
 - init_uts_ns
 - linux_banner

Information on these variables is stored in a dedicated meminspect
section.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 init/version-timestamp.c | 3 +++
 init/version.c           | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/init/version-timestamp.c b/init/version-timestamp.c
index 375726e05f69..37bdcdd443f9 100644
--- a/init/version-timestamp.c
+++ b/init/version-timestamp.c
@@ -6,6 +6,7 @@
 #include <linux/refcount.h>
 #include <linux/uts.h>
 #include <linux/utsname.h>
+#include <linux/meminspect.h>
 
 struct uts_namespace init_uts_ns = {
 	.ns = NS_COMMON_INIT(init_uts_ns),
@@ -24,3 +25,5 @@ struct uts_namespace init_uts_ns = {
 const char linux_banner[] =
 	"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
 	LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
+
+MEMINSPECT_SIMPLE_ENTRY(linux_banner);
diff --git a/init/version.c b/init/version.c
index 94c96f6fbfe6..eeb139236562 100644
--- a/init/version.c
+++ b/init/version.c
@@ -16,6 +16,7 @@
 #include <linux/uts.h>
 #include <linux/utsname.h>
 #include <linux/proc_ns.h>
+#include <linux/meminspect.h>
 
 static int __init early_hostname(char *arg)
 {
@@ -51,4 +52,6 @@ const char linux_banner[] __weak;
 
 #include "version-timestamp.c"
 
+MEMINSPECT_SIMPLE_ENTRY(init_uts_ns);
+
 EXPORT_SYMBOL_GPL(init_uts_ns);

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 03/26] mm/percpu: Annotate static information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 01/26] kernel: " Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 02/26] init/version: Annotate static information into meminspect Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 04/26] cpu: " Mukesh Ojha
                   ` (24 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate vital static information in meminspect:
 - __per_cpu_offset

Information on these annotated variables is stored in a dedicated
meminspect section.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 mm/percpu.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/mm/percpu.c b/mm/percpu.c
index a802d72c116f..5b1c87e46273 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -87,6 +87,7 @@
 #include <linux/sched.h>
 #include <linux/sched/mm.h>
 #include <linux/memcontrol.h>
+#include <linux/meminspect.h>
 
 #include <asm/cacheflush.h>
 #include <asm/sections.h>
@@ -3367,6 +3368,10 @@ void __init setup_per_cpu_areas(void)
 
 #endif	/* CONFIG_SMP */
 
+#if defined(CONFIG_SMP) && !defined(__per_cpu_offset)
+MEMINSPECT_SIMPLE_ENTRY(__per_cpu_offset);
+#endif
+
 /*
  * pcpu_nr_pages - calculate total number of populated backing pages
  *

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 04/26] cpu: Annotate static information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (2 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 03/26] mm/percpu: " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 05/26] genirq/irqdesc: " Mukesh Ojha
                   ` (23 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate vital static information into memory inspection table:
 - __cpu_present_mask
 - __cpu_online_mask
 - __cpu_possible_mask
 - __cpu_active_mask

Information on these annotated variables is stored in a dedicated
meminspect section.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 kernel/cpu.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index b3c8553d7bd6..01c86510124f 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -37,6 +37,7 @@
 #include <linux/random.h>
 #include <linux/cc_platform.h>
 #include <linux/parser.h>
+#include <linux/meminspect.h>
 
 #include <trace/events/power.h>
 #define CREATE_TRACE_POINTS
@@ -3083,19 +3084,23 @@ struct cpumask __cpu_possible_mask __ro_after_init;
 unsigned int __num_possible_cpus __ro_after_init;
 #endif
 EXPORT_SYMBOL(__cpu_possible_mask);
+MEMINSPECT_SIMPLE_ENTRY(__cpu_possible_mask);
 EXPORT_SYMBOL(__num_possible_cpus);
 
 struct cpumask __cpu_online_mask __read_mostly;
 EXPORT_SYMBOL(__cpu_online_mask);
+MEMINSPECT_SIMPLE_ENTRY(__cpu_online_mask);
 
 struct cpumask __cpu_enabled_mask __read_mostly;
 EXPORT_SYMBOL(__cpu_enabled_mask);
 
 struct cpumask __cpu_present_mask __read_mostly;
 EXPORT_SYMBOL(__cpu_present_mask);
+MEMINSPECT_SIMPLE_ENTRY(__cpu_present_mask);
 
 struct cpumask __cpu_active_mask __read_mostly;
 EXPORT_SYMBOL(__cpu_active_mask);
+MEMINSPECT_SIMPLE_ENTRY(__cpu_active_mask);
 
 struct cpumask __cpu_dying_mask __read_mostly;
 EXPORT_SYMBOL(__cpu_dying_mask);

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 05/26] genirq/irqdesc: Annotate static information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (3 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 04/26] cpu: " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  7:46   ` Lorenzo Stoakes
  2026-07-08  5:31 ` [PATCH v3 06/26] timers: " Mukesh Ojha
                   ` (22 subsequent siblings)
  27 siblings, 1 reply; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate vital static information into inspection table:
 - total_nr_irqs

Information on these annotated variables is stored in a dedicated
meminspect section.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 kernel/irq/irqdesc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 80ef4e27dcf4..4e58e7f5fc6c 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -16,6 +16,7 @@
 #include <linux/irqdomain.h>
 #include <linux/sysfs.h>
 #include <linux/string_choices.h>
+#include <linux/meminspect.h>
 
 #include "internals.h"
 
@@ -142,6 +143,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
 }
 
 unsigned int total_nr_irqs __read_mostly = NR_IRQS;
+MEMINSPECT_SIMPLE_ENTRY(total_nr_irqs);
 
 /**
  * irq_get_nr_irqs() - Number of interrupts supported by the system.

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 06/26] timers: Annotate static information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (4 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 05/26] genirq/irqdesc: " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 07/26] timekeeping: Register tk_data " Mukesh Ojha
                   ` (21 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate vital static information into inspection table:
 - jiffies_64

Information on these variables is stored in a dedicated meminspect
section.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 kernel/time/timer.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 655a8c6cd84d..6cbb054c7c4b 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -44,6 +44,7 @@
 #include <linux/compat.h>
 #include <linux/random.h>
 #include <linux/sysctl.h>
+#include <linux/meminspect.h>
 
 #include <linux/uaccess.h>
 #include <asm/unistd.h>
@@ -60,6 +61,7 @@
 __visible u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
 
 EXPORT_SYMBOL(jiffies_64);
+MEMINSPECT_SIMPLE_ENTRY(jiffies_64);
 
 /*
  * The timer wheel has LVL_DEPTH array levels. Each level provides an array of

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 07/26] timekeeping: Register tk_data into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (5 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 06/26] timers: " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 08/26] kernel/fork: Annotate static information " Mukesh Ojha
                   ` (20 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree

Annotate timekeeper_data into meminspect for debugging:
 - tk_data (timekeeper_data array)

Register the timekeeper_data array using MEMINSPECT_NAMED_ENTRY
with the "tk_data" identifier. Update the meminspect ID enum and
the minidump backend string table accordingly.

Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 include/linux/meminspect.h | 1 +
 kernel/time/timekeeping.c  | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/include/linux/meminspect.h b/include/linux/meminspect.h
index a9eb93c6ea2f..b64ca614b243 100644
--- a/include/linux/meminspect.h
+++ b/include/linux/meminspect.h
@@ -49,6 +49,7 @@ enum meminspect_uid {
 	MEMINSPECT_ID_kallsyms_markers,
 	MEMINSPECT_ID_kallsyms_seqs_of_names,
 	MEMINSPECT_ID_swapper_pg_dir,
+	MEMINSPECT_ID_tk_data,
 	MEMINSPECT_ID_DYNAMIC,
 	MEMINSPECT_ID_MAX = 201,
 };
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 5985d6652c1d..8a5da24d8678 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -14,6 +14,7 @@
 #include <linux/random.h>
 #include <linux/sched/clock.h>
 #include <linux/sched/loadavg.h>
+#include <linux/meminspect.h>
 #include <linux/static_key.h>
 #include <linux/stop_machine.h>
 #include <linux/syscore_ops.h>
@@ -53,6 +54,7 @@ struct tk_data {
 } ____cacheline_aligned;
 
 static struct tk_data timekeeper_data[TIMEKEEPERS_MAX];
+MEMINSPECT_NAMED_ENTRY(tk_data, timekeeper_data);
 
 /* The core timekeeper */
 #define tk_core		(timekeeper_data[TIMEKEEPER_CORE])

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 08/26] kernel/fork: Annotate static information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (6 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 07/26] timekeeping: Register tk_data " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 09/26] mm/page_alloc: " Mukesh Ojha
                   ` (19 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate vital static information into inspection table:
 - nr_threads

Information on these annotated variables is stored in a dedicated
meminspect section.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 kernel/fork.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/kernel/fork.c b/kernel/fork.c
index 175c73bbe2bf..ec99066eedd2 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -111,6 +111,8 @@
 #include <linux/tick.h>
 #include <linux/unwind_deferred.h>
 #include <linux/pgalloc.h>
+#include <linux/meminspect.h>
+
 #include <linux/uaccess.h>
 
 #include <asm/mmu_context.h>
@@ -142,6 +144,7 @@
  */
 unsigned long total_forks;	/* Handle normal Linux uptimes. */
 int nr_threads;			/* The idle threads do not count.. */
+MEMINSPECT_SIMPLE_ENTRY(nr_threads);
 
 static int max_threads;		/* tunable limit on nr_threads */
 

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 09/26] mm/page_alloc: Annotate static information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (7 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 08/26] kernel/fork: Annotate static information " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 10/26] mm/show_mem: " Mukesh Ojha
                   ` (18 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate vital static information into inspection table:
 - node_states

Information on these variables is stored in a dedicated meminspect
section.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 mm/page_alloc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index a63733dac659..70c5e0794efa 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -54,6 +54,7 @@
 #include <linux/delayacct.h>
 #include <linux/cacheinfo.h>
 #include <linux/pgalloc_tag.h>
+#include <linux/meminspect.h>
 #include <asm/div64.h>
 #include "internal.h"
 #include "page_alloc.h"
@@ -204,6 +205,7 @@ nodemask_t node_states[NR_NODE_STATES] __read_mostly = {
 #endif	/* NUMA */
 };
 EXPORT_SYMBOL(node_states);
+MEMINSPECT_SIMPLE_ENTRY(node_states);
 
 gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK;
 

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 10/26] mm/show_mem: Annotate static information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (8 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 09/26] mm/page_alloc: " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 11/26] mm/swapfile: " Mukesh Ojha
                   ` (17 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate vital static information into inspection table:
 - _totalram_pages

Information on these variables is stored in a dedicated meminspect
section.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 mm/show_mem.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/show_mem.c b/mm/show_mem.c
index d1288b4c2b64..67ef32f1ebb9 100644
--- a/mm/show_mem.c
+++ b/mm/show_mem.c
@@ -14,6 +14,7 @@
 #include <linux/mmzone.h>
 #include <linux/swap.h>
 #include <linux/vmstat.h>
+#include <linux/meminspect.h>
 
 #include "internal.h"
 #include "page_alloc.h"
@@ -21,6 +22,7 @@
 
 atomic_long_t _totalram_pages __read_mostly;
 EXPORT_SYMBOL(_totalram_pages);
+MEMINSPECT_SIMPLE_ENTRY(_totalram_pages);
 unsigned long totalreserve_pages __read_mostly;
 unsigned long totalcma_pages __read_mostly;
 

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 11/26] mm/swapfile: Annotate static information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (9 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 10/26] mm/show_mem: " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  7:47   ` Lorenzo Stoakes
  2026-07-08  5:31 ` [PATCH v3 12/26] kernel/vmcore_info: Register dynamic " Mukesh Ojha
                   ` (16 subsequent siblings)
  27 siblings, 1 reply; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate vital static information into inspection table:
 - nr_swapfiles

Information on these variables is stored in a dedicated meminspect
section.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 mm/swapfile.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/swapfile.c b/mm/swapfile.c
index a602e5820513..d480727e4987 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -42,6 +42,7 @@
 #include <linux/suspend.h>
 #include <linux/zswap.h>
 #include <linux/plist.h>
+#include <linux/meminspect.h>
 
 #include <asm/tlbflush.h>
 #include <linux/leafops.h>
@@ -65,6 +66,7 @@ static void move_cluster(struct swap_info_struct *si,
  */
 static DEFINE_SPINLOCK(swap_lock);
 static unsigned int nr_swapfiles;
+MEMINSPECT_SIMPLE_ENTRY(nr_swapfiles);
 atomic_long_t nr_swap_pages;
 /*
  * Some modules use swappable objects and may try to swap them out under

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 12/26] kernel/vmcore_info: Register dynamic information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (10 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 11/26] mm/swapfile: " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 13/26] kernel/configs: " Mukesh Ojha
                   ` (15 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Register vmcoreinfo information into the inspection table.
Because the size of the info is computed after all entries are
added, there is no point in registering the whole page; instead,
call the inspection registration once everything is in place with
the right size. A second reason is that the vmcoreinfo is added
as a region inside the ELF core image note, so there is no point
in having blank space at the end.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 kernel/vmcore_info.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/kernel/vmcore_info.c b/kernel/vmcore_info.c
index 8614430ca212..c5181e9d049c 100644
--- a/kernel/vmcore_info.c
+++ b/kernel/vmcore_info.c
@@ -14,6 +14,7 @@
 #include <linux/cpuhotplug.h>
 #include <linux/memblock.h>
 #include <linux/kmemleak.h>
+#include <linux/meminspect.h>
 
 #include <asm/page.h>
 #include <asm/sections.h>
@@ -247,6 +248,9 @@ static int __init crash_save_vmcoreinfo_init(void)
 	arch_crash_save_vmcoreinfo();
 	update_vmcoreinfo_note();
 
+	meminspect_lock_register_id_va(MEMINSPECT_ID_VMCOREINFO,
+				       (void *)vmcoreinfo_data, vmcoreinfo_size);
+
 	return 0;
 }
 

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 13/26] kernel/configs: Register dynamic information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (11 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 12/26] kernel/vmcore_info: Register dynamic " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 14/26] mm/init-mm: Annotate static " Mukesh Ojha
                   ` (14 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Register kernel_config_data information into inspection table.
Debugging tools look for the start and end markers, so we need to
capture those as well into the region.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 kernel/configs.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/kernel/configs.c b/kernel/configs.c
index a28c79c5f713..1e7b86a8b3fc 100644
--- a/kernel/configs.c
+++ b/kernel/configs.c
@@ -15,6 +15,7 @@
 #include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/uaccess.h>
+#include <linux/meminspect.h>
 
 /*
  * "IKCFG_ST" and "IKCFG_ED" are used to extract the config data from
@@ -64,6 +65,11 @@ static int __init ikconfig_init(void)
 
 	proc_set_size(entry, &kernel_config_data_end - &kernel_config_data);
 
+	/* Register 8 bytes before and after, to catch the marker too */
+	meminspect_lock_register_id_va(MEMINSPECT_ID_CONFIG,
+				       (void *)&kernel_config_data - 8,
+				       &kernel_config_data_end - &kernel_config_data + 16);
+
 	return 0;
 }
 

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 14/26] mm/init-mm: Annotate static information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (12 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 13/26] kernel/configs: " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  7:52   ` Lorenzo Stoakes
  2026-07-08  5:31 ` [PATCH v3 15/26] panic: " Mukesh Ojha
                   ` (13 subsequent siblings)
  27 siblings, 1 reply; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate vital static information into inspection table:
 - init_mm
 - swapper_pg_dir
 - _sinittext
 - _einittext
 - _end
 - _text
 - _stext
 - _etext

Information on these variables is stored into dedicated meminspect
section.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 mm/init-mm.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/mm/init-mm.c b/mm/init-mm.c
index 3e792aad7626..cf53058410b1 100644
--- a/mm/init-mm.c
+++ b/mm/init-mm.c
@@ -7,6 +7,8 @@
 #include <linux/cpumask.h>
 #include <linux/mman.h>
 #include <linux/pgtable.h>
+#include <linux/meminspect.h>
+#include <asm/sections.h>
 
 #include <linux/atomic.h>
 #include <linux/user_namespace.h>
@@ -19,6 +21,13 @@
 
 const struct vm_operations_struct vma_dummy_vm_ops;
 
+MEMINSPECT_AREA_ENTRY(_sinittext, sizeof(void *));
+MEMINSPECT_AREA_ENTRY(_einittext, sizeof(void *));
+MEMINSPECT_AREA_ENTRY(_end, sizeof(void *));
+MEMINSPECT_AREA_ENTRY(_text, sizeof(void *));
+MEMINSPECT_AREA_ENTRY(_stext, sizeof(void *));
+MEMINSPECT_AREA_ENTRY(_etext, sizeof(void *));
+
 /*
  * For dynamically allocated mm_structs, there is a dynamically sized cpumask
  * at the end of the structure, the size of which depends on the maximum CPU
@@ -50,6 +59,9 @@ struct mm_struct init_mm = {
 	INIT_MM_CONTEXT(init_mm)
 };
 
+MEMINSPECT_SIMPLE_ENTRY(init_mm);
+MEMINSPECT_AREA_ENTRY(swapper_pg_dir, sizeof(void *));
+
 void setup_initial_init_mm(void *start_code, void *end_code,
 			   void *end_data, void *brk)
 {

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 15/26] panic: Annotate static information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (13 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 14/26] mm/init-mm: Annotate static " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 16/26] kallsyms: " Mukesh Ojha
                   ` (12 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate vital static information into inspection table:
 - tainted_mask
 - taint_flags

Information on these variables is stored into dedicated meminspect
section.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 kernel/panic.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/kernel/panic.c b/kernel/panic.c
index 90e21f15fd7e..31d2e08b7e2b 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -37,6 +37,7 @@
 #include <linux/context_tracking.h>
 #include <linux/seq_buf.h>
 #include <linux/sys_info.h>
+#include <linux/meminspect.h>
 #include <trace/events/error_report.h>
 #include <asm/sections.h>
 #include <kunit/test-bug.h>
@@ -58,6 +59,7 @@ static unsigned int __read_mostly sysctl_oops_all_cpu_backtrace;
 int panic_on_oops = IS_ENABLED(CONFIG_PANIC_ON_OOPS);
 static unsigned long tainted_mask =
 	IS_ENABLED(CONFIG_RANDSTRUCT) ? (1 << TAINT_RANDSTRUCT) : 0;
+MEMINSPECT_SIMPLE_ENTRY(tainted_mask);
 static int pause_on_oops;
 static int pause_on_oops_flag;
 static DEFINE_SPINLOCK(pause_on_oops_lock);
@@ -833,6 +835,8 @@ const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = {
 	TAINT_FLAG(FWCTL,			'J', ' '),
 };
 
+MEMINSPECT_SIMPLE_ENTRY(taint_flags);
+
 #undef TAINT_FLAG
 
 static void print_tainted_seq(struct seq_buf *s, bool verbose)

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 16/26] kallsyms: Annotate static information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (14 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 15/26] panic: " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 17/26] mm/mm_init: " Mukesh Ojha
                   ` (11 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate vital static information into meminspect:
 - kallsyms_num_syms
 - kallsyms_offsets
 - kallsyms_names
 - kallsyms_token_table
 - kallsyms_token_index
 - kallsyms_markers
 - kallsyms_seqs_of_names

Information on these variables is stored in a dedicated meminspect
section.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 kernel/kallsyms.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index aec2f06858af..e71c085ec837 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -31,9 +31,18 @@
 #include <linux/kernel.h>
 #include <linux/bsearch.h>
 #include <linux/btf_ids.h>
+#include <linux/meminspect.h>
 
 #include "kallsyms_internal.h"
 
+MEMINSPECT_SIMPLE_ENTRY(kallsyms_num_syms);
+MEMINSPECT_AREA_ENTRY(kallsyms_offsets, sizeof(void *));
+MEMINSPECT_AREA_ENTRY(kallsyms_names, sizeof(void *));
+MEMINSPECT_AREA_ENTRY(kallsyms_token_table, sizeof(void *));
+MEMINSPECT_AREA_ENTRY(kallsyms_token_index, sizeof(void *));
+MEMINSPECT_AREA_ENTRY(kallsyms_markers, sizeof(void *));
+MEMINSPECT_AREA_ENTRY(kallsyms_seqs_of_names, sizeof(void *));
+
 /*
  * Expand a compressed symbol data into the resulting uncompressed string,
  * if uncompressed string is too long (>= maxlen), it will be truncated,

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 17/26] mm/mm_init: Annotate static information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (15 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 16/26] kallsyms: " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 18/26] sched/core: Annotate runqueues " Mukesh Ojha
                   ` (10 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate vital static information into inspection table:
 - high_memory

Information on these variables is stored in a dedicated meminspect
section.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 mm/mm_init.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/mm_init.c b/mm/mm_init.c
index 3ff2e90aa17a..d98b6071d2a1 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -32,6 +32,7 @@
 #include <linux/vmstat.h>
 #include <linux/kexec_handover.h>
 #include <linux/hugetlb.h>
+#include <linux/meminspect.h>
 #include "internal.h"
 #include "page_alloc.h"
 #include "slab.h"
@@ -53,6 +54,7 @@ EXPORT_SYMBOL(mem_map);
  */
 void *high_memory;
 EXPORT_SYMBOL(high_memory);
+MEMINSPECT_SIMPLE_ENTRY(high_memory);
 
 unsigned long zero_page_pfn __ro_after_init;
 EXPORT_SYMBOL(zero_page_pfn);

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 18/26] sched/core: Annotate runqueues into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (16 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 17/26] mm/mm_init: " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:31 ` [PATCH v3 19/26] mm/numa: Register node data information " Mukesh Ojha
                   ` (9 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Annotate runqueues into meminspect. Even if these are static, they are
defined percpu, and a later init call will instantiate them for each
cpu. Hence, we cannot annotate them in the usual way, but rather have to
call meminspect API at init time.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 kernel/sched/core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 2e7cde033a31..1c2e80a54d2b 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -69,6 +69,7 @@
 #include <linux/wait_api.h>
 #include <linux/workqueue_api.h>
 #include <linux/livepatch_sched.h>
+#include <linux/meminspect.h>
 
 #ifdef CONFIG_PREEMPT_DYNAMIC
 # ifdef CONFIG_GENERIC_IRQ_ENTRY
@@ -9059,6 +9060,7 @@ void __init sched_init(void)
 #endif
 
 		zalloc_cpumask_var_node(&rq->scratch_mask, GFP_KERNEL, cpu_to_node(i));
+		meminspect_lock_register_va(rq, sizeof(*rq));
 	}
 
 	set_load_weight(&init_task, false);

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 19/26] mm/numa: Register node data information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (17 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 18/26] sched/core: Annotate runqueues " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  7:55   ` Lorenzo Stoakes
  2026-07-08  5:31 ` [PATCH v3 20/26] mm/sparse: Register " Mukesh Ojha
                   ` (8 subsequent siblings)
  27 siblings, 1 reply; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

Register dynamic information into meminspect for debugging:
 - dynamic node data for each node

Use meminspect_register_pa() to collect node data into meminspect.

Co-developed-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 mm/numa.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/numa.c b/mm/numa.c
index 7d5e06fe5bd4..f04740dfb2cb 100644
--- a/mm/numa.c
+++ b/mm/numa.c
@@ -4,6 +4,7 @@
 #include <linux/printk.h>
 #include <linux/numa.h>
 #include <linux/numa_memblks.h>
+#include <linux/meminspect.h>
 
 struct pglist_data *node_data[MAX_NUMNODES];
 EXPORT_SYMBOL(node_data);
@@ -20,6 +21,7 @@ void __init alloc_node_data(int nid)
 	if (!nd_pa)
 		panic("Cannot allocate %zu bytes for node %d data\n",
 		      nd_size, nid);
+	meminspect_lock_register_pa(nd_pa, nd_size);
 
 	/* report and initialize */
 	pr_info("NODE_DATA(%d) allocated [mem %#010Lx-%#010Lx]\n", nid,

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 20/26] mm/sparse: Register information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (18 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 19/26] mm/numa: Register node data information " Mukesh Ojha
@ 2026-07-08  5:31 ` Mukesh Ojha
  2026-07-08  5:32 ` [PATCH v3 21/26] printk: " Mukesh Ojha
                   ` (7 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:31 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

Annotate vital static, dynamic information into meminspect for
debugging:
 - mem_section (static)
 - section (dynamic)

meminspect uses a different API to annotate variables for inspection,
and information about these variables is stored in the inspection table.

Co-developed-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 mm/sparse.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/mm/sparse.c b/mm/sparse.c
index 058ef9300367..9e890fb6c43e 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -15,6 +15,7 @@
 #include <linux/swapops.h>
 #include <linux/bootmem_info.h>
 #include <linux/vmstat.h>
+#include <linux/meminspect.h>
 #include "internal.h"
 #include <asm/dma.h>
 
@@ -30,6 +31,7 @@ struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT]
 	____cacheline_internodealigned_in_smp;
 #endif
 EXPORT_SYMBOL(mem_section);
+MEMINSPECT_SIMPLE_ENTRY(mem_section);
 
 #ifdef NODE_NOT_IN_PAGE_FLAGS
 /*
@@ -206,6 +208,7 @@ static void __init memblocks_present(void)
 	size = sizeof(struct mem_section *) * NR_SECTION_ROOTS;
 	align = 1 << (INTERNODE_CACHE_SHIFT);
 	mem_section = memblock_alloc_or_panic(size, align);
+	meminspect_lock_register_va(mem_section, size);
 #endif
 
 	for_each_mem_pfn_range(i, MAX_NUMNODES, &start, &end, &nid)

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 21/26] printk: Register information into meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (19 preceding siblings ...)
  2026-07-08  5:31 ` [PATCH v3 20/26] mm/sparse: Register " Mukesh Ojha
@ 2026-07-08  5:32 ` Mukesh Ojha
  2026-07-08  7:59   ` Lorenzo Stoakes
  2026-07-08  5:32 ` [PATCH v3 22/26] remoteproc: qcom: Move minidump data structures into its own header Mukesh Ojha
                   ` (6 subsequent siblings)
  27 siblings, 1 reply; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:32 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

Annotate vital static, dynamic information into meminspect for debugging

Static:
 - prb_descs
 - prb_infos
 - prb
 - prb_data
 - clear_seq
 - printk_rb_static
 - printk_rb_dynamic

Dynamic:
 - new_descs
 - new_infos
 - new_log_buf

meminspect uses a different API to annotate variables for inspection,
and information about these variables is stored in the inspection table.

Reviewed-by: Petr Mladek <pmladek@suse.com>
Co-developed-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Reviewed-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 kernel/printk/printk.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 2fe9a963c823..f7f32c09b9b8 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -49,6 +49,7 @@
 #include <linux/sched/debug.h>
 #include <linux/sched/task_stack.h>
 #include <linux/panic.h>
+#include <linux/meminspect.h>
 
 #include <linux/uaccess.h>
 #include <asm/sections.h>
@@ -518,10 +519,17 @@ static u32 log_buf_len = __LOG_BUF_LEN;
 #endif
 _DEFINE_PRINTKRB(printk_rb_static, CONFIG_LOG_BUF_SHIFT - PRB_AVGBITS,
 		 PRB_AVGBITS, &__log_buf[0]);
+MEMINSPECT_NAMED_ENTRY(prb_descs, _printk_rb_static_descs);
+MEMINSPECT_NAMED_ENTRY(prb_infos, _printk_rb_static_infos);
+MEMINSPECT_NAMED_ENTRY(prb_data, __log_buf);
+MEMINSPECT_SIMPLE_ENTRY(printk_rb_static);
 
 static struct printk_ringbuffer printk_rb_dynamic;
+MEMINSPECT_SIMPLE_ENTRY(printk_rb_dynamic);
 
 struct printk_ringbuffer *prb = &printk_rb_static;
+MEMINSPECT_SIMPLE_ENTRY(prb);
+MEMINSPECT_SIMPLE_ENTRY(clear_seq);
 
 /*
  * We cannot access per-CPU data (e.g. per-CPU flush irq_work) before
@@ -1238,6 +1246,10 @@ void __init setup_log_buf(int early)
 
 	local_irq_restore(flags);
 
+	meminspect_lock_register_va(new_log_buf, new_log_buf_len);
+	meminspect_lock_register_va(new_descs, new_descs_size);
+	meminspect_lock_register_va(new_infos, new_infos_size);
+
 	/*
 	 * Copy any remaining messages that might have appeared from
 	 * NMI context after copying but before switching to the

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 22/26] remoteproc: qcom: Move minidump data structures into its own header
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (20 preceding siblings ...)
  2026-07-08  5:32 ` [PATCH v3 21/26] printk: " Mukesh Ojha
@ 2026-07-08  5:32 ` Mukesh Ojha
  2026-07-08  5:32 ` [PATCH v3 23/26] soc: qcom: Add minidump backend driver Mukesh Ojha
                   ` (5 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:32 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Move the minidump data structures into its own header such that it can
be reused by other drivers. No functional change.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/remoteproc/qcom_common.c  | 55 +-------------------------------
 include/linux/soc/qcom/minidump.h | 67 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 54 deletions(-)

diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c
index e1a955476c9b..a5ab9f024e64 100644
--- a/drivers/remoteproc/qcom_common.c
+++ b/drivers/remoteproc/qcom_common.c
@@ -18,6 +18,7 @@
 #include <linux/rpmsg/qcom_smd.h>
 #include <linux/slab.h>
 #include <linux/soc/qcom/mdt_loader.h>
+#include <linux/soc/qcom/minidump.h>
 #include <linux/soc/qcom/smem.h>
 
 #include "remoteproc_internal.h"
@@ -28,60 +29,6 @@
 #define to_ssr_subdev(d) container_of(d, struct qcom_rproc_ssr, subdev)
 #define to_pdm_subdev(d) container_of(d, struct qcom_rproc_pdm, subdev)
 
-#define MAX_REGION_NAME_LENGTH  16
-#define SBL_MINIDUMP_SMEM_ID	602
-#define MINIDUMP_REGION_VALID		('V' << 24 | 'A' << 16 | 'L' << 8 | 'I' << 0)
-#define MINIDUMP_SS_ENCR_DONE		('D' << 24 | 'O' << 16 | 'N' << 8 | 'E' << 0)
-#define MINIDUMP_SS_ENABLED		('E' << 24 | 'N' << 16 | 'B' << 8 | 'L' << 0)
-
-/**
- * struct minidump_region - Minidump region
- * @name		: Name of the region to be dumped
- * @seq_num:		: Use to differentiate regions with same name.
- * @valid		: This entry to be dumped (if set to 1)
- * @address		: Physical address of region to be dumped
- * @size		: Size of the region
- */
-struct minidump_region {
-	char	name[MAX_REGION_NAME_LENGTH];
-	__le32	seq_num;
-	__le32	valid;
-	__le64	address;
-	__le64	size;
-};
-
-/**
- * struct minidump_subsystem - Subsystem's SMEM Table of content
- * @status : Subsystem toc init status
- * @enabled : if set to 1, this region would be copied during coredump
- * @encryption_status: Encryption status for this subsystem
- * @encryption_required : Decides to encrypt the subsystem regions or not
- * @region_count : Number of regions added in this subsystem toc
- * @regions_baseptr : regions base pointer of the subsystem
- */
-struct minidump_subsystem {
-	__le32	status;
-	__le32	enabled;
-	__le32	encryption_status;
-	__le32	encryption_required;
-	__le32	region_count;
-	__le64	regions_baseptr;
-};
-
-/**
- * struct minidump_global_toc - Global Table of Content
- * @status : Global Minidump init status
- * @md_revision : Minidump revision
- * @enabled : Minidump enable status
- * @subsystems : Array of subsystems toc
- */
-struct minidump_global_toc {
-	__le32				status;
-	__le32				md_revision;
-	__le32				enabled;
-	struct minidump_subsystem	subsystems[];
-};
-
 struct qcom_ssr_subsystem {
 	const char *name;
 	struct srcu_notifier_head notifier_list;
diff --git a/include/linux/soc/qcom/minidump.h b/include/linux/soc/qcom/minidump.h
new file mode 100644
index 000000000000..7449a04e6e15
--- /dev/null
+++ b/include/linux/soc/qcom/minidump.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Qualcomm Minidump definitions
+ *
+ * Copyright (C) 2016 Linaro Ltd
+ * Copyright (C) 2015 Sony Mobile Communications Inc
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __QCOM_MINIDUMP_H__
+#define __QCOM_MINIDUMP_H__
+
+#define MAX_REGION_NAME_LENGTH  16
+#define SBL_MINIDUMP_SMEM_ID	602
+#define MINIDUMP_REGION_VALID		('V' << 24 | 'A' << 16 | 'L' << 8 | 'I' << 0)
+#define MINIDUMP_SS_ENCR_DONE		('D' << 24 | 'O' << 16 | 'N' << 8 | 'E' << 0)
+#define MINIDUMP_SS_ENABLED		('E' << 24 | 'N' << 16 | 'B' << 8 | 'L' << 0)
+
+/**
+ * struct minidump_region - Minidump region
+ * @name		: Name of the region to be dumped
+ * @seq_num:		: Use to differentiate regions with same name.
+ * @valid		: This entry to be dumped (if set to 1)
+ * @address		: Physical address of region to be dumped
+ * @size		: Size of the region
+ */
+struct minidump_region {
+	char	name[MAX_REGION_NAME_LENGTH];
+	__le32	seq_num;
+	__le32	valid;
+	__le64	address;
+	__le64	size;
+};
+
+/**
+ * struct minidump_subsystem - Subsystem's SMEM Table of content
+ * @status : Subsystem toc init status
+ * @enabled : if set to 1, this region would be copied during coredump
+ * @encryption_status: Encryption status for this subsystem
+ * @encryption_required : Decides to encrypt the subsystem regions or not
+ * @region_count : Number of regions added in this subsystem toc
+ * @regions_baseptr : regions base pointer of the subsystem
+ */
+struct minidump_subsystem {
+	__le32	status;
+	__le32	enabled;
+	__le32	encryption_status;
+	__le32	encryption_required;
+	__le32	region_count;
+	__le64	regions_baseptr;
+};
+
+/**
+ * struct minidump_global_toc - Global Table of Content
+ * @status : Global Minidump init status
+ * @md_revision : Minidump revision
+ * @enabled : Minidump enable status
+ * @subsystems : Array of subsystems toc
+ */
+struct minidump_global_toc {
+	__le32				status;
+	__le32				md_revision;
+	__le32				enabled;
+	struct minidump_subsystem	subsystems[];
+};
+
+#endif

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 23/26] soc: qcom: Add minidump backend driver
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (21 preceding siblings ...)
  2026-07-08  5:32 ` [PATCH v3 22/26] remoteproc: qcom: Move minidump data structures into its own header Mukesh Ojha
@ 2026-07-08  5:32 ` Mukesh Ojha
  2026-07-08  5:32 ` [PATCH v3 24/26] soc: qcom: smem: Add minidump platform device Mukesh Ojha
                   ` (4 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:32 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Qualcomm Minidump is a backend driver that manages the minidump shared
memory table on Qualcomm platforms. It uses the meminspect table that
it parses in order to obtain inspection entries from the kernel and
convert them into regions. Regions are afterwards being registered into
the shared memory's Minidump table of contents. Further, Qualcomm boot
firmware can read the table of contents and dump the memory accordingly,
as per the firmware requirements.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/soc/qcom/Kconfig          |  13 ++
 drivers/soc/qcom/Makefile         |   1 +
 drivers/soc/qcom/minidump.c       | 271 ++++++++++++++++++++++++++++++++++++++
 include/linux/soc/qcom/minidump.h |   3 +
 4 files changed, 288 insertions(+)

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index f6970431d07d..18ed8d6a3b62 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -180,6 +180,19 @@ config QCOM_SMEM
 	  The driver provides an interface to items in a heap shared among all
 	  processors in a Qualcomm platform.
 
+config QCOM_MINIDUMP
+	tristate "Qualcomm Minidump memory inspection driver"
+	depends on ARCH_QCOM || COMPILE_TEST
+	depends on QCOM_SMEM
+	help
+	  Say y here to enable the Qualcomm Minidump memory inspection driver.
+	  This driver uses memory inspection mechanism to register minidump
+	  regions with the Qualcomm firmware, into the shared memory.
+	  The registered regions are being linked into the minidump table
+	  of contents.
+	  Further on, the firmware will be able to read the table of contents
+	  and extract the memory regions on case-by-case basis.
+
 config QCOM_SMD_RPM
 	tristate "Qualcomm Resource Power Manager (RPM) over SMD"
 	depends on ARCH_QCOM || COMPILE_TEST
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index b7f1d2a57367..3e5a2cacccd4 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -25,6 +25,7 @@ qcom_rpmh-y			+= rpmh.o
 obj-$(CONFIG_QCOM_SMD_RPM)	+= rpm-proc.o smd-rpm.o
 obj-$(CONFIG_QCOM_SMEM) +=	smem.o
 obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
+obj-$(CONFIG_QCOM_MINIDUMP)	+= minidump.o
 CFLAGS_smp2p.o := -I$(src)
 obj-$(CONFIG_QCOM_SMP2P)	+= smp2p.o
 obj-$(CONFIG_QCOM_SMSM)	+= smsm.o
diff --git a/drivers/soc/qcom/minidump.c b/drivers/soc/qcom/minidump.c
new file mode 100644
index 000000000000..78d199b7c552
--- /dev/null
+++ b/drivers/soc/qcom/minidump.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Qualcomm Minidump kernel inspect driver
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/notifier.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/soc/qcom/smem.h>
+#include <linux/soc/qcom/minidump.h>
+#include <linux/meminspect.h>
+
+/**
+ * struct minidump - Minidump driver data information
+ *
+ * @dev:	Minidump device struct.
+ * @toc:	Minidump table of contents subsystem.
+ * @regions:	Minidump regions array.
+ * @nb:		Notifier block to register to meminspect.
+ */
+struct minidump {
+	struct device			*dev;
+	struct minidump_subsystem	*toc;
+	struct minidump_region		*regions;
+	struct notifier_block		nb;
+};
+
+static const char * const meminspect_id_to_md_string[] = {
+	"",
+	"ELF",
+	"vmcoreinfo",
+	"config",
+	"totalram",
+	"cpu_possible",
+	"cpu_present",
+	"cpu_online",
+	"cpu_active",
+	"mem_section",
+	"jiffies",
+	"linux_banner",
+	"nr_threads",
+	"nr_irqs",
+	"tainted_mask",
+	"taint_flags",
+	"node_states",
+	"__per_cpu_offset",
+	"nr_swapfiles",
+	"init_uts_ns",
+	"printk_rb_static",
+	"printk_rb_dynamic",
+	"prb",
+	"prb_descs",
+	"prb_infos",
+	"prb_data",
+	"clear_seq",
+	"high_memory",
+	"init_mm",
+	"tk_data",
+};
+
+/**
+ * qcom_md_table_init() - Initialize the minidump table
+ * @md:		minidump data
+ * @mdss_toc: minidump subsystem table of contents
+ *
+ * Return: On success, it returns 0 and negative error value on failure.
+ */
+static int qcom_md_table_init(struct minidump *md,
+			      struct minidump_subsystem *mdss_toc)
+{
+	md->toc = mdss_toc;
+	md->regions = devm_kcalloc(md->dev, MAX_NUM_REGIONS,
+				   sizeof(*md->regions), GFP_KERNEL);
+	if (!md->regions)
+		return -ENOMEM;
+
+	md->toc->regions_baseptr = cpu_to_le64(virt_to_phys(md->regions));
+	md->toc->enabled = cpu_to_le32(MINIDUMP_SS_ENABLED);
+	md->toc->status = cpu_to_le32(1);
+	md->toc->region_count = cpu_to_le32(0);
+
+	/* Tell bootloader not to encrypt the regions of this subsystem */
+	md->toc->encryption_status = cpu_to_le32(MINIDUMP_SS_ENCR_DONE);
+	md->toc->encryption_required = cpu_to_le32(MINIDUMP_SS_ENCR_NOTREQ);
+
+	return 0;
+}
+
+/**
+ * qcom_md_get_region_index() - Lookup minidump region by id
+ * @md: minidump data
+ * @id: minidump region id
+ *
+ * Return: On success, it returns the internal region index, on failure,
+ *	returns	negative error value
+ */
+static int qcom_md_get_region_index(struct minidump *md, int id)
+{
+	unsigned int count = le32_to_cpu(md->toc->region_count);
+	unsigned int i;
+
+	for (i = 0; i < count; i++)
+		if (md->regions[i].seq_num == id)
+			return i;
+
+	return -ENOENT;
+}
+
+/**
+ * register_md_region() - Register a new minidump region
+ * @priv: private data
+ * @e:	  pointer to inspect entry
+ *
+ * Return: None
+ */
+static void __maybe_unused register_md_region(void *priv,
+					      const struct inspect_entry *e)
+{
+	unsigned int num_region, region_cnt;
+	const char *name = "unknown";
+	struct minidump_region *mdr;
+	struct minidump *md = priv;
+
+	if (!(e->va || e->pa) || !e->size) {
+		dev_dbg(md->dev, "invalid region requested\n");
+		return;
+	}
+
+	if (e->id < ARRAY_SIZE(meminspect_id_to_md_string))
+		name = meminspect_id_to_md_string[e->id];
+
+	if (qcom_md_get_region_index(md, e->id) >= 0) {
+		dev_dbg(md->dev, "%s:%d region is already registered\n",
+			name, e->id);
+		return;
+	}
+
+	/* Check if there is a room for a new entry */
+	num_region = le32_to_cpu(md->toc->region_count);
+	if (num_region >= MAX_NUM_REGIONS) {
+		dev_dbg(md->dev, "maximum region limit %u reached\n",
+			num_region);
+		return;
+	}
+
+	region_cnt = le32_to_cpu(md->toc->region_count);
+	mdr = &md->regions[region_cnt];
+	scnprintf(mdr->name, MAX_REGION_NAME_LENGTH, "K%.8s", name);
+	mdr->seq_num = e->id;
+	if (e->pa)
+		mdr->address = cpu_to_le64(e->pa);
+	else if (e->va)
+		mdr->address = cpu_to_le64(__pa(e->va));
+	mdr->size = cpu_to_le64(ALIGN(e->size, 4));
+	mdr->valid = cpu_to_le32(MINIDUMP_REGION_VALID);
+	region_cnt++;
+	md->toc->region_count = cpu_to_le32(region_cnt);
+
+	dev_dbg(md->dev, "%s:%d region registered %llx:%llx\n",
+		mdr->name, mdr->seq_num, mdr->address, mdr->size);
+}
+
+/**
+ * unregister_md_region() - Unregister a previously registered minidump region
+ * @priv:  private data
+ * @e:	   pointer to inspect entry
+ *
+ * Return: None
+ */
+static void __maybe_unused unregister_md_region(void *priv,
+						const struct inspect_entry *e)
+{
+	struct minidump_region *mdr;
+	struct minidump *md = priv;
+	unsigned int region_cnt;
+	unsigned int idx;
+
+	idx = qcom_md_get_region_index(md, e->id);
+	if (idx < 0) {
+		dev_dbg(md->dev, "%d region is not present\n", e->id);
+		return;
+	}
+
+	mdr = &md->regions[0];
+	region_cnt = le32_to_cpu(md->toc->region_count);
+
+	/*
+	 * Left shift one position all the regions located after the
+	 * region being removed, in order to fill the gap.
+	 * Then, zero out the last region at the end.
+	 */
+	memmove(&mdr[idx], &mdr[idx + 1], (region_cnt - idx - 1) * sizeof(*mdr));
+	memset(&mdr[region_cnt - 1], 0, sizeof(*mdr));
+	region_cnt--;
+	md->toc->region_count = cpu_to_le32(region_cnt);
+}
+
+static int qcom_md_notifier_cb(struct notifier_block *nb,
+			       unsigned long code, void *entry)
+{
+	struct minidump *md = container_of(nb, struct minidump, nb);
+
+	if (code == MEMINSPECT_NOTIFIER_ADD)
+		register_md_region(md, entry);
+	else if (code == MEMINSPECT_NOTIFIER_REMOVE)
+		unregister_md_region(md, entry);
+
+	return 0;
+}
+
+static int qcom_md_probe(struct platform_device *pdev)
+{
+	struct minidump_global_toc *mdgtoc;
+	struct device *dev = &pdev->dev;
+	struct minidump *md;
+	size_t size;
+	int ret;
+
+	md = devm_kzalloc(dev, sizeof(*md), GFP_KERNEL);
+	if (!md)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, md);
+	md->dev = dev;
+	md->nb.notifier_call = qcom_md_notifier_cb;
+
+	mdgtoc = qcom_smem_get(QCOM_SMEM_HOST_ANY, SBL_MINIDUMP_SMEM_ID, &size);
+	if (IS_ERR(mdgtoc)) {
+		ret = PTR_ERR(mdgtoc);
+		return dev_err_probe(dev, ret, "Couldn't find minidump smem item\n");
+	}
+
+	if (size < sizeof(*mdgtoc) || !mdgtoc->status)
+		return dev_err_probe(dev, -EINVAL, "minidump table not ready\n");
+
+	ret = qcom_md_table_init(md, &mdgtoc->subsystems[MINIDUMP_SUBSYSTEM_APSS]);
+	if (ret)
+		return dev_err_probe(dev, ret, "Could not initialize table\n");
+
+	meminspect_notifier_register(&md->nb);
+	meminspect_lock_traverse(md, register_md_region);
+
+	return 0;
+}
+
+static void qcom_md_remove(struct platform_device *pdev)
+{
+	struct minidump *md = platform_get_drvdata(pdev);
+
+	meminspect_notifier_unregister(&md->nb);
+	meminspect_lock_traverse(md, unregister_md_region);
+}
+
+static struct platform_driver qcom_md_driver = {
+	.probe = qcom_md_probe,
+	.remove = qcom_md_remove,
+	.driver  = {
+		.name = "qcom-minidump",
+	},
+};
+
+module_platform_driver(qcom_md_driver);
+
+MODULE_AUTHOR("Eugen Hristev <eugen.hristev@linaro.org>");
+MODULE_AUTHOR("Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>");
+MODULE_DESCRIPTION("Qualcomm minidump inspect driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/soc/qcom/minidump.h b/include/linux/soc/qcom/minidump.h
index 7449a04e6e15..91d73e647d5b 100644
--- a/include/linux/soc/qcom/minidump.h
+++ b/include/linux/soc/qcom/minidump.h
@@ -10,11 +10,14 @@
 #ifndef __QCOM_MINIDUMP_H__
 #define __QCOM_MINIDUMP_H__
 
+#define MINIDUMP_SUBSYSTEM_APSS	0
 #define MAX_REGION_NAME_LENGTH  16
 #define SBL_MINIDUMP_SMEM_ID	602
 #define MINIDUMP_REGION_VALID		('V' << 24 | 'A' << 16 | 'L' << 8 | 'I' << 0)
 #define MINIDUMP_SS_ENCR_DONE		('D' << 24 | 'O' << 16 | 'N' << 8 | 'E' << 0)
+#define MINIDUMP_SS_ENCR_NOTREQ		(0 << 24 | 0 << 16 | 'N' << 8 | 'R' << 0)
 #define MINIDUMP_SS_ENABLED		('E' << 24 | 'N' << 16 | 'B' << 8 | 'L' << 0)
+#define MAX_NUM_REGIONS		201
 
 /**
  * struct minidump_region - Minidump region

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 24/26] soc: qcom: smem: Add minidump platform device
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (22 preceding siblings ...)
  2026-07-08  5:32 ` [PATCH v3 23/26] soc: qcom: Add minidump backend driver Mukesh Ojha
@ 2026-07-08  5:32 ` Mukesh Ojha
  2026-07-08  5:32 ` [PATCH v3 25/26] dt-bindings: reserved-memory: Add Google Kinfo Pixel reserved memory Mukesh Ojha
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:32 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

From: Eugen Hristev <ehristev@kernel.org>

Minidump can collect various memory snippets using Qualcomm boot firmware
support. To determine which snippets should be collected, each snippet
must be registered by the kernel into a shared memory table managed by
the Qualcomm SMEM driver. To instantiate the minidump platform driver,
register its data using platform_device_register_data(). The minidump
driver will later probe the device and retrieve the required memory
snippets from the memory inspection table (meminspect).

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/soc/qcom/smem.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index afb21a778fe7..11ebcfc34d0c 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -267,6 +267,7 @@ struct smem_region {
  * @partitions: list of partitions of current processor/host
  * @item_count: max accepted item number
  * @socinfo:	platform device pointer
+ * @mdinfo:	minidump device pointer
  * @num_regions: number of @regions
  * @regions:	list of the memory regions defining the shared memory
  */
@@ -277,6 +278,7 @@ struct qcom_smem {
 
 	u32 item_count;
 	struct platform_device *socinfo;
+	struct platform_device *mdinfo;
 	struct smem_ptable *ptable;
 	struct smem_partition global_partition;
 	struct xarray partitions;
@@ -1245,12 +1247,20 @@ static int qcom_smem_probe(struct platform_device *pdev)
 	if (IS_ERR(smem->socinfo))
 		dev_dbg(&pdev->dev, "failed to register socinfo device\n");
 
+	smem->mdinfo = platform_device_register_data(&pdev->dev, "qcom-minidump",
+						     PLATFORM_DEVID_AUTO, NULL,
+						     0);
+	if (IS_ERR(smem->mdinfo))
+		dev_err(&pdev->dev, "failed to register platform md device\n");
+
 	return 0;
 }
 
 static void qcom_smem_remove(struct platform_device *pdev)
 {
 	platform_device_unregister(__smem->socinfo);
+	if (!IS_ERR(__smem->mdinfo))
+		platform_device_unregister(__smem->mdinfo);
 
 	xa_destroy(&__smem->partitions);
 	/* Set to -EPROBE_DEFER to signal unprobed state */

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 25/26] dt-bindings: reserved-memory: Add Google Kinfo Pixel reserved memory
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (23 preceding siblings ...)
  2026-07-08  5:32 ` [PATCH v3 24/26] soc: qcom: smem: Add minidump platform device Mukesh Ojha
@ 2026-07-08  5:32 ` Mukesh Ojha
  2026-07-08  7:08 ` [PATCH v3 26/26] meminspect: Add debug kinfo compatible driver Mukesh Ojha
                   ` (2 subsequent siblings)
  27 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  5:32 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Eugen Hristev, Mukesh Ojha,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan
  Cc: workflows, linux-doc, linux-kernel, linux-arch, linux-mm,
	linux-arm-msm, linux-remoteproc, devicetree, Eugen Hristev

Add documentation for Google Kinfo Pixel reserved memory area.

Co-developed-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 .../reserved-memory/google,debug-kinfo.yaml        | 48 ++++++++++++++++++++++
 MAINTAINERS                                        |  6 +++
 2 files changed, 54 insertions(+)

diff --git a/Documentation/devicetree/bindings/reserved-memory/google,debug-kinfo.yaml b/Documentation/devicetree/bindings/reserved-memory/google,debug-kinfo.yaml
new file mode 100644
index 000000000000..d260c2d5f70b
--- /dev/null
+++ b/Documentation/devicetree/bindings/reserved-memory/google,debug-kinfo.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/reserved-memory/google,debug-kinfo.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Google Pixel Kinfo reserved memory
+
+maintainers:
+  - Eugen Hristev <eugen.hristev@linaro.org>
+  - Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
+
+description:
+  Reserved memory region for storing kernel debugging information that
+  can be read by firmware and bootloader on Google Pixel platforms.
+
+allOf:
+  - $ref: reserved-memory.yaml
+
+properties:
+  compatible:
+    const: google,debug-kinfo
+
+  reg:
+    maxItems: 1
+    description: >
+      Page-aligned region of memory containing debugging data of the
+      running kernel.
+
+required:
+  - compatible
+  - reg
+  - no-map
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    reserved-memory {
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        debug-kinfo@fa00000 {
+            compatible = "google,debug-kinfo";
+            reg = <0xfa00000 0x1000>;
+            no-map;
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index fdad8ef377c8..2d816d783024 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16901,6 +16901,12 @@ F:	Documentation/dev-tools/meminspect.rst
 F:	include/linux/meminspect.h
 F:	kernel/meminspect/*
 
+MEMINSPECT KINFO DRIVER
+M:	Eugen Hristev <eugen.hristev@linaro.org>
+M:	Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/reserved-memory/google,debug-kinfo.yaml
+
 MEMBLOCK AND MEMORY MANAGEMENT INITIALIZATION
 M:	Mike Rapoport <rppt@kernel.org>
 L:	linux-mm@kvack.org

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* [PATCH v3 26/26] meminspect: Add debug kinfo compatible driver
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (24 preceding siblings ...)
  2026-07-08  5:32 ` [PATCH v3 25/26] dt-bindings: reserved-memory: Add Google Kinfo Pixel reserved memory Mukesh Ojha
@ 2026-07-08  7:08 ` Mukesh Ojha
  2026-07-08  8:06   ` Lorenzo Stoakes
  2026-07-09 13:24   ` Petr Pavlu
  2026-07-08  7:11 ` [PATCH v3 00/26] Introduce meminspect Lorenzo Stoakes
  2026-07-10  1:51 ` Liam R. Howlett
  27 siblings, 2 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08  7:08 UTC (permalink / raw)
  To: akpm, anna-maria, arnd, andersson, chrisl, cl, conor+dt, david,
	dennis, devicetree, ehristev, frederic, mingo, jstultz, corbet,
	juri.lelli, kasong, kees, konradybcio, krzk+dt, linux-arch,
	linux-arm-msm, linux-doc, linux-kernel, linux-mm,
	linux-remoteproc, mathieu.poirier, mukesh.ojha, peterz, pmladek,
	robh, saravanak, tj, tglx, vincent.guittot, workflows
  Cc: atomlin, ast, aliceryhl, linux.amoon, ardb, baoquan.he, baohua,
	bsegall, jackmanb, leitao, brauner, coxu, dietmar.eggemann,
	dianders, ebiggers, feng.tang, yangfeng, gary, guohanjun, jack,
	wangjinchao600, joel.granados, hannes, john.ogness, jpoimboe,
	shikemeng, kas, kprateek.nayak, liam, ljs, elver, mgorman, mhocko,
	ojeda, rppt, namcao, nathan, nphamcs, n.schier, pasha.tatashin,
	petr.pavlu, pnina.feder, rdunlap, rioo.tsukatsukii, senozhatsky,
	skhan, sboyd, rostedt, surenb, thomas.weissschuh, vschneid,
	vbabka, youngjun.park, zhengyejian, ziy, Eugen Hristev

From: Eugen Hristev <eugen.hristev@linaro.org>

With this driver, the registered regions are copied to a shared memory
zone at register time. The shared memory zone is supplied via OF. This
driver will select only regions that are of interest, and keep only
addresses. The format of the list is Kinfo compatible, with devices like
Google Pixel phone. The firmware is only interested in some symbols'
addresses.

Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 MAINTAINERS                |   1 +
 drivers/of/platform.c      |   1 +
 kernel/meminspect/Kconfig  |  11 ++
 kernel/meminspect/Makefile |   1 +
 kernel/meminspect/kinfo.c  | 257 +++++++++++++++++++++++++++++++++++++
 5 files changed, 271 insertions(+)
 create mode 100644 kernel/meminspect/kinfo.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 2d816d783024..d805ff9fedac 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16906,6 +16906,7 @@ M:	Eugen Hristev <eugen.hristev@linaro.org>
 M:	Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
 S:	Maintained
 F:	Documentation/devicetree/bindings/reserved-memory/google,debug-kinfo.yaml
+F:	kernel/meminspect/kinfo.c
 
 MEMBLOCK AND MEMORY MANAGEMENT INITIALIZATION
 M:	Mike Rapoport <rppt@kernel.org>
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 53bca8c6f781..f80bd25fc481 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -494,6 +494,7 @@ static const struct of_device_id reserved_mem_matches[] = {
 	{ .compatible = "qcom,smem" },
 	{ .compatible = "ramoops" },
 	{ .compatible = "nvmem-rmem" },
+	{ .compatible = "google,debug-kinfo" },
 	{ .compatible = "google,open-dice" },
 	{}
 };
diff --git a/kernel/meminspect/Kconfig b/kernel/meminspect/Kconfig
index 18ff511ad4cf..7f6436c3344b 100644
--- a/kernel/meminspect/Kconfig
+++ b/kernel/meminspect/Kconfig
@@ -16,3 +16,14 @@ config MEMINSPECT
 
 	  Note that modules using this feature must be rebuilt if this
 	  option changes.
+
+config MEMINSPECT_KINFO
+	tristate "Shared memory KInfo compatible driver"
+	depends on MEMINSPECT
+	help
+	  Say y here to enable the Shared memory KInfo compatible driver.
+	  With this driver, the registered regions are copied to a shared
+	  memory zone at register time.
+	  The shared memory zone is supplied via OF.
+	  This driver will select only regions that are of interest,
+	  and keep only addresses. The format of the list is Kinfo compatible.
diff --git a/kernel/meminspect/Makefile b/kernel/meminspect/Makefile
index 09fd55e6d9cf..283604d892e5 100644
--- a/kernel/meminspect/Makefile
+++ b/kernel/meminspect/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-$(CONFIG_MEMINSPECT) += meminspect.o
+obj-$(CONFIG_MEMINSPECT_KINFO) += kinfo.o
diff --git a/kernel/meminspect/kinfo.c b/kernel/meminspect/kinfo.c
new file mode 100644
index 000000000000..7451c13bc316
--- /dev/null
+++ b/kernel/meminspect/kinfo.c
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *
+ * Copyright 2002 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
+ * Copyright 2021 Google LLC
+ * Copyright 2025 Linaro Ltd. Eugen Hristev <eugen.hristev@linaro.org>
+ */
+#include <linux/container_of.h>
+#include <linux/kallsyms.h>
+#include <linux/meminspect.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
+#include <linux/utsname.h>
+
+#define BUILD_INFO_LEN		256
+#define DEBUG_KINFO_MAGIC	0xcceeddff
+
+/*
+ * Header structure must be byte-packed, since the table is provided to
+ * bootloader.
+ */
+struct kernel_info {
+	/* For kallsyms */
+	u8 enabled_all;
+	u8 enabled_base_relative;
+	u8 enabled_absolute_percpu;
+	u8 enabled_cfi_clang;
+	u32 num_syms;
+	u16 name_len;
+	u16 bit_per_long;
+	u16 module_name_len;
+	u16 symbol_len;
+	u64 _relative_pa;
+	u64 _text_pa;
+	u64 _stext_pa;
+	u64 _etext_pa;
+	u64 _sinittext_pa;
+	u64 _einittext_pa;
+	u64 _end_pa;
+	u64 _offsets_pa;
+	u64 _names_pa;
+	u64 _token_table_pa;
+	u64 _token_index_pa;
+	u64 _markers_pa;
+	u64 _seqs_of_names_pa;
+
+	/* For frame pointer */
+	u32 thread_size;
+
+	/* For virt_to_phys */
+	u64 swapper_pg_dir_pa;
+
+	/* For linux banner */
+	u8 last_uts_release[__NEW_UTS_LEN];
+
+	/* For module kallsyms */
+	u32 enabled_modules_tree_lookup;
+	u32 mod_mem_offset;
+	u32 mod_kallsyms_offset;
+} __packed;
+
+struct kernel_all_info {
+	u32 magic_number;
+	u32 combined_checksum;
+	struct kernel_info info;
+} __packed;
+
+struct debug_kinfo {
+	struct device *dev;
+	void *all_info_addr;
+	size_t all_info_size;
+	struct notifier_block nb;
+};
+
+static void update_kernel_all_info(struct kernel_all_info *all_info)
+{
+	struct kernel_info *info;
+	u32 *checksum_info;
+	int index;
+
+	all_info->magic_number = DEBUG_KINFO_MAGIC;
+	all_info->combined_checksum = 0;
+
+	info = &all_info->info;
+	checksum_info = (u32 *)info;
+	for (index = 0; index < sizeof(*info) / sizeof(u32); index++)
+		all_info->combined_checksum ^= checksum_info[index];
+}
+
+static void __maybe_unused register_kinfo_region(void *priv,
+						 const struct inspect_entry *e)
+{
+	struct debug_kinfo *kinfo = priv;
+	struct kernel_all_info *all_info = kinfo->all_info_addr;
+	struct kernel_info *info = &all_info->info;
+	struct uts_namespace *uts;
+	u64 paddr;
+
+	if (e->pa)
+		paddr = e->pa;
+	else
+		paddr = __pa(e->va);
+
+	switch (e->id) {
+	case MEMINSPECT_ID__sinittext:
+		info->_sinittext_pa = paddr;
+		break;
+	case MEMINSPECT_ID__einittext:
+		info->_einittext_pa = paddr;
+		break;
+	case MEMINSPECT_ID__end:
+		info->_end_pa = paddr;
+		break;
+	case MEMINSPECT_ID__text:
+		info->_text_pa = paddr;
+		break;
+	case MEMINSPECT_ID__stext:
+		info->_stext_pa = paddr;
+		break;
+	case MEMINSPECT_ID__etext:
+		info->_etext_pa = paddr;
+		break;
+	case MEMINSPECT_ID_kallsyms_num_syms:
+		info->num_syms = *(__u32 *)e->va;
+		break;
+	case MEMINSPECT_ID_kallsyms_offsets:
+		info->_offsets_pa = paddr;
+		break;
+	case MEMINSPECT_ID_kallsyms_names:
+		info->_names_pa = paddr;
+		break;
+	case MEMINSPECT_ID_kallsyms_token_table:
+		info->_token_table_pa = paddr;
+		break;
+	case MEMINSPECT_ID_kallsyms_token_index:
+		info->_token_index_pa = paddr;
+		break;
+	case MEMINSPECT_ID_kallsyms_markers:
+		info->_markers_pa = paddr;
+		break;
+	case MEMINSPECT_ID_kallsyms_seqs_of_names:
+		info->_seqs_of_names_pa = paddr;
+		break;
+	case MEMINSPECT_ID_swapper_pg_dir:
+		info->swapper_pg_dir_pa = paddr;
+		break;
+	case MEMINSPECT_ID_init_uts_ns:
+		if (!e->va)
+			return;
+		uts = e->va;
+		strscpy(info->last_uts_release, uts->name.release, __NEW_UTS_LEN);
+		break;
+	default:
+		break;
+	};
+
+	update_kernel_all_info(all_info);
+}
+
+static int kinfo_notifier_cb(struct notifier_block *nb,
+			     unsigned long code, void *entry)
+{
+	struct debug_kinfo *kinfo = container_of(nb, struct debug_kinfo, nb);
+
+	if (code == MEMINSPECT_NOTIFIER_ADD)
+		register_kinfo_region(kinfo, entry);
+
+	return NOTIFY_DONE;
+}
+
+static int debug_kinfo_probe(struct platform_device *pdev)
+{
+	struct kernel_all_info *all_info;
+	struct device *dev = &pdev->dev;
+	struct reserved_mem *rmem;
+	struct debug_kinfo *kinfo;
+	struct kernel_info *info;
+
+	rmem = of_reserved_mem_lookup(dev->of_node);
+	if (!rmem)
+		return dev_err_probe(dev, -ENODEV, "no such reserved mem of node name %s\n",
+			      dev->of_node->name);
+
+	/* Need to wait for reserved memory to be mapped */
+	if (!rmem->priv)
+		return -EPROBE_DEFER;
+
+	if (!rmem->base || !rmem->size)
+		dev_err_probe(dev, -EINVAL, "unexpected reserved memory\n");
+
+	if (rmem->size < sizeof(struct kernel_all_info))
+		dev_err_probe(dev, -EINVAL, "reserved memory size too small\n");
+
+	kinfo = devm_kzalloc(dev, sizeof(*kinfo), GFP_KERNEL);
+	if (!kinfo)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, kinfo);
+
+	kinfo->dev = dev;
+	kinfo->all_info_addr = rmem->priv;
+	kinfo->all_info_size = rmem->size;
+
+	all_info = kinfo->all_info_addr;
+
+	memset(all_info, 0, sizeof(struct kernel_all_info));
+	info = &all_info->info;
+	info->enabled_all = IS_ENABLED(CONFIG_KALLSYMS_ALL);
+	info->enabled_absolute_percpu = IS_ENABLED(CONFIG_KALLSYMS_ABSOLUTE_PERCPU);
+	info->enabled_base_relative = IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE);
+	info->enabled_cfi_clang = IS_ENABLED(CONFIG_CFI_CLANG);
+	info->name_len = KSYM_NAME_LEN;
+	info->bit_per_long = BITS_PER_LONG;
+	info->module_name_len = MODULE_NAME_LEN;
+	info->symbol_len = KSYM_SYMBOL_LEN;
+	info->thread_size = THREAD_SIZE;
+	info->enabled_modules_tree_lookup = IS_ENABLED(CONFIG_MODULES_TREE_LOOKUP);
+	info->mod_mem_offset = offsetof(struct module, mem);
+	info->mod_kallsyms_offset = offsetof(struct module, kallsyms);
+
+	kinfo->nb.notifier_call = kinfo_notifier_cb;
+
+	meminspect_notifier_register(&kinfo->nb);
+	meminspect_lock_traverse(kinfo, register_kinfo_region);
+
+	return 0;
+}
+
+static void debug_kinfo_remove(struct platform_device *pdev)
+{
+	struct debug_kinfo *kinfo = platform_get_drvdata(pdev);
+
+	meminspect_notifier_unregister(&kinfo->nb);
+}
+
+static const struct of_device_id debug_kinfo_of_match[] = {
+	{ .compatible	= "google,debug-kinfo" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, debug_kinfo_of_match);
+
+static struct platform_driver debug_kinfo_driver = {
+	.probe = debug_kinfo_probe,
+	.remove = debug_kinfo_remove,
+	.driver = {
+		.name = "debug-kinfo",
+		.of_match_table = debug_kinfo_of_match,
+	},
+};
+module_platform_driver(debug_kinfo_driver);
+
+MODULE_AUTHOR("Eugen Hristev <eugen.hristev@linaro.org>");
+MODULE_AUTHOR("Jone Chou <jonechou@google.com>");
+MODULE_DESCRIPTION("meminspect Kinfo Driver");
+MODULE_LICENSE("GPL");
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 00/26] Introduce meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (25 preceding siblings ...)
  2026-07-08  7:08 ` [PATCH v3 26/26] meminspect: Add debug kinfo compatible driver Mukesh Ojha
@ 2026-07-08  7:11 ` Lorenzo Stoakes
  2026-07-08  8:18   ` Lorenzo Stoakes
  2026-07-10  1:51 ` Liam R. Howlett
  27 siblings, 1 reply; 46+ messages in thread
From: Lorenzo Stoakes @ 2026-07-08  7:11 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree,
	Jason Gunthorpe

+cc Jason as maybe he has thoughts on this...

Overall - for this to be sensibly mainlined, we need to see a. a COMPELLING case
made for this feature, b. some buy-in from others, and c. have confidence this
will be properly maintained.

I don't feel you've demonstrated any of these.

And looking through the history of this (you've made it really hard with your
changelog):

    v2 - https://lore.kernel.org/lkml/20260311-minidump-v2-v2-0-f91cedc6f99e@oss.qualcomm.com/
    v1 - https://lore.kernel.org/lkml/20251119154427.1033475-1-eugen.hristev@linaro.org/
RFC v3 - (I literally can't find it...?)
RFC v2 - https://lore.kernel.org/all/20250724135512.518487-1-eugen.hristev@linaro.org/
RFC v1 - https://lore.kernel.org/lkml/20250422113156.575971-1-eugen.hristev@linaro.org/

I'm struggling to understand why on earth it came out of RFC?

You really shouldn't drop the RFC tag unless you've got CLEAR signal that the
community wants the feature and that there's buy-in.

Instead you've got some specific technical feedback, some trivia, etc. which
warrants RFC respins, but nothing to suggest buy-in.

So please attach the RFC tag to any future respins. And I suggest you make the
case for this a LOT clearer and seek to engage with others to confirm that there
is anybody else who wants this.

On Wed, Jul 08, 2026 at 11:01:39AM +0530, Mukesh Ojha wrote:
> First of all, I want to thank Eugene for his excellent work on this
> series. What began as the Qualcomm Minidump driver from me has now
> evolved into meminspect. He also presented meminspect at Linux
> Plumbers 2025.
>
> Video of the recording is available here for anyone interested:
> https://www.youtube.com/watch?v=aDZv4-kOLSc

It's iffy putting links like this in a commit message that'll end up as a commit
(in mm we put the cover letter in). Links can die. Companies can change their
minds about videos being available.

Maybe better as something explicitly after the commit message.

>
> Introduction: Memory inspection mechanism
>
> meminspect is a mechanism which allows the kernel to mark specific
> memory areas for memory dumping or specific inspection, statistics,
> usage.  Once regions are marked, meminspect keeps an internal list with
> the regions in a dedicated table.  Further, these regions can be
> accessed using specific API by any interested driver.  Regions being
> marked beforehand, when the system is up and running, there is no need
> nor dependency on a panic handler, or a working kernel that can dump the
> debug information.  meminspect can be primarily used for debugging. The
> approach is feasible to work when pstore, kdump, or another mechanism do
> not. Pstore relies on persistent storage, a dedicated RAM area or
> flash, which has the disadvantage of having the memory reserved all the
> time, or another specific non volatile memory. Some devices cannot keep
> the RAM contents on reboot so ramoops does not work. Some devices do not
> allow kexec to run another kernel to debug the crashed one.  For such
> devices, that have another mechanism to help debugging, like firmware,
> meminspect is a viable solution.

Please use paragraphs, this is an unreadable wall of text and it just seems
to be noise.

Why would we want to mark specific areas a special way? What are the
trade-offs, what does that actually do? How do you interact with it? Why
can't other approaches be used?

You should make it CLEAR what exactly the benefits are and why this is
better than alternatives.

>
> meminspect can create a core image, similar with /proc/vmcore, with only
> the registered regions included. This can be loaded into crash tool/gdb
> and analyzed. This happens if CRASH_DUMP=y.  To have this working,

What is CRASH_DUMP? Where is it defined? You mean CONFIG_CRASH_DUMP?

> specific information from the kernel is registered, and this is done at
> meminspect init time, no need for the meminspect users to do anything.

Again this just doesn't really mean anything to me?

>
> This version of the meminspect patch series includes two drivers that
> make use of it: one is the Qualcomm Minidump, and the other one is the
> Debug Kinfo backend for Android devices, reworked from this source here:
> https://android.googlesource.com/kernel/common/+/refs/heads/android-mainline/drivers/android/debug_kinfo.c
> written originally by Jone Chou <jonechou@google.com>

This feels rather like you've taken a specific use case you have, and
worked backwards from it to changes to core, honestly.

>
> Tested on Qualcomm SA8775P (Lemans EVK) on next-20260707 with the
> minidump backend: kernel crash dump regions correctly captured
> via firmware.

What is a minidump backend? There's no detail about the testing here
either. Does anybody outside of Qualcomm care about this?

>
> This series introduces a new cross-subsystem framework and, to
> avoid merge ordering issues, I suggest the entire series be taken
> via the mm tree. Subsystem maintainers for touched files have
> been CC'd; I request an Acked-by from them if the respective
> patches look fine from their side.

Don't put stuff about mechanics of merge in the middle of a cover letter
that will go into the git log, put this and the stuff about the video in a
block of text below the main text, you can tag it 'REVIEWERS NOTES' or
similar.

Not only A-b for touched files, but as this is ostensibly an mm feature
you'll need tags from mm maintainers and acceptance of the feature overall
for it to be accepted.

>
> Alternatively, the qcom backend patches (22-24) can be deferred
> to Bjorn's qcom tree in a follow-on series once the core
> meminspect framework lands.

I think that would be better yes, you shouldn't be adding new driver
changes in a core series like this, only touching stuff you have to touch
as a result of the core change.

Anything else should be saved for later series. You can express ordering
requirements in the cover letter...

>
> *** How to use meminspect with minidump backend on Qualcomm platform guide ***

Odd to put a specific qualcomm TODO in a cover letter for a mainline
feature...

Again this makes it feels like this is something you want for your driver,
and the core changes are just a means of getting there, which is not an
acceptable justification for core changes.

You have to rework this entire cover letter to sell it as a GENERAL
feature.

I'm really not convinced we want to give drivers (which are great at doing
exactly the wrong thing with mm APIs) the ability to do invasive things in
mm.

>
> Prerequisites:
> Crash tool compiled with target=ARM64.
>
> Target kernel must be built with: CONFIG_DEBUG_INFO_REDUCED=n;
> this will have vmlinux include all the debugging information
> needed for the crash tool and CONFIG_MEMINSPECT,
> CONFIG_CRASH_DUMP, and the driver CONFIG_QCOM_MINIDUMP.
> Kernel arguments: Kernel firmware must be set to mode 'mini' by kernel
> module parameter like this : qcom_scm.download_mode=mini
>
> After the kernel boots and the minidump module is loaded,
> everything is ready for a possible crash. Upon triggering a
> forced kernel crash, the target board will wait in download mode,
> where QDL (https://github.com/linux-msm/qdl) running on the host
> connected to the target (here, Lemans EVK) can be used to collect
> minidump.elf from the target device onto the host.
>
> Currently, --minimal mode is being used to get dmesg log from
> crashed device.
>
> Without --minimal mode, the crash tool needs to be patched to
> not crash on missing symbols and needs to be tuned, which I am
> currently working on in parallel.
>
> crash> log
> [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x514f0014]
> [    0.000000] Linux version 7.0.0-rc3-next-20260309-00028-g528b3c656121 (@21e3bca4168f) (aarch64-linux-gnu-gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #5 SMP PREEMPT Tue Mar 10 18:18:41 UTC 2026
>
> *** Debug Kinfo backend driver ***
> I need help with the testing of this driver, Anyone who actually wants

Err you're putting forward a non-RFC series to mainline and also saying
essentially it's untested at least in one respect?

This is signal that this should _remain_ RFC.

> to test this, feel free to reply to the patch. we have also written a
> simple DT binding for the driver.
>
> Thanks in advance for the review, and apologies if I missed addressing any comment.
>
> -Mukesh
>
> Changes in v3: https://lore.kernel.org/lkml/20260311-minidump-v2-v2-0-f91cedc6f99e@oss.qualcomm.com/

And again, ->v2 but you label it v3...!

> - Addressed most of doc. comments and binding and 0-day kernel
>   test robot warning.
> - Add timekeeping: Register tk_data into meminspect
> - fixed some of the bugs identified during testing.
> - Fix missing return before dev_err_probe() in qcom_md_probe(); all
>   three error paths (SMEM lookup, table validation, table init) now
>   correctly abort probe on failure
> - Fix meminspect_traverse() kernel-doc: @priv description corrected
> - Fix meminspect.rst: replace stale MEMINSPECT_ITERATOR_CB type name
>   with the actual meminspect_iter_cb_t typedef
> - Add kernel-doc for meminspect_iter_cb_t typedef
> - Lot of code formating and style change as per coding standard.
>
> Changes in v2: https://lore.kernel.org/lkml/20251119154427.1033475-1-eugen.hristev@linaro.org/

The link is to v1... what a mess!

>  - Fixed doc warnings
>  - Fixed kernel-test robot warnings.
>  - Took Mike suggestion to remove mark inspect flag for dynamic memory.
>  - Added R-b for printk patch.
>  - Modified some commit messages for clarity.
>  - corrected binding change for debug-kinfo as per Rob suggestion.
>
> Changelog for meminspect v1:

You don't include a link to RFC v3 at all?

> - rename to meminspect
> - start on top of v2 actually, with the section and all.
> - remove the backend thing, change the API to access the table
> - move everything to kernel/
> - add dependency to CRASH_DUMP instead of a separate knob
> - move the minidump driver to soc/qcom
> - integrate the meminspect better into memblock by using a new memblock flag
> - minor fixes : use dev_err_probe everywhere, rearrange variable declarations,
> remove some useless code, etc.
>
> Changelog for RFC v3:
> - V2 available here : https://lore.kernel.org/all/20250724135512.518487-1-eugen.hristev@linaro.org/

Same comment as below. Put links for changelogs with the version you're changing
it's a total nightmare trying to follow this.

And I literally cannot find RFC v3 on list, did you mislabel it?

> - Removed the .section as requested by David Hildenbrand.
> - Moved all kmemdump registration(when possible) to vmcoreinfo.
> - Because of this, some of the variables that I was registering had to be non-static
> so I had to modify this as per David Hildenbrand suggestion.
> - Fixed minor things in the Kinfo driver: one field was broken, fixed some
> compiler warnings, fixed the copyright and remove some useless includes.
> - Moved the whole kmemdump from drivers/debug into mm/ and Kconfigs into mm/Kconfig.debug
> and it's now available in kernel hacking, as per Randy Dunlap review
> - Reworked some of the Documentation as per review from Jon Corbet
>
> Changelog for RFC v2:
> - V1 available here: https://lore.kernel.org/lkml/20250422113156.575971-1-eugen.hristev@linaro.org/

Why are you linking the previous version here, it's strange.

Just put RFC v1: with the link below, same goes for other cases.

> - Reworked the whole minidump implementation based on suggestions from Thomas Gleixner.
> This means new API, macros, new way to store the regions inside kmemdump
> (ditched the IDR, moved to static allocation, have a static default backend, etc)
> - Reworked qcom_minidump driver based on review from Bjorn Andersson
> - Reworked printk log buffer registration based on review from Petr Mladek.
>
> ---
> Eugen Hristev (21):
>       kernel: Introduce meminspect
>       init/version: Annotate static information into meminspect
>       mm/percpu: Annotate static information into meminspect
>       cpu: Annotate static information into meminspect
>       genirq/irqdesc: Annotate static information into meminspect
>       timers: Annotate static information into meminspect
>       kernel/fork: Annotate static information into meminspect
>       mm/page_alloc: Annotate static information into meminspect
>       mm/show_mem: Annotate static information into meminspect
>       mm/swapfile: Annotate static information into meminspect
>       kernel/vmcore_info: Register dynamic information into meminspect
>       kernel/configs: Register dynamic information into meminspect
>       mm/init-mm: Annotate static information into meminspect
>       panic: Annotate static information into meminspect
>       kallsyms: Annotate static information into meminspect
>       mm/mm_init: Annotate static information into meminspect
>       sched/core: Annotate runqueues into meminspect
>       remoteproc: qcom: Move minidump data structures into its own header
>       soc: qcom: Add minidump backend driver
>       soc: qcom: smem: Add minidump platform device
>       meminspect: Add debug kinfo compatible driver
>
> Mukesh Ojha (5):
>       timekeeping: Register tk_data into meminspect
>       mm/numa: Register node data information into meminspect
>       mm/sparse: Register information into meminspect
>       printk: Register information into meminspect
>       dt-bindings: reserved-memory: Add Google Kinfo Pixel reserved memory
>
>  Documentation/dev-tools/index.rst                  |   1 +
>  Documentation/dev-tools/meminspect.rst             | 144 +++++++
>  .../reserved-memory/google,debug-kinfo.yaml        |  48 +++
>  MAINTAINERS                                        |  16 +
>  drivers/of/platform.c                              |   1 +
>  drivers/remoteproc/qcom_common.c                   |  55 +--
>  drivers/soc/qcom/Kconfig                           |  13 +
>  drivers/soc/qcom/Makefile                          |   1 +
>  drivers/soc/qcom/minidump.c                        | 271 ++++++++++++
>  drivers/soc/qcom/smem.c                            |  10 +

Yeah I hate that you're adding a wholy unrelated driver feature as part of this.

Let's not.

>  include/asm-generic/vmlinux.lds.h                  |  13 +
>  include/linux/meminspect.h                         | 271 ++++++++++++
>  include/linux/soc/qcom/minidump.h                  |  70 +++
>  init/Kconfig                                       |   1 +
>  init/version-timestamp.c                           |   3 +
>  init/version.c                                     |   3 +
>  kernel/Makefile                                    |   1 +
>  kernel/configs.c                                   |   6 +
>  kernel/cpu.c                                       |   5 +
>  kernel/fork.c                                      |   3 +
>  kernel/irq/irqdesc.c                               |   2 +
>  kernel/kallsyms.c                                  |   9 +
>  kernel/meminspect/Kconfig                          |  29 ++
>  kernel/meminspect/Makefile                         |   4 +
>  kernel/meminspect/kinfo.c                          | 257 +++++++++++
>  kernel/meminspect/meminspect.c                     | 474 +++++++++++++++++++++
>  kernel/panic.c                                     |   4 +
>  kernel/printk/printk.c                             |  12 +
>  kernel/sched/core.c                                |   2 +
>  kernel/time/timekeeping.c                          |   2 +
>  kernel/time/timer.c                                |   2 +
>  kernel/vmcore_info.c                               |   4 +
>  mm/init-mm.c                                       |  12 +
>  mm/mm_init.c                                       |   2 +
>  mm/numa.c                                          |   2 +
>  mm/page_alloc.c                                    |   2 +
>  mm/percpu.c                                        |   5 +
>  mm/show_mem.c                                      |   2 +
>  mm/sparse.c                                        |   3 +
>  mm/swapfile.c                                      |   2 +
>  40 files changed, 1713 insertions(+), 54 deletions(-)
> ---
> base-commit: 5c73cd9f0819c1c44e373e3dabb68318b1de1a12
> change-id: 20260708-meminspect-v3-76dd8166c4f1
>
> Best regards,
> --
> -Mukesh Ojha
>

Thanks, Lorenzo

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 01/26] kernel: Introduce meminspect
  2026-07-08  5:31 ` [PATCH v3 01/26] kernel: " Mukesh Ojha
@ 2026-07-08  7:38   ` Lorenzo Stoakes
  2026-07-08 13:33     ` Mukesh Ojha
  0 siblings, 1 reply; 46+ messages in thread
From: Lorenzo Stoakes @ 2026-07-08  7:38 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree

This is an unmergeable mess of a patch but I have broader concerns:

* I'm very concerned that this is just one giant workaround to
  EXPORT_SYMBOLS() for unexported memory, or really just a way for drivers
  to stuff arbitrary VAs/PAs in some global region.

* I'm also very concerned about memory lifecycle - saying a physical range
  X-Y is Z doesn't mean it's forever that? And for virtual addresses it's
  even more problematic - are you going to put vmalloc pointers there that
  can get unmapped? Or direct map ranges that might end up unmapped for
  various reasons? What about memory hotplug?...

* I hate the idea of exposing information about physical (and virtual!)
  memory ranges to drivers arbitrarily, drivers are notorious for doing the
  wrong thing (TM) and this is just asking for people to do 'interesting'
  things with this stuff.

On Wed, Jul 08, 2026 at 11:01:40AM +0530, Mukesh Ojha wrote:
> From: Eugen Hristev <ehristev@kernel.org>
>
> Memory inspection mechanism allows registration of a specific
> memory area (or object) for later inspection purposes. Ranges are
> added into an inspection table, which can be requested and
> analyzed by specific drivers. Drivers would interface with any
> hardware mechanism that will allow inspection of the data,
> including but not limited to: dumping for debugging, creating a
> core dump, analysis, or statistical information. Drivers can
> register a notifier to know when new objects are registered, or
> to traverse an existing inspection table. The inspection table is
> created ahead of time such that it can be later used regardless
> of the state of the kernel (running, frozen, crashed, or any
> particular state).

This is the complete opposite of what a commit message should be...

Firstly it's an totally unacceptable, unreadable wall of text.

Secondly you're not at all describing what you're doing in this commit
here.

As far as I can tell from the code here, you're explicitly only supporting
ELF registered ranges (perhaps static also?)

I mean this is clearly not the whole thing, despite what the commit msg
suggests, as you have 25 further commits (!)

The commit message should explain WHAT THE PATCH IS DOING, the trade-offs,
the motivation, anything that needs to be called out.

It does absolutely none of that and instead you get what seems like
marketing copy in a giant unbroken, unreadable, paragraph.

>
> Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>

This patch is seriously far from being even vaguely upstreamable, and for
an effective v5 this is concerning.

> ---
>  Documentation/dev-tools/index.rst      |   1 +
>  Documentation/dev-tools/meminspect.rst | 144 ++++++++++
>  MAINTAINERS                            |   9 +
>  include/asm-generic/vmlinux.lds.h      |  13 +
>  include/linux/meminspect.h             | 270 +++++++++++++++++++
>  init/Kconfig                           |   1 +
>  kernel/Makefile                        |   1 +
>  kernel/meminspect/Kconfig              |  18 ++
>  kernel/meminspect/Makefile             |   3 +
>  kernel/meminspect/meminspect.c         | 474 +++++++++++++++++++++++++++++++++
>  10 files changed, 934 insertions(+)

This changelog is completely ridiculous for a single patch.

This is kernel 101 stuff... you don't send everything in a single commit
including documentation + MAINTAINERS changes...!

You have to split things up into logical parts.

>
> diff --git a/Documentation/dev-tools/index.rst b/Documentation/dev-tools/index.rst
> index 59cbb77b33ff..ea2989ca1566 100644
> --- a/Documentation/dev-tools/index.rst
> +++ b/Documentation/dev-tools/index.rst
> @@ -40,3 +40,4 @@ Documentation/process/debugging/index.rst
>     autofdo
>     propeller
>     container
> +   meminspect
> diff --git a/Documentation/dev-tools/meminspect.rst b/Documentation/dev-tools/meminspect.rst
> new file mode 100644
> index 000000000000..4ca10e33e4fd
> --- /dev/null
> +++ b/Documentation/dev-tools/meminspect.rst
> @@ -0,0 +1,144 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +==========
> +meminspect
> +==========
> +
> +This document provides information about the meminspect feature.
> +
> +Overview
> +========
> +
> +meminspect is a mechanism that allows the kernel to register a chunk of
> +memory into a table, to be used at a later time for a specific
> +inspection purpose like debugging, memory dumping or statistics.

What's a chunk of memory? Physical memory? MMIO ranges? Virtual ranges? Direct
map? Vmalloc?

Be more specific.

> +
> +meminspect allows drivers to traverse the inspection table on demand,
> +or to register a notifier to be called whenever a new entry is being added
> +or removed.

I absolutely hate the idea of exposing a table of pointers to 'memory' that has
lifetime information to drivers with arbitrary context.

What about security?

> +
> +The reasoning for meminspect is also to minimize the required information
> +in case of a kernel problem. For example a traditional debug method involves
> +dumping the whole kernel memory and then inspecting it. Meminspect allows the
> +users to select which memory is of interest, in order to help this specific
> +use case in production, where memory and connectivity are limited.

Again this is so vague it's uselses...

> +
> +Although the kernel has multiple internal mechanisms, meminspect fits
> +a particular model which is not covered by the others.

This is nebulous nonsense you have to explain WHY and what exactly it gives that
others don't.

You can very well inspect specific areas of memory using

> +
> +meminspect Internals
> +====================
> +
> +API
> +---
> +
> +Static memory can be registered at compile time, by instructing the compiler
> +to create a separate section with annotation info.
> +For each such annotated memory (variables usually), a dedicated struct
> +is created with the required information.
> +To achieve this goal, some basic APIs are available:
> +
> +* MEMINSPECT_ENTRY(idx, sym, sz)
> +  is the basic macro that takes an ID, the symbol, and a size.
> +
> +To make it easier, some wrappers are also defined
> +
> +* MEMINSPECT_SIMPLE_ENTRY(sym)
> +  uses the dedicated MEMINSPECT_ID_##sym with a size equal to sizeof(sym)
> +
> +* MEMINSPECT_NAMED_ENTRY(name, sym)
> +  is a simple entry that has an id that cannot be derived from the sym,
> +  so a name has to be provided
> +
> +* MEMINSPECT_AREA_ENTRY(sym, sz)
> +  registers sym, but with the size given as sz, useful for e.g.
> +  arrays which do not have a fixed size at compile time.
> +
> +For dynamically allocated memory, or for other cases, the following APIs
> +are defined::
> +
> +  meminspect_register_id_pa(enum meminspect_uid id, phys_addr_t zone,
> +                            size_t size, unsigned int type);
> +
> +which takes the ID and the physical address.

What about lifetime?...

Exposing arbitrary physical memory to drivers is just a big nope.

> +
> +Similarly there are variations:
> +
> + * meminspect_register_pa() omits the ID
> + * meminspect_register_id_va() requires the ID but takes a virtual address
> + * meminspect_register_va() omits the ID and requires a virtual address
> +
> +If the ID is not given, the next available dynamic ID is allocated.
> +
> +To unregister a dynamic entry, some APIs are defined:
> + * meminspect_unregister_pa(phys_addr_t zone, size_t size);
> + * meminspect_unregister_id(enum meminspect_uid id);
> + * meminspect_unregister_va(va, size);
> +
> +All of the above have a lock variant that ensures the lock on the table
> +is taken.
> +
> +
> +meminspect drivers
> +------------------
> +
> +Drivers are free to traverse the table by using a dedicated function::
> +
> + meminspect_traverse(void *priv, meminspect_iter_cb_t cb)
> +
> +The callback is called for each entry in the table.
> +
> +Drivers can also register a notifier with meminspect_notifier_register()
> +and unregister with meminspect_notifier_unregister() to be called when a new
> +entry is added or removed.
> +
> +Data structures
> +---------------
> +
> +The regions are stored in a simple fixed size array. It avoids
> +memory allocation overhead. This is not performance critical nor does
> +allocating a few hundred entries create a memory consumption problem.
> +
> +The static variables registered into meminspect are annotated into
> +a dedicated .inspect_table memory section. This is then walked by meminspect
> +at a later time and each variable is then copied to the whole inspect table.
> +
> +meminspect Initialization
> +-------------------------
> +
> +At any time, meminspect is ready to accept region registration
> +from any part of the kernel. The table does not require any initialization.



> +In case CONFIG_CRASH_DUMP is enabled, meminspect creates an ELF header
> +corresponding to a core dump image, in which each region is added as a
> +program header. In this scenario, the first region is this ELF header, and
> +the second region is the vmcoreinfo ELF note.
> +By using this mechanism, all the meminspect table, if dumped, can be
> +concatenated to obtain a core image that is loadable with the `crash` tool.
> +
> +meminspect example
> +==================
> +
> +A simple scenario for meminspect is the following:
> +The kernel registers the linux_banner variable into meminspect with
> +a simple annotation like::
> +
> +  MEMINSPECT_SIMPLE_ENTRY(linux_banner);
> +
> +The meminspect late initcall will parse the compile-time table
> +and copy the entry information into the inspection table.
> +At a later point, any interested driver can call the traverse function to
> +find out all entries in the table.
> +A specific driver will then note into a specific table the address of the
> +banner and the size of it.
> +The specific table is then written to a shared memory area that can be
> +read by upper level firmware.

This feels like you're finding a way to export things that aren't exported...?!

> +When the kernel freezes (hypothetically), the kernel will no longer feed
> +the watchdog. The watchdog will trigger a higher exception level interrupt
> +which will be handled by the upper level firmware. This firmware will then
> +read the shared memory table and find an entry with the start and size of
> +the banner. It will then copy it for debugging purpose. The upper level

This feels like a giant workaround to provide EXPORT_SYMBOLS()

> +firmware will then be able to provide useful debugging information,
> +like in this example, the banner.
> +
> +As seen here, meminspect facilitates the interaction between the kernel
> +and a specific firmware.
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c3f72058a2f2..fdad8ef377c8 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16892,6 +16892,15 @@ F:	arch/*/include/asm/sync_core.h
>  F:	include/uapi/linux/membarrier.h
>  F:	kernel/sched/membarrier.c
>
> +MEMINSPECT
> +M:	Eugen Hristev <eugen.hristev@linaro.org>
> +M:	Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> +L:	linux-kernel@vger.kernel.org
> +S:	Maintained
> +F:	Documentation/dev-tools/meminspect.rst
> +F:	include/linux/meminspect.h
> +F:	kernel/meminspect/*
> +
>  MEMBLOCK AND MEMORY MANAGEMENT INITIALIZATION
>  M:	Mike Rapoport <rppt@kernel.org>
>  L:	linux-mm@kvack.org
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index 5659f4b5a125..3122ddf5517a 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -506,6 +506,8 @@
>  	FW_LOADER_BUILT_IN_DATA						\
>  	TRACEDATA							\
>  									\
> +	MEMINSPECT_TABLE						\
> +									\
>  	PRINTK_INDEX							\
>  									\
>  	/* Kernel symbol table */					\
> @@ -904,6 +906,17 @@
>  #define TRACEDATA
>  #endif
>
> +#ifdef CONFIG_MEMINSPECT
> +#define MEMINSPECT_TABLE						\
> +	. = ALIGN(8);							\
> +	.inspect_table : AT(ADDR(.inspect_table) - LOAD_OFFSET) {	\
> +		BOUNDED_SECTION_POST_LABEL(.inspect_table,		\
> +					   __inspect_table, , _end)	\
> +	}
> +#else
> +#define MEMINSPECT_TABLE
> +#endif
> +
>  #ifdef CONFIG_PRINTK_INDEX
>  #define PRINTK_INDEX							\
>  	.printk_index : AT(ADDR(.printk_index) - LOAD_OFFSET) {		\
> diff --git a/include/linux/meminspect.h b/include/linux/meminspect.h
> new file mode 100644
> index 000000000000..a9eb93c6ea2f
> --- /dev/null
> +++ b/include/linux/meminspect.h
> @@ -0,0 +1,270 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef _MEMINSPECT_H
> +#define _MEMINSPECT_H
> +
> +#include <asm/page.h>
> +#include <linux/notifier.h>
> +
> +enum meminspect_uid {
> +	MEMINSPECT_ID_NONE = 0,
> +	MEMINSPECT_ID_ELF,
> +	MEMINSPECT_ID_VMCOREINFO,
> +	MEMINSPECT_ID_CONFIG,
> +	MEMINSPECT_ID__totalram_pages,
> +	MEMINSPECT_ID___cpu_possible_mask,
> +	MEMINSPECT_ID___cpu_present_mask,
> +	MEMINSPECT_ID___cpu_online_mask,
> +	MEMINSPECT_ID___cpu_active_mask,
> +	MEMINSPECT_ID_mem_section,
> +	MEMINSPECT_ID_jiffies_64,
> +	MEMINSPECT_ID_linux_banner,
> +	MEMINSPECT_ID_nr_threads,
> +	MEMINSPECT_ID_total_nr_irqs,
> +	MEMINSPECT_ID_tainted_mask,
> +	MEMINSPECT_ID_taint_flags,
> +	MEMINSPECT_ID_node_states,
> +	MEMINSPECT_ID___per_cpu_offset,
> +	MEMINSPECT_ID_nr_swapfiles,
> +	MEMINSPECT_ID_init_uts_ns,
> +	MEMINSPECT_ID_printk_rb_static,
> +	MEMINSPECT_ID_printk_rb_dynamic,
> +	MEMINSPECT_ID_prb,
> +	MEMINSPECT_ID_prb_descs,
> +	MEMINSPECT_ID_prb_infos,
> +	MEMINSPECT_ID_prb_data,
> +	MEMINSPECT_ID_clear_seq,
> +	MEMINSPECT_ID_high_memory,
> +	MEMINSPECT_ID_init_mm,
> +	MEMINSPECT_ID__sinittext,
> +	MEMINSPECT_ID__einittext,
> +	MEMINSPECT_ID__end,
> +	MEMINSPECT_ID__text,
> +	MEMINSPECT_ID__stext,
> +	MEMINSPECT_ID__etext,
> +	MEMINSPECT_ID_kallsyms_num_syms,
> +	MEMINSPECT_ID_kallsyms_offsets,
> +	MEMINSPECT_ID_kallsyms_names,
> +	MEMINSPECT_ID_kallsyms_token_table,
> +	MEMINSPECT_ID_kallsyms_token_index,
> +	MEMINSPECT_ID_kallsyms_markers,
> +	MEMINSPECT_ID_kallsyms_seqs_of_names,
> +	MEMINSPECT_ID_swapper_pg_dir,
> +	MEMINSPECT_ID_DYNAMIC,
> +	MEMINSPECT_ID_MAX = 201,

Err why 201?

> +};

This feels like a bunch of stuff you didn't document?

> +
> +#define MEMINSPECT_TYPE_REGULAR		0
> +
> +#define MEMINSPECT_NOTIFIER_ADD		0
> +#define MEMINSPECT_NOTIFIER_REMOVE	1

Broken indentation...

> +
> +/**
> + * struct inspect_entry - memory inspect entry information
> + * @id: unique id for this entry
> + * @va: virtual address for the memory (pointer)

Err what?? Virtual address as mapped how? Are you now assuming things are
mapped?

> + * @pa: physical address for the memory
> + * @size: size of the memory area of this entry
> + * @type: type of the entry (class)

'Class'?

> + */
> +struct inspect_entry {
> +	enum meminspect_uid	id;
> +	void			*va;
> +	phys_addr_t		pa;
> +	size_t			size;
> +	unsigned int		type;
> +};
> +
> +/**
> + * typedef meminspect_iter_cb_t - Iterator callback for meminspect traversal
> + * @priv: private data passed through from the caller of meminspect_traverse()
> + * @ie:   pointer to the current inspect_entry; read-only, table lock held
> + *
> + * The table lock is held by the caller; the callback must not call any
> + * meminspect_table_lock() or meminspect_table_unlock() variants.
> + */
> +typedef void (*meminspect_iter_cb_t)(void *priv, const struct inspect_entry *ie);

So drivers can now just access some tagged region, with a VA that err I
guess we just assume is valid when accessed and a PA that err I guess we
just assume is still being used for what it was tagged for?

This seems insane?

> +
> +#ifdef CONFIG_MEMINSPECT
> +/* .inspect_table section table markers*/
> +extern const struct inspect_entry __inspect_table[];
> +extern const struct inspect_entry __inspect_table_end[];
> +
> +/*
> + * Annotate a static variable into inspection table.
> + * Can be called multiple times for the same ID, in which case
> + * multiple table entries will be created
> + */
> +#define MEMINSPECT_ENTRY(idx, sym, sz)						\
> +	static const struct inspect_entry __UNIQUE_ID(__inspect_entry_##idx)	\
> +	__used __section(".inspect_table") = {					\
> +		.id = idx,							\
> +		.va = (void *)&(sym),						\
> +		.size = (sz),							\
> +	}
> +/*
> + * A simple entry is just a variable, the size of the entry is the variable size
> + * The variable can also be a pointer, the pointer itself is being added in this
> + * case.
> + */
> +#define MEMINSPECT_SIMPLE_ENTRY(sym)	\
> +	MEMINSPECT_ENTRY(MEMINSPECT_ID_##sym, sym, sizeof(sym))
> +/*
> + * In the case when `sym` is not a variable, but a member of a struct e.g.,
> + * and we cannot derive a name from it, a name must be provided.
> + */
> +#define MEMINSPECT_NAMED_ENTRY(name, sym)	\
> +	MEMINSPECT_ENTRY(MEMINSPECT_ID_##name, sym, sizeof(sym))
> +/*
> + * Create a more complex entry, by registering an arbitrary memory starting
> + * at sym. The size is provided as a parameter.
> + * This is used e.g. when the symbol is a start of an unknown sized array.
> + */
> +#define MEMINSPECT_AREA_ENTRY(sym, sz) \
> +	MEMINSPECT_ENTRY(MEMINSPECT_ID_##sym, sym, sz)
> +
> +/* Iterate through .inspect_table section entries */
> +#define for_each_meminspect_entry(__entry)		\
> +	for (__entry = __inspect_table;			\
> +	     __entry < __inspect_table_end;		\
> +	     __entry++)
> +
> +#else
> +#define MEMINSPECT_ENTRY(...)
> +#define MEMINSPECT_SIMPLE_ENTRY(...)
> +#define MEMINSPECT_NAMED_ENTRY(...)
> +#define MEMINSPECT_AREA_ENTRY(...)
> +#endif
> +
> +#ifdef CONFIG_MEMINSPECT
> +
> +/*
> + * Dynamic helpers to register entries.
> + * These do not lock the table, so use with caution.
> + */
> +void meminspect_register_id_pa(enum meminspect_uid id, phys_addr_t zone,
> +			       size_t size, unsigned int type);
> +void meminspect_table_lock(void);
> +void meminspect_table_unlock(void);
> +
> +#define meminspect_register_pa(...) \
> +	meminspect_register_id_pa(MEMINSPECT_ID_DYNAMIC, __VA_ARGS__, MEMINSPECT_TYPE_REGULAR)
> +
> +#define meminspect_register_id_va(id, va, size) \
> +	meminspect_register_id_pa(id, virt_to_phys(va), size, MEMINSPECT_TYPE_REGULAR)
> +
> +#define meminspect_register_va(...) \
> +	meminspect_register_id_va(MEMINSPECT_ID_DYNAMIC, __VA_ARGS__)
> +
> +void meminspect_unregister_pa(phys_addr_t zone, size_t size);
> +void meminspect_unregister_id(enum meminspect_uid id);
> +
> +#define meminspect_unregister_va(va, size) \
> +	meminspect_unregister_pa(virt_to_phys(va), size)
> +
> +void meminspect_traverse(void *priv, meminspect_iter_cb_t cb);
> +
> +/*
> + * Producers, or registrators, are advised to use the locked API below
> + */
> +#define meminspect_lock_register_pa(...)			\
> +	do {							\
> +		meminspect_table_lock();			\
> +		meminspect_register_pa(__VA_ARGS__);		\
> +		meminspect_table_unlock();			\
> +	} while (0)
> +
> +#define meminspect_lock_register_id_va(...)			\
> +	do {							\
> +		meminspect_table_lock();			\
> +		meminspect_register_id_va(__VA_ARGS__);		\
> +		meminspect_table_unlock();			\
> +	} while (0)
> +
> +#define meminspect_lock_register_va(...)			\
> +	do {							\
> +		meminspect_table_lock();			\
> +		meminspect_register_va(__VA_ARGS__);		\
> +		meminspect_table_unlock();			\
> +	} while (0)
> +
> +#define meminspect_lock_unregister_pa(...)			\
> +	do {							\
> +		meminspect_table_lock();			\
> +		meminspect_unregister_pa(__VA_ARGS__);		\
> +		meminspect_table_unlock();			\
> +	} while (0)
> +
> +#define meminspect_lock_unregister_va(...)			\
> +	do {							\
> +		meminspect_table_lock();			\
> +		meminspect_unregister_va(__VA_ARGS__);		\
> +		meminspect_table_unlock();			\
> +	} while (0)
> +
> +#define meminspect_lock_unregister_id(...)			\
> +	do {							\
> +		meminspect_table_lock();			\
> +		meminspect_unregister_id(__VA_ARGS__);		\
> +		meminspect_table_unlock();			\
> +	} while (0)
> +
> +#define meminspect_lock_traverse(...)				\
> +	do {							\
> +		meminspect_table_lock();			\
> +		meminspect_traverse(__VA_ARGS__);		\
> +		meminspect_table_unlock();			\
> +	} while (0)
> +
> +int meminspect_notifier_register(struct notifier_block *n);
> +int meminspect_notifier_unregister(struct notifier_block *n);
> +
> +#else
> +static inline void meminspect_register_id_pa(enum meminspect_uid id,
> +					     phys_addr_t zone,
> +					     size_t size, unsigned int type)
> +{
> +}
> +
> +static inline void meminspect_table_lock(void)
> +{
> +}
> +
> +static inline void meminspect_table_unlock(void)
> +{
> +}
> +
> +static inline void meminspect_unregister_pa(phys_addr_t zone, size_t size)
> +{
> +}
> +
> +static inline void meminspect_unregister_id(enum meminspect_uid id)
> +{
> +}
> +
> +static inline void meminspect_traverse(void *priv, meminspect_iter_cb_t cb)
> +{
> +}
> +
> +static inline int meminspect_notifier_register(struct notifier_block *n)
> +{
> +	return 0;
> +}
> +
> +static inline int meminspect_notifier_unregister(struct notifier_block *n)
> +{
> +	return 0;
> +}
> +
> +#define meminspect_register_pa(...)		do { } while (0)
> +#define meminspect_register_id_va(...)		do { } while (0)
> +#define meminspect_register_va(...)		do { } while (0)
> +#define meminspect_lock_register_pa(...)	do { } while (0)
> +#define meminspect_lock_register_va(...)	do { } while (0)
> +#define meminspect_lock_register_id_va(...)	do { } while (0)
> +#define meminspect_lock_traverse(...)		do { } while (0)
> +#define meminspect_lock_unregister_va(...)	do { } while (0)
> +#define meminspect_lock_unregister_pa(...)	do { } while (0)
> +#define meminspect_lock_unregister_id(...)	do { } while (0)
> +#endif
> +
> +#endif
> diff --git a/init/Kconfig b/init/Kconfig
> index fa42fb264c9c..adbe607b7b62 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -2294,6 +2294,7 @@ config TRACEPOINTS
>  source "kernel/Kconfig.kexec"
>
>  source "kernel/liveupdate/Kconfig"
> +source "kernel/meminspect/Kconfig"
>
>  endmenu		# General setup
>
> diff --git a/kernel/Makefile b/kernel/Makefile
> index 1e1a31673577..7c74a4f94a81 100644
> --- a/kernel/Makefile
> +++ b/kernel/Makefile
> @@ -52,6 +52,7 @@ obj-y += locking/
>  obj-y += power/
>  obj-y += printk/
>  obj-y += irq/
> +obj-y += meminspect/
>  obj-y += rcu/
>  obj-y += livepatch/
>  obj-y += liveupdate/
> diff --git a/kernel/meminspect/Kconfig b/kernel/meminspect/Kconfig
> new file mode 100644
> index 000000000000..18ff511ad4cf
> --- /dev/null
> +++ b/kernel/meminspect/Kconfig
> @@ -0,0 +1,18 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +config MEMINSPECT
> +	bool "Allow the kernel to register memory regions for inspection purpose"
> +	depends on !CRASH_DUMP || DMA_CMA

Why does it depend on CONFIG_DMA_CMA?

> +	help
> +	  Inspection mechanism allows registration of a specific memory
> +	  area (or object) for later inspection purposes. Ranges are added
> +	  into an inspection table, which can be requested and analyzed by
> +	  specific drivers. Drivers would interface any hardware mechanism
> +	  that will allow inspection of the data, including but not limited
> +	  to: dumping for debugging, creating a coredump, analysis, or
> +	  statistical information.  The inspection table is created ahead
> +	  of time such that it can be later used regardless of the state of
> +	  the kernel (running, frozen, crashed, or any particular state).

Another wall of text and it's not at all clear what this is suppose to do,
this needs to be completely reworked.

> +
> +	  Note that modules using this feature must be rebuilt if this
> +	  option changes.
> diff --git a/kernel/meminspect/Makefile b/kernel/meminspect/Makefile
> new file mode 100644
> index 000000000000..09fd55e6d9cf
> --- /dev/null
> +++ b/kernel/meminspect/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_MEMINSPECT) += meminspect.o
> diff --git a/kernel/meminspect/meminspect.c b/kernel/meminspect/meminspect.c
> new file mode 100644
> index 000000000000..d9d38f484f1f
> --- /dev/null
> +++ b/kernel/meminspect/meminspect.c
> @@ -0,0 +1,474 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/crash_core.h>
> +#include <linux/dma-map-ops.h>
> +#include <linux/errno.h>
> +#include <linux/meminspect.h>
> +#include <linux/notifier.h>
> +#include <linux/vmcore_info.h>
> +
> +static DEFINE_MUTEX(meminspect_lock);
> +static struct inspect_entry inspect_entries[MEMINSPECT_ID_MAX];
> +
> +static ATOMIC_NOTIFIER_HEAD(meminspect_notifier_list);
> +
> +#ifdef CONFIG_CRASH_DUMP
> +
> +#define CORE_STR "CORE"
> +
> +static struct elfhdr *ehdr;
> +static size_t elf_offset;
> +static bool elf_hdr_ready;
> +
> +static void append_kcore_note(char *notes, size_t *i, const char *name,
> +			      unsigned int type, const void *desc,
> +			      size_t descsz)
> +{
> +	struct elf_note *note = (struct elf_note *)&notes[*i];
> +
> +	note->n_namesz = strlen(name) + 1;
> +	note->n_descsz = descsz;
> +	note->n_type = type;
> +	*i += sizeof(*note);
> +	memcpy(&notes[*i], name, note->n_namesz);
> +	*i = ALIGN(*i + note->n_namesz, 4);
> +	memcpy(&notes[*i], desc, descsz);
> +	*i = ALIGN(*i + descsz, 4);
> +}
> +
> +static void append_kcore_note_nodesc(char *notes, size_t *i, const char *name,
> +				     unsigned int type, size_t descsz)
> +{
> +	struct elf_note *note = (struct elf_note *)&notes[*i];
> +
> +	note->n_namesz = strlen(name) + 1;
> +	note->n_descsz = descsz;
> +	note->n_type = type;
> +	*i += sizeof(*note);
> +	memcpy(&notes[*i], name, note->n_namesz);
> +	*i = ALIGN(*i + note->n_namesz, 4);
> +}
> +
> +static struct elf_phdr *elf_phdr_entry_addr(struct elfhdr *ehdr, int idx)
> +{
> +	struct elf_phdr *ephdr = (struct elf_phdr *)((size_t)ehdr + ehdr->e_phoff);
> +
> +	return &ephdr[idx];
> +}
> +
> +static int clear_elfheader(const struct inspect_entry *e)
> +{
> +	struct elf_phdr *phdr;
> +	struct elf_phdr *tmp_phdr;
> +	unsigned int phidx;
> +	unsigned int i;
> +
> +	for (i = 0; i < ehdr->e_phnum; i++) {
> +		phdr = elf_phdr_entry_addr(ehdr, i);
> +		if (phdr->p_paddr == e->pa &&
> +		    phdr->p_memsz == ALIGN(e->size, 4))
> +			break;
> +	}
> +
> +	if (i == ehdr->e_phnum) {
> +		pr_debug("Cannot find program header entry in elf\n");
> +		return -EINVAL;
> +	}
> +
> +	phidx = i;
> +
> +	/* Clear program header */
> +	tmp_phdr = elf_phdr_entry_addr(ehdr, phidx);
> +	for (i = phidx; i < ehdr->e_phnum - 1; i++) {
> +		tmp_phdr = elf_phdr_entry_addr(ehdr, i + 1);
> +		phdr = elf_phdr_entry_addr(ehdr, i);
> +		memcpy(phdr, tmp_phdr, sizeof(*phdr));
> +		phdr->p_offset = phdr->p_offset - ALIGN(e->size, 4);
> +	}
> +	memset(tmp_phdr, 0, sizeof(*tmp_phdr));
> +	ehdr->e_phnum--;
> +
> +	elf_offset -= ALIGN(e->size, 4);
> +
> +	return 0;
> +}
> +
> +static void update_elfheader(const struct inspect_entry *e)
> +{
> +	struct elf_phdr *phdr;
> +
> +	phdr = elf_phdr_entry_addr(ehdr, ehdr->e_phnum++);
> +
> +	phdr->p_type = PT_LOAD;
> +	phdr->p_offset = elf_offset;
> +	phdr->p_vaddr = (elf_addr_t)e->va;
> +	if (e->pa)
> +		phdr->p_paddr = (elf_addr_t)e->pa;
> +	else
> +		phdr->p_paddr = (elf_addr_t)virt_to_phys(e->va);
> +
> +	phdr->p_filesz = ALIGN(e->size, 4);
> +	phdr->p_memsz = ALIGN(e->size, 4);
> +	phdr->p_flags = PF_R | PF_W;
> +	elf_offset += ALIGN(e->size, 4);
> +}
> +
> +/*
> + * This function prepares the elf header for the coredump image.
> + * Initially there is a single program header for the elf NOTE.
> + * The note contains the usual core dump information, and the vmcoreinfo.
> + */
> +static int init_elfheader(void)
> +{
> +	struct elf_phdr *phdr;
> +	void *notes;
> +	unsigned int elfh_size, buf_sz;
> +	unsigned int phdr_off;
> +	size_t note_len, i = 0;
> +	struct page *p;
> +
> +	struct elf_prstatus prstatus = {};
> +	struct elf_prpsinfo prpsinfo = {
> +		.pr_sname = 'R',
> +		.pr_fname = "vmlinux",
> +	};
> +
> +	/*
> +	 * Header buffer contains:
> +	 * ELF header, Note entry with PR status, PR ps info, and vmcoreinfo.
> +	 * Also, MEMINSPECT_ID_MAX program headers.
> +	 */
> +	elfh_size = sizeof(*ehdr);
> +	elfh_size += sizeof(struct elf_prstatus);
> +	elfh_size += sizeof(struct elf_prpsinfo);
> +	elfh_size += sizeof(VMCOREINFO_NOTE_NAME);
> +	elfh_size += ALIGN(vmcoreinfo_size, 4);
> +	elfh_size += (sizeof(*phdr)) * (MEMINSPECT_ID_MAX);
> +
> +	elfh_size = ALIGN(elfh_size, 4);
> +
> +	/* Length of the note is made of :
> +	 * 3 elf notes structs (prstatus, prpsinfo, vmcoreinfo)
> +	 * 3 notes names (2 core strings, 1 vmcoreinfo name)
> +	 * sizeof each note
> +	 */
> +	note_len = (3 * sizeof(struct elf_note) +
> +		    2 * ALIGN(sizeof(CORE_STR), 4) +
> +		    VMCOREINFO_NOTE_NAME_BYTES +
> +		    ALIGN(sizeof(struct elf_prstatus), 4) +
> +		    ALIGN(sizeof(struct elf_prpsinfo), 4) +
> +		    ALIGN(vmcoreinfo_size, 4));
> +
> +	buf_sz = elfh_size + note_len - ALIGN(vmcoreinfo_size, 4);
> +
> +	/* Never freed */
> +	p = dma_alloc_from_contiguous(NULL, buf_sz >> PAGE_SHIFT,
> +				      get_order(buf_sz), true);
> +	if (!p)
> +		return -ENOMEM;
> +
> +	ehdr = dma_common_contiguous_remap(p, buf_sz,
> +					   pgprot_decrypted(pgprot_dmacoherent(PAGE_KERNEL)),
> +					   __builtin_return_address(0));
> +	if (!ehdr) {
> +		dma_release_from_contiguous(NULL, p, buf_sz >> PAGE_SHIFT);
> +		return -ENOMEM;
> +	}
> +
> +	memset(ehdr, 0, elfh_size);
> +
> +	/* Assign Program headers offset, it's right after the elf header. */
> +	phdr = (struct elf_phdr *)(ehdr + 1);
> +	phdr_off = sizeof(*ehdr);
> +
> +	memcpy(ehdr->e_ident, ELFMAG, SELFMAG);
> +	ehdr->e_ident[EI_CLASS] = ELF_CLASS;
> +	ehdr->e_ident[EI_DATA] = ELF_DATA;
> +	ehdr->e_ident[EI_VERSION] = EV_CURRENT;
> +	ehdr->e_ident[EI_OSABI] = ELF_OSABI;
> +	ehdr->e_type = ET_CORE;
> +	ehdr->e_machine = ELF_ARCH;
> +	ehdr->e_version = EV_CURRENT;
> +	ehdr->e_ehsize = sizeof(*ehdr);
> +	ehdr->e_phentsize = sizeof(*phdr);
> +
> +	elf_offset = elfh_size;
> +
> +	notes = (void *)(((char *)ehdr) + elf_offset);
> +
> +	/* we have a single program header now */
> +	ehdr->e_phnum = 1;
> +
> +	phdr->p_type = PT_NOTE;
> +	phdr->p_offset = elf_offset;
> +	phdr->p_filesz = note_len;
> +
> +	/* advance elf offset */
> +	elf_offset += note_len;
> +
> +	strscpy(prpsinfo.pr_psargs, saved_command_line,
> +		sizeof(prpsinfo.pr_psargs));
> +
> +	append_kcore_note(notes, &i, CORE_STR, NT_PRSTATUS, &prstatus,
> +			  sizeof(prstatus));
> +	append_kcore_note(notes, &i, CORE_STR, NT_PRPSINFO, &prpsinfo,
> +			  sizeof(prpsinfo));
> +	append_kcore_note_nodesc(notes, &i, VMCOREINFO_NOTE_NAME, 0,
> +				 ALIGN(vmcoreinfo_size, 4));
> +
> +	ehdr->e_phoff = phdr_off;
> +
> +	/* This is the first coredump region, the ELF header */
> +	meminspect_register_id_pa(MEMINSPECT_ID_ELF, page_to_phys(p),
> +				  buf_sz, MEMINSPECT_TYPE_REGULAR);
> +
> +	/*
> +	 * The second region is the vmcoreinfo, which goes right after.
> +	 * It's being registered through vmcoreinfo.
> +	 */
> +
> +	return 0;
> +}
> +#endif

Put /* <condition> */ on the end of big #endif blocks please.

> +
> +/**
> + * meminspect_unregister_id() - Unregister region from inspection table.
> + * @id: region's id in the table
> + *
> + * Return: None
> + */
> +void meminspect_unregister_id(enum meminspect_uid id)
> +{
> +	struct inspect_entry *e;
> +
> +	WARN_ON(!mutex_is_locked(&meminspect_lock));
> +
> +	e = &inspect_entries[id];
> +	if (!e->id)
> +		return;
> +
> +	atomic_notifier_call_chain(&meminspect_notifier_list,
> +				   MEMINSPECT_NOTIFIER_REMOVE, e);
> +#ifdef CONFIG_CRASH_DUMP
> +	if (elf_hdr_ready)
> +		clear_elfheader(e);
> +#endif
> +	memset(e, 0, sizeof(*e));
> +}
> +EXPORT_SYMBOL_GPL(meminspect_unregister_id);
> +
> +/**
> + * meminspect_unregister_pa() - Unregister region from inspection table.
> + * @pa: Physical address of the memory region to remove
> + * @size: Size of the memory region to remove
> + *
> + * Return: None
> + */
> +void meminspect_unregister_pa(phys_addr_t pa, size_t size)
> +{
> +	struct inspect_entry *e;
> +	enum meminspect_uid i;
> +
> +	WARN_ON(!mutex_is_locked(&meminspect_lock));
> +
> +	for (i = MEMINSPECT_ID_ELF; i < MEMINSPECT_ID_MAX; i++) {
> +		e = &inspect_entries[i];
> +		if (e->pa != pa)
> +			continue;
> +		if (e->size != size)
> +			continue;
> +		meminspect_unregister_id(e->id);
> +		return;
> +	}
> +}
> +EXPORT_SYMBOL_GPL(meminspect_unregister_pa);
> +
> +/**
> + * meminspect_register_id_pa() - Register region into inspection table
> + *		 with given ID and physical address.
> + * @req_id: Requested unique meminspect_uid that identifies the region
> + *	This can be MEMINSPECT_ID_DYNAMIC, in which case the function will
> + *	find an unused ID and register with it.
> + * @pa: physical address of the memory region
> + * @size: region size
> + * @type: region type
> + *
> + * Return: None
> + */
> +void meminspect_register_id_pa(enum meminspect_uid req_id, phys_addr_t pa,
> +			       size_t size, unsigned int type)
> +{
> +	struct inspect_entry *e;
> +	enum meminspect_uid uid = req_id;
> +
> +	WARN_ON(!mutex_is_locked(&meminspect_lock));
> +
> +	if (uid <= MEMINSPECT_ID_NONE || uid >= MEMINSPECT_ID_MAX)
> +		return;
> +
> +	if (uid == MEMINSPECT_ID_DYNAMIC)
> +		while (uid < MEMINSPECT_ID_MAX) {
> +			if (!inspect_entries[uid].id)
> +				break;
> +			uid++;
> +		}
> +
> +	if (uid == MEMINSPECT_ID_MAX)
> +		return;
> +
> +	e = &inspect_entries[uid];
> +
> +	if (e->id)
> +		meminspect_unregister_id(e->id);
> +
> +	e->pa = pa;
> +	e->va = phys_to_virt(pa);
> +	e->size = size;
> +	e->id = uid;
> +	e->type = type;
> +#ifdef CONFIG_CRASH_DUMP
> +	if (elf_hdr_ready)
> +		update_elfheader(e);
> +#endif
> +	atomic_notifier_call_chain(&meminspect_notifier_list,
> +				   MEMINSPECT_NOTIFIER_ADD, e);
> +}
> +EXPORT_SYMBOL_GPL(meminspect_register_id_pa);
> +
> +/**
> + * meminspect_table_lock() - Lock the mutex on the inspection table
> + *
> + * Return: None
> + */
> +void meminspect_table_lock(void)
> +{
> +	mutex_lock(&meminspect_lock);
> +}
> +EXPORT_SYMBOL_GPL(meminspect_table_lock);
> +
> +/**
> + * meminspect_table_unlock() - Unlock the mutex on the inspection table
> + *
> + * Return: None
> + */
> +void meminspect_table_unlock(void)
> +{
> +	mutex_unlock(&meminspect_lock);
> +}
> +EXPORT_SYMBOL_GPL(meminspect_table_unlock);
> +
> +/**
> + * meminspect_traverse() - Traverse the meminspect table and call the
> + *		callback function for each valid entry.
> + * @priv: private data to be passed to the callback
> + * @cb: meminspect iterator callback that should be called for each entry
> + *
> + * Return: None
> + */
> +void meminspect_traverse(void *priv, meminspect_iter_cb_t cb)
> +{
> +	const struct inspect_entry *e;
> +	int i;
> +
> +	WARN_ON(!mutex_is_locked(&meminspect_lock));
> +
> +	for (i = MEMINSPECT_ID_ELF; i < MEMINSPECT_ID_MAX; i++) {
> +		e = &inspect_entries[i];
> +		if (e->id)
> +			cb(priv, e);
> +	}
> +}
> +EXPORT_SYMBOL_GPL(meminspect_traverse);
> +
> +/**
> + * meminspect_notifier_register() - Register a notifier to meminspect table
> + * @n: notifier block to register. This will be called whenever an entry
> + *		is being added or removed.
> + *
> + * Return: errno
> + */
> +int meminspect_notifier_register(struct notifier_block *n)
> +{
> +	return atomic_notifier_chain_register(&meminspect_notifier_list, n);
> +}
> +EXPORT_SYMBOL_GPL(meminspect_notifier_register);
> +
> +/**
> + * meminspect_notifier_unregister() - Unregister a previously registered
> + *		notifier from meminspect table.
> + * @n: notifier block to unregister.
> + *
> + * Return: errno
> + */
> +int meminspect_notifier_unregister(struct notifier_block *n)
> +{
> +	return atomic_notifier_chain_unregister(&meminspect_notifier_list, n);
> +}
> +EXPORT_SYMBOL_GPL(meminspect_notifier_unregister);
> +
> +#ifdef CONFIG_CRASH_DUMP
> +static int __init meminspect_prepare_crashdump(void)
> +{
> +	const struct inspect_entry *e;
> +	int ret;
> +	enum meminspect_uid i;
> +
> +	ret = init_elfheader();
> +
> +	if (ret < 0)
> +		return ret;
> +
> +	/*
> +	 * Some regions may have been registered very early.
> +	 * Update the elf header for all existing regions,
> +	 * except for MEMINSPECT_ID_ELF and MEMINSPECT_ID_VMCOREINFO,
> +	 * those are included in the ELF header upon its creation.
> +	 */
> +	for (i = MEMINSPECT_ID_VMCOREINFO + 1; i < MEMINSPECT_ID_MAX; i++) {
> +		e = &inspect_entries[i];
> +		if (e->id)
> +			update_elfheader(e);
> +	}
> +
> +	elf_hdr_ready = true;
> +
> +	return 0;
> +}
> +#endif
> +
> +static int __init meminspect_prepare_table(void)
> +{
> +	const struct inspect_entry *e;
> +	enum meminspect_uid i;
> +	int ret;
> +
> +	meminspect_table_lock();
> +	/*
> +	 * First, copy all entries from the compiler built table
> +	 * In case some entries are registered multiple times,
> +	 * the last chronological entry will be stored.
> +	 * Previously registered entries will be dropped.
> +	 */
> +	for_each_meminspect_entry(e) {
> +		inspect_entries[e->id] = *e;
> +		if (!inspect_entries[e->id].pa && inspect_entries[e->id].va)
> +			inspect_entries[e->id].pa = virt_to_phys(inspect_entries[e->id].va);
> +	}
> +#ifdef CONFIG_CRASH_DUMP
> +	ret = meminspect_prepare_crashdump();
> +	if (ret)
> +		pr_warn("meminspect: failed to prepare crashdump ELF header: %d\n", ret);
> +#endif
> +	/* if we have early notifiers registered, call them now */
> +	for (i = MEMINSPECT_ID_ELF; i < MEMINSPECT_ID_MAX; i++)
> +		if (inspect_entries[i].id)
> +			atomic_notifier_call_chain(&meminspect_notifier_list,
> +						   MEMINSPECT_NOTIFIER_ADD,
> +						   &inspect_entries[i]);
> +	meminspect_table_unlock();
> +
> +	pr_debug("Memory inspection table initialized\n");
> +
> +	return 0;
> +}
> +late_initcall(meminspect_prepare_table);
>
> --
> 2.53.0
>

Thanks, Lorenzo

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 05/26] genirq/irqdesc: Annotate static information into meminspect
  2026-07-08  5:31 ` [PATCH v3 05/26] genirq/irqdesc: " Mukesh Ojha
@ 2026-07-08  7:46   ` Lorenzo Stoakes
  0 siblings, 0 replies; 46+ messages in thread
From: Lorenzo Stoakes @ 2026-07-08  7:46 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree

On Wed, Jul 08, 2026 at 11:01:44AM +0530, Mukesh Ojha wrote:
> From: Eugen Hristev <ehristev@kernel.org>
>
> Annotate vital static information into inspection table:
>  - total_nr_irqs
>
> Information on these annotated variables is stored in a dedicated
> meminspect section.
>
> Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
>  kernel/irq/irqdesc.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
> index 80ef4e27dcf4..4e58e7f5fc6c 100644
> --- a/kernel/irq/irqdesc.c
> +++ b/kernel/irq/irqdesc.c
> @@ -16,6 +16,7 @@
>  #include <linux/irqdomain.h>
>  #include <linux/sysfs.h>
>  #include <linux/string_choices.h>
> +#include <linux/meminspect.h>
>
>  #include "internals.h"
>
> @@ -142,6 +143,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
>  }
>
>  unsigned int total_nr_irqs __read_mostly = NR_IRQS;
> +MEMINSPECT_SIMPLE_ENTRY(total_nr_irqs);

Err... this is effectively exporting this unexported variable to drivers?

This is massively open to abuse no? A driver could now manipulate this value if
it wanted to?

Why would we want internal state like this exposed to drivers/firmware? This
isn't something you can even do right now without kernel debug symbols.

I am getting ever more convinced that this resembles a backdoor EXPORT_SYMBOLS()
but now much worse because you get a VA and a PA and more information...!

>
>  /**
>   * irq_get_nr_irqs() - Number of interrupts supported by the system.
>
> --
> 2.53.0
>

Thanks, Lorenzo

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 11/26] mm/swapfile: Annotate static information into meminspect
  2026-07-08  5:31 ` [PATCH v3 11/26] mm/swapfile: " Mukesh Ojha
@ 2026-07-08  7:47   ` Lorenzo Stoakes
  2026-07-08 19:05     ` Mukesh Ojha
  0 siblings, 1 reply; 46+ messages in thread
From: Lorenzo Stoakes @ 2026-07-08  7:47 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree

On Wed, Jul 08, 2026 at 11:01:50AM +0530, Mukesh Ojha wrote:
> From: Eugen Hristev <ehristev@kernel.org>
>
> Annotate vital static information into inspection table:
>  - nr_swapfiles
>
> Information on these variables is stored in a dedicated meminspect
> section.
>
> Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
>  mm/swapfile.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/mm/swapfile.c b/mm/swapfile.c
> index a602e5820513..d480727e4987 100644
> --- a/mm/swapfile.c
> +++ b/mm/swapfile.c
> @@ -42,6 +42,7 @@
>  #include <linux/suspend.h>
>  #include <linux/zswap.h>
>  #include <linux/plist.h>
> +#include <linux/meminspect.h>
>
>  #include <asm/tlbflush.h>
>  #include <linux/leafops.h>
> @@ -65,6 +66,7 @@ static void move_cluster(struct swap_info_struct *si,
>   */
>  static DEFINE_SPINLOCK(swap_lock);
>  static unsigned int nr_swapfiles;
> +MEMINSPECT_SIMPLE_ENTRY(nr_swapfiles);

Now the EXPORT_SYMBOL_GPL() is an EXPORT_SYMBOL() in effect no?

>  atomic_long_t nr_swap_pages;
>  /*
>   * Some modules use swappable objects and may try to swap them out under
>
> --
> 2.53.0
>

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 14/26] mm/init-mm: Annotate static information into meminspect
  2026-07-08  5:31 ` [PATCH v3 14/26] mm/init-mm: Annotate static " Mukesh Ojha
@ 2026-07-08  7:52   ` Lorenzo Stoakes
  0 siblings, 0 replies; 46+ messages in thread
From: Lorenzo Stoakes @ 2026-07-08  7:52 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree

NAK.

You're exporting internal mm stuff to drivers, in no world are you going to
do that, sorry.

On Wed, Jul 08, 2026 at 11:01:53AM +0530, Mukesh Ojha wrote:
> From: Eugen Hristev <ehristev@kernel.org>
>
> Annotate vital static information into inspection table:
>  - init_mm
>  - swapper_pg_dir
>  - _sinittext
>  - _einittext
>  - _end
>  - _text
>  - _stext
>  - _etext
>
> Information on these variables is stored into dedicated meminspect
> section.
>
> Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
>  mm/init-mm.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/mm/init-mm.c b/mm/init-mm.c
> index 3e792aad7626..cf53058410b1 100644
> --- a/mm/init-mm.c
> +++ b/mm/init-mm.c
> @@ -7,6 +7,8 @@
>  #include <linux/cpumask.h>
>  #include <linux/mman.h>
>  #include <linux/pgtable.h>
> +#include <linux/meminspect.h>

Hate the idea of a very specific inspection mechanism hooking into core mm
initialisation in general.

If you thing needs to do this, your thing is broken IMO.

> +#include <asm/sections.h>

Err sections? So now this file is now a dumping ground for meminspect ELF
section declarations?

>
>  #include <linux/atomic.h>
>  #include <linux/user_namespace.h>
> @@ -19,6 +21,13 @@
>
>  const struct vm_operations_struct vma_dummy_vm_ops;
>
> +MEMINSPECT_AREA_ENTRY(_sinittext, sizeof(void *));
> +MEMINSPECT_AREA_ENTRY(_einittext, sizeof(void *));
> +MEMINSPECT_AREA_ENTRY(_end, sizeof(void *));
> +MEMINSPECT_AREA_ENTRY(_text, sizeof(void *));
> +MEMINSPECT_AREA_ENTRY(_stext, sizeof(void *));
> +MEMINSPECT_AREA_ENTRY(_etext, sizeof(void *));

Is this just a weird way of getting ELF symbols?

> +
>  /*
>   * For dynamically allocated mm_structs, there is a dynamically sized cpumask
>   * at the end of the structure, the size of which depends on the maximum CPU
> @@ -50,6 +59,9 @@ struct mm_struct init_mm = {
>  	INIT_MM_CONTEXT(init_mm)
>  };
>
> +MEMINSPECT_SIMPLE_ENTRY(init_mm);
> +MEMINSPECT_AREA_ENTRY(swapper_pg_dir, sizeof(void *));

Absolutely, positively not, this is totally insane and COMPLETELY violates
separation between drivers and mm.

We already let drivers access FAR too much.

Exporting core mm internals would be like giving up on any semblence of
separation of concerns.

> +
>  void setup_initial_init_mm(void *start_code, void *end_code,
>  			   void *end_data, void *brk)
>  {
>
> --
> 2.53.0
>

Thanks, Lorenzo

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 19/26] mm/numa: Register node data information into meminspect
  2026-07-08  5:31 ` [PATCH v3 19/26] mm/numa: Register node data information " Mukesh Ojha
@ 2026-07-08  7:55   ` Lorenzo Stoakes
  0 siblings, 0 replies; 46+ messages in thread
From: Lorenzo Stoakes @ 2026-07-08  7:55 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree

On Wed, Jul 08, 2026 at 11:01:58AM +0530, Mukesh Ojha wrote:
> Register dynamic information into meminspect for debugging:
>  - dynamic node data for each node
>
> Use meminspect_register_pa() to collect node data into meminspect.

This commit message is a total mess, this feels like internal development stuff
not something you're trying to get upstreamed in core.

>
> Co-developed-by: Eugen Hristev <eugen.hristev@linaro.org>
> Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
>  mm/numa.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/mm/numa.c b/mm/numa.c
> index 7d5e06fe5bd4..f04740dfb2cb 100644
> --- a/mm/numa.c
> +++ b/mm/numa.c
> @@ -4,6 +4,7 @@
>  #include <linux/printk.h>
>  #include <linux/numa.h>
>  #include <linux/numa_memblks.h>
> +#include <linux/meminspect.h>
>
>  struct pglist_data *node_data[MAX_NUMNODES];
>  EXPORT_SYMBOL(node_data);
> @@ -20,6 +21,7 @@ void __init alloc_node_data(int nid)
>  	if (!nd_pa)
>  		panic("Cannot allocate %zu bytes for node %d data\n",
>  		      nd_size, nid);
> +	meminspect_lock_register_pa(nd_pa, nd_size);

Not keyed on node ID, just exposing the physical address assigned to a node to
all drivers.

Nope to this.

>
>  	/* report and initialize */
>  	pr_info("NODE_DATA(%d) allocated [mem %#010Lx-%#010Lx]\n", nid,
>
> --
> 2.53.0
>

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 21/26] printk: Register information into meminspect
  2026-07-08  5:32 ` [PATCH v3 21/26] printk: " Mukesh Ojha
@ 2026-07-08  7:59   ` Lorenzo Stoakes
  2026-07-08 18:53     ` Mukesh Ojha
  2026-07-09  8:16     ` Petr Mladek
  0 siblings, 2 replies; 46+ messages in thread
From: Lorenzo Stoakes @ 2026-07-08  7:59 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree

On Wed, Jul 08, 2026 at 11:02:00AM +0530, Mukesh Ojha wrote:
> Annotate vital static, dynamic information into meminspect for debugging
>
> Static:
>  - prb_descs
>  - prb_infos
>  - prb
>  - prb_data
>  - clear_seq
>  - printk_rb_static
>  - printk_rb_dynamic
>
> Dynamic:
>  - new_descs
>  - new_infos
>  - new_log_buf
>
> meminspect uses a different API to annotate variables for inspection,
> and information about these variables is stored in the inspection table.

This commit message is a mess again. You're writing what the code does, not why,
you mention separate API but not which or why.

It's useless basically, and it's weird to list arbitrary fields like this.

Always think 'what would be useful to reviewers and people coming back to this
patch in debug/development'.

If it just says what the code says it's useless. Put what's NOT there.

>
> Reviewed-by: Petr Mladek <pmladek@suse.com>
> Co-developed-by: Eugen Hristev <eugen.hristev@linaro.org>
> Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
> Reviewed-by: John Ogness <john.ogness@linutronix.de>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
>  kernel/printk/printk.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index 2fe9a963c823..f7f32c09b9b8 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -49,6 +49,7 @@
>  #include <linux/sched/debug.h>
>  #include <linux/sched/task_stack.h>
>  #include <linux/panic.h>
> +#include <linux/meminspect.h>
>
>  #include <linux/uaccess.h>
>  #include <asm/sections.h>
> @@ -518,10 +519,17 @@ static u32 log_buf_len = __LOG_BUF_LEN;
>  #endif
>  _DEFINE_PRINTKRB(printk_rb_static, CONFIG_LOG_BUF_SHIFT - PRB_AVGBITS,
>  		 PRB_AVGBITS, &__log_buf[0]);
> +MEMINSPECT_NAMED_ENTRY(prb_descs, _printk_rb_static_descs);
> +MEMINSPECT_NAMED_ENTRY(prb_infos, _printk_rb_static_infos);
> +MEMINSPECT_NAMED_ENTRY(prb_data, __log_buf);
> +MEMINSPECT_SIMPLE_ENTRY(printk_rb_static);
>
>  static struct printk_ringbuffer printk_rb_dynamic;
> +MEMINSPECT_SIMPLE_ENTRY(printk_rb_dynamic);
>
>  struct printk_ringbuffer *prb = &printk_rb_static;
> +MEMINSPECT_SIMPLE_ENTRY(prb);
> +MEMINSPECT_SIMPLE_ENTRY(clear_seq);
>
>  /*
>   * We cannot access per-CPU data (e.g. per-CPU flush irq_work) before
> @@ -1238,6 +1246,10 @@ void __init setup_log_buf(int early)
>
>  	local_irq_restore(flags);
>
> +	meminspect_lock_register_va(new_log_buf, new_log_buf_len);
> +	meminspect_lock_register_va(new_descs, new_descs_size);
> +	meminspect_lock_register_va(new_infos, new_infos_size);
> +
>  	/*
>  	 * Copy any remaining messages that might have appeared from
>  	 * NMI context after copying but before switching to the
>
> --
> 2.53.0
>

Overall exposing live dynamic printk information to drivers seems unwise, but
not quite as insane as some of the other stuff thus exposed...

Thanks, Lorenzo

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 26/26] meminspect: Add debug kinfo compatible driver
  2026-07-08  7:08 ` [PATCH v3 26/26] meminspect: Add debug kinfo compatible driver Mukesh Ojha
@ 2026-07-08  8:06   ` Lorenzo Stoakes
  2026-07-08 18:46     ` Mukesh Ojha
  2026-07-09 13:24   ` Petr Pavlu
  1 sibling, 1 reply; 46+ messages in thread
From: Lorenzo Stoakes @ 2026-07-08  8:06 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: akpm, anna-maria, arnd, andersson, chrisl, cl, conor+dt, david,
	dennis, devicetree, ehristev, frederic, mingo, jstultz, corbet,
	juri.lelli, kasong, kees, konradybcio, krzk+dt, linux-arch,
	linux-arm-msm, linux-doc, linux-kernel, linux-mm,
	linux-remoteproc, mathieu.poirier, peterz, pmladek, robh,
	saravanak, tj, tglx, vincent.guittot, workflows, atomlin, ast,
	aliceryhl, linux.amoon, ardb, baoquan.he, baohua, bsegall,
	jackmanb, leitao, brauner, coxu, dietmar.eggemann, dianders,
	ebiggers, feng.tang, yangfeng, gary, guohanjun, jack,
	wangjinchao600, joel.granados, hannes, john.ogness, jpoimboe,
	shikemeng, kas, kprateek.nayak, liam, elver, mgorman, mhocko,
	ojeda, rppt, namcao, nathan, nphamcs, n.schier, pasha.tatashin,
	petr.pavlu, pnina.feder, rdunlap, rioo.tsukatsukii, senozhatsky,
	skhan, sboyd, rostedt, surenb, thomas.weissschuh, vschneid,
	vbabka, youngjun.park, zhengyejian, ziy, Eugen Hristev

On Wed, Jul 08, 2026 at 12:38:09PM +0530, Mukesh Ojha wrote:
> From: Eugen Hristev <eugen.hristev@linaro.org>
>
> With this driver, the registered regions are copied to a shared memory
> zone at register time. The shared memory zone is supplied via OF. This
> driver will select only regions that are of interest, and keep only
> addresses. The format of the list is Kinfo compatible, with devices like
> Google Pixel phone. The firmware is only interested in some symbols'
> addresses.
>
> Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>

Hang on, this is a driver that exposes internal kernel symbol information in a
shared memory region for anybody who wants to access it?

This doesn't really seem sane?

Looking through the code it seems you are only exposing things that are already
otherwise exposed, so maybe it's not so bad, but it seems as if a registered
meminfo driver could in any case get access to things they shouldn't?

> ---
>  MAINTAINERS                |   1 +
>  drivers/of/platform.c      |   1 +
>  kernel/meminspect/Kconfig  |  11 ++
>  kernel/meminspect/Makefile |   1 +
>  kernel/meminspect/kinfo.c  | 257 +++++++++++++++++++++++++++++++++++++
>  5 files changed, 271 insertions(+)
>  create mode 100644 kernel/meminspect/kinfo.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 2d816d783024..d805ff9fedac 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16906,6 +16906,7 @@ M:	Eugen Hristev <eugen.hristev@linaro.org>
>  M:	Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/reserved-memory/google,debug-kinfo.yaml
> +F:	kernel/meminspect/kinfo.c
>
>  MEMBLOCK AND MEMORY MANAGEMENT INITIALIZATION
>  M:	Mike Rapoport <rppt@kernel.org>
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> index 53bca8c6f781..f80bd25fc481 100644
> --- a/drivers/of/platform.c
> +++ b/drivers/of/platform.c
> @@ -494,6 +494,7 @@ static const struct of_device_id reserved_mem_matches[] = {
>  	{ .compatible = "qcom,smem" },
>  	{ .compatible = "ramoops" },
>  	{ .compatible = "nvmem-rmem" },
> +	{ .compatible = "google,debug-kinfo" },
>  	{ .compatible = "google,open-dice" },
>  	{}
>  };
> diff --git a/kernel/meminspect/Kconfig b/kernel/meminspect/Kconfig
> index 18ff511ad4cf..7f6436c3344b 100644
> --- a/kernel/meminspect/Kconfig
> +++ b/kernel/meminspect/Kconfig
> @@ -16,3 +16,14 @@ config MEMINSPECT
>
>  	  Note that modules using this feature must be rebuilt if this
>  	  option changes.
> +
> +config MEMINSPECT_KINFO
> +	tristate "Shared memory KInfo compatible driver"
> +	depends on MEMINSPECT
> +	help
> +	  Say y here to enable the Shared memory KInfo compatible driver.
> +	  With this driver, the registered regions are copied to a shared
> +	  memory zone at register time.
> +	  The shared memory zone is supplied via OF.
> +	  This driver will select only regions that are of interest,
> +	  and keep only addresses. The format of the list is Kinfo compatible.
> diff --git a/kernel/meminspect/Makefile b/kernel/meminspect/Makefile
> index 09fd55e6d9cf..283604d892e5 100644
> --- a/kernel/meminspect/Makefile
> +++ b/kernel/meminspect/Makefile
> @@ -1,3 +1,4 @@
>  # SPDX-License-Identifier: GPL-2.0
>
>  obj-$(CONFIG_MEMINSPECT) += meminspect.o
> +obj-$(CONFIG_MEMINSPECT_KINFO) += kinfo.o
> diff --git a/kernel/meminspect/kinfo.c b/kernel/meminspect/kinfo.c
> new file mode 100644
> index 000000000000..7451c13bc316
> --- /dev/null
> +++ b/kernel/meminspect/kinfo.c
> @@ -0,0 +1,257 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + *
> + * Copyright 2002 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
> + * Copyright 2021 Google LLC
> + * Copyright 2025 Linaro Ltd. Eugen Hristev <eugen.hristev@linaro.org>
> + */
> +#include <linux/container_of.h>
> +#include <linux/kallsyms.h>
> +#include <linux/meminspect.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_reserved_mem.h>
> +#include <linux/platform_device.h>
> +#include <linux/utsname.h>
> +
> +#define BUILD_INFO_LEN		256
> +#define DEBUG_KINFO_MAGIC	0xcceeddff
> +
> +/*
> + * Header structure must be byte-packed, since the table is provided to
> + * bootloader.
> + */
> +struct kernel_info {
> +	/* For kallsyms */
> +	u8 enabled_all;
> +	u8 enabled_base_relative;
> +	u8 enabled_absolute_percpu;
> +	u8 enabled_cfi_clang;
> +	u32 num_syms;
> +	u16 name_len;
> +	u16 bit_per_long;
> +	u16 module_name_len;
> +	u16 symbol_len;
> +	u64 _relative_pa;
> +	u64 _text_pa;
> +	u64 _stext_pa;
> +	u64 _etext_pa;
> +	u64 _sinittext_pa;
> +	u64 _einittext_pa;
> +	u64 _end_pa;
> +	u64 _offsets_pa;
> +	u64 _names_pa;
> +	u64 _token_table_pa;
> +	u64 _token_index_pa;
> +	u64 _markers_pa;
> +	u64 _seqs_of_names_pa;
> +
> +	/* For frame pointer */
> +	u32 thread_size;
> +
> +	/* For virt_to_phys */
> +	u64 swapper_pg_dir_pa;
> +
> +	/* For linux banner */
> +	u8 last_uts_release[__NEW_UTS_LEN];
> +
> +	/* For module kallsyms */
> +	u32 enabled_modules_tree_lookup;
> +	u32 mod_mem_offset;
> +	u32 mod_kallsyms_offset;
> +} __packed;
> +
> +struct kernel_all_info {
> +	u32 magic_number;
> +	u32 combined_checksum;
> +	struct kernel_info info;
> +} __packed;
> +
> +struct debug_kinfo {
> +	struct device *dev;
> +	void *all_info_addr;
> +	size_t all_info_size;
> +	struct notifier_block nb;
> +};
> +
> +static void update_kernel_all_info(struct kernel_all_info *all_info)
> +{
> +	struct kernel_info *info;
> +	u32 *checksum_info;
> +	int index;
> +
> +	all_info->magic_number = DEBUG_KINFO_MAGIC;
> +	all_info->combined_checksum = 0;
> +
> +	info = &all_info->info;
> +	checksum_info = (u32 *)info;
> +	for (index = 0; index < sizeof(*info) / sizeof(u32); index++)
> +		all_info->combined_checksum ^= checksum_info[index];
> +}
> +
> +static void __maybe_unused register_kinfo_region(void *priv,
> +						 const struct inspect_entry *e)
> +{
> +	struct debug_kinfo *kinfo = priv;
> +	struct kernel_all_info *all_info = kinfo->all_info_addr;
> +	struct kernel_info *info = &all_info->info;
> +	struct uts_namespace *uts;
> +	u64 paddr;
> +
> +	if (e->pa)
> +		paddr = e->pa;
> +	else
> +		paddr = __pa(e->va);
> +
> +	switch (e->id) {
> +	case MEMINSPECT_ID__sinittext:
> +		info->_sinittext_pa = paddr;
> +		break;
> +	case MEMINSPECT_ID__einittext:
> +		info->_einittext_pa = paddr;
> +		break;
> +	case MEMINSPECT_ID__end:
> +		info->_end_pa = paddr;
> +		break;
> +	case MEMINSPECT_ID__text:
> +		info->_text_pa = paddr;
> +		break;
> +	case MEMINSPECT_ID__stext:
> +		info->_stext_pa = paddr;
> +		break;
> +	case MEMINSPECT_ID__etext:
> +		info->_etext_pa = paddr;
> +		break;
> +	case MEMINSPECT_ID_kallsyms_num_syms:
> +		info->num_syms = *(__u32 *)e->va;
> +		break;
> +	case MEMINSPECT_ID_kallsyms_offsets:
> +		info->_offsets_pa = paddr;
> +		break;
> +	case MEMINSPECT_ID_kallsyms_names:
> +		info->_names_pa = paddr;
> +		break;
> +	case MEMINSPECT_ID_kallsyms_token_table:
> +		info->_token_table_pa = paddr;
> +		break;
> +	case MEMINSPECT_ID_kallsyms_token_index:
> +		info->_token_index_pa = paddr;
> +		break;
> +	case MEMINSPECT_ID_kallsyms_markers:
> +		info->_markers_pa = paddr;
> +		break;
> +	case MEMINSPECT_ID_kallsyms_seqs_of_names:
> +		info->_seqs_of_names_pa = paddr;
> +		break;
> +	case MEMINSPECT_ID_swapper_pg_dir:
> +		info->swapper_pg_dir_pa = paddr;
> +		break;
> +	case MEMINSPECT_ID_init_uts_ns:
> +		if (!e->va)
> +			return;
> +		uts = e->va;
> +		strscpy(info->last_uts_release, uts->name.release, __NEW_UTS_LEN);
> +		break;
> +	default:
> +		break;
> +	};
> +
> +	update_kernel_all_info(all_info);
> +}
> +
> +static int kinfo_notifier_cb(struct notifier_block *nb,
> +			     unsigned long code, void *entry)
> +{
> +	struct debug_kinfo *kinfo = container_of(nb, struct debug_kinfo, nb);
> +
> +	if (code == MEMINSPECT_NOTIFIER_ADD)
> +		register_kinfo_region(kinfo, entry);
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static int debug_kinfo_probe(struct platform_device *pdev)
> +{
> +	struct kernel_all_info *all_info;
> +	struct device *dev = &pdev->dev;
> +	struct reserved_mem *rmem;
> +	struct debug_kinfo *kinfo;
> +	struct kernel_info *info;
> +
> +	rmem = of_reserved_mem_lookup(dev->of_node);
> +	if (!rmem)
> +		return dev_err_probe(dev, -ENODEV, "no such reserved mem of node name %s\n",
> +			      dev->of_node->name);
> +
> +	/* Need to wait for reserved memory to be mapped */
> +	if (!rmem->priv)
> +		return -EPROBE_DEFER;
> +
> +	if (!rmem->base || !rmem->size)
> +		dev_err_probe(dev, -EINVAL, "unexpected reserved memory\n");
> +
> +	if (rmem->size < sizeof(struct kernel_all_info))
> +		dev_err_probe(dev, -EINVAL, "reserved memory size too small\n");
> +
> +	kinfo = devm_kzalloc(dev, sizeof(*kinfo), GFP_KERNEL);
> +	if (!kinfo)
> +		return -ENOMEM;
> +
> +	platform_set_drvdata(pdev, kinfo);
> +
> +	kinfo->dev = dev;
> +	kinfo->all_info_addr = rmem->priv;
> +	kinfo->all_info_size = rmem->size;
> +
> +	all_info = kinfo->all_info_addr;
> +
> +	memset(all_info, 0, sizeof(struct kernel_all_info));
> +	info = &all_info->info;
> +	info->enabled_all = IS_ENABLED(CONFIG_KALLSYMS_ALL);
> +	info->enabled_absolute_percpu = IS_ENABLED(CONFIG_KALLSYMS_ABSOLUTE_PERCPU);
> +	info->enabled_base_relative = IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE);
> +	info->enabled_cfi_clang = IS_ENABLED(CONFIG_CFI_CLANG);
> +	info->name_len = KSYM_NAME_LEN;
> +	info->bit_per_long = BITS_PER_LONG;
> +	info->module_name_len = MODULE_NAME_LEN;
> +	info->symbol_len = KSYM_SYMBOL_LEN;
> +	info->thread_size = THREAD_SIZE;
> +	info->enabled_modules_tree_lookup = IS_ENABLED(CONFIG_MODULES_TREE_LOOKUP);
> +	info->mod_mem_offset = offsetof(struct module, mem);
> +	info->mod_kallsyms_offset = offsetof(struct module, kallsyms);
> +
> +	kinfo->nb.notifier_call = kinfo_notifier_cb;
> +
> +	meminspect_notifier_register(&kinfo->nb);
> +	meminspect_lock_traverse(kinfo, register_kinfo_region);
> +
> +	return 0;
> +}
> +
> +static void debug_kinfo_remove(struct platform_device *pdev)
> +{
> +	struct debug_kinfo *kinfo = platform_get_drvdata(pdev);
> +
> +	meminspect_notifier_unregister(&kinfo->nb);
> +}
> +
> +static const struct of_device_id debug_kinfo_of_match[] = {
> +	{ .compatible	= "google,debug-kinfo" },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, debug_kinfo_of_match);
> +
> +static struct platform_driver debug_kinfo_driver = {
> +	.probe = debug_kinfo_probe,
> +	.remove = debug_kinfo_remove,
> +	.driver = {
> +		.name = "debug-kinfo",
> +		.of_match_table = debug_kinfo_of_match,
> +	},
> +};
> +module_platform_driver(debug_kinfo_driver);
> +
> +MODULE_AUTHOR("Eugen Hristev <eugen.hristev@linaro.org>");
> +MODULE_AUTHOR("Jone Chou <jonechou@google.com>");
> +MODULE_DESCRIPTION("meminspect Kinfo Driver");
> +MODULE_LICENSE("GPL");
> --
> 2.53.0
>

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 00/26] Introduce meminspect
  2026-07-08  7:11 ` [PATCH v3 00/26] Introduce meminspect Lorenzo Stoakes
@ 2026-07-08  8:18   ` Lorenzo Stoakes
  2026-07-09 20:42     ` Mukesh Ojha
  0 siblings, 1 reply; 46+ messages in thread
From: Lorenzo Stoakes @ 2026-07-08  8:18 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree,
	Jason Gunthorpe

Having had a look through, thoughts:

I'm very concerned that this (whether intended or not) is a work around for
drivers to get access to symbols that are not exported.

In many cases you are adding meminspect instrumentation for stuff that's already
exported (fine). In some cases it's stuff that's only GPL-exported (not fine),
and in some cases you are exporting totally unexpected symbols (very very very
not fine).

A driver that hooks on to meminspect then gets the PA and VA for these and can
access these symbols as far as I can tell.

On that basis I really question the whole approach. It feels like you want to
have essentially richer symbol information here, so the approach should perhaps
be built on the existing mechanism for symbols rather than arbitrarily +
invasively stuck into core kernel logic?

I am also concerned that you're not accounting for memory lifecycle or things
like memory hotplug - you seem to just store PAs/VAs with assumption that the
ranges remain eternally mapped at the same ranges for both.

This is a concern because you also track dynamic ranges, and drivers might
register stuff they allocate this way, and it all seems like an easy way to get
UAF's.

I may have missed something here and happy to be corrected, though.

In general the series is far from being in upstreamable shape - you send a giant
1st patch which lumps together a whole bunch of stuff, then you send dozens of
2-5 line patches, and finally include some qualcomm driver specific stuff for
good measure.

The commit messages are generally awful and give little to no information, the
cover letter is deeply uncompelling and doesn't make the case for the feature at
all.

You make zero comments about key concerns with regards to stability, robustness,
security. There's no testing logic anywhere, and you even include a plea for
testing in the cover letter.

This is very much RFC stuff and I continue to not understand why you've taken
the RFC label off here.

And it all very much smacks of trying to solve an internal problem you've
encountered downstream by changing the core of the kernel, rather than you
sending a generally useful feature.

You need to address all of this and re-RFC the series. It instinctively feels
like trying to solve the problem in the wrong place, but in any case it would be
better to start with a SMALLER version of this first then look to extend it only
if the community supports it.

Thanks, Lorenzo

On Wed, Jul 08, 2026 at 08:11:52AM +0100, Lorenzo Stoakes wrote:
> +cc Jason as maybe he has thoughts on this...
>
> Overall - for this to be sensibly mainlined, we need to see a. a COMPELLING case
> made for this feature, b. some buy-in from others, and c. have confidence this
> will be properly maintained.
>
> I don't feel you've demonstrated any of these.
>
> And looking through the history of this (you've made it really hard with your
> changelog):
>
>     v2 - https://lore.kernel.org/lkml/20260311-minidump-v2-v2-0-f91cedc6f99e@oss.qualcomm.com/
>     v1 - https://lore.kernel.org/lkml/20251119154427.1033475-1-eugen.hristev@linaro.org/
> RFC v3 - (I literally can't find it...?)
> RFC v2 - https://lore.kernel.org/all/20250724135512.518487-1-eugen.hristev@linaro.org/
> RFC v1 - https://lore.kernel.org/lkml/20250422113156.575971-1-eugen.hristev@linaro.org/
>
> I'm struggling to understand why on earth it came out of RFC?
>
> You really shouldn't drop the RFC tag unless you've got CLEAR signal that the
> community wants the feature and that there's buy-in.
>
> Instead you've got some specific technical feedback, some trivia, etc. which
> warrants RFC respins, but nothing to suggest buy-in.
>
> So please attach the RFC tag to any future respins. And I suggest you make the
> case for this a LOT clearer and seek to engage with others to confirm that there
> is anybody else who wants this.
>
> On Wed, Jul 08, 2026 at 11:01:39AM +0530, Mukesh Ojha wrote:
> > First of all, I want to thank Eugene for his excellent work on this
> > series. What began as the Qualcomm Minidump driver from me has now
> > evolved into meminspect. He also presented meminspect at Linux
> > Plumbers 2025.
> >
> > Video of the recording is available here for anyone interested:
> > https://www.youtube.com/watch?v=aDZv4-kOLSc
>
> It's iffy putting links like this in a commit message that'll end up as a commit
> (in mm we put the cover letter in). Links can die. Companies can change their
> minds about videos being available.
>
> Maybe better as something explicitly after the commit message.
>
> >
> > Introduction: Memory inspection mechanism
> >
> > meminspect is a mechanism which allows the kernel to mark specific
> > memory areas for memory dumping or specific inspection, statistics,
> > usage.  Once regions are marked, meminspect keeps an internal list with
> > the regions in a dedicated table.  Further, these regions can be
> > accessed using specific API by any interested driver.  Regions being
> > marked beforehand, when the system is up and running, there is no need
> > nor dependency on a panic handler, or a working kernel that can dump the
> > debug information.  meminspect can be primarily used for debugging. The
> > approach is feasible to work when pstore, kdump, or another mechanism do
> > not. Pstore relies on persistent storage, a dedicated RAM area or
> > flash, which has the disadvantage of having the memory reserved all the
> > time, or another specific non volatile memory. Some devices cannot keep
> > the RAM contents on reboot so ramoops does not work. Some devices do not
> > allow kexec to run another kernel to debug the crashed one.  For such
> > devices, that have another mechanism to help debugging, like firmware,
> > meminspect is a viable solution.
>
> Please use paragraphs, this is an unreadable wall of text and it just seems
> to be noise.
>
> Why would we want to mark specific areas a special way? What are the
> trade-offs, what does that actually do? How do you interact with it? Why
> can't other approaches be used?
>
> You should make it CLEAR what exactly the benefits are and why this is
> better than alternatives.
>
> >
> > meminspect can create a core image, similar with /proc/vmcore, with only
> > the registered regions included. This can be loaded into crash tool/gdb
> > and analyzed. This happens if CRASH_DUMP=y.  To have this working,
>
> What is CRASH_DUMP? Where is it defined? You mean CONFIG_CRASH_DUMP?
>
> > specific information from the kernel is registered, and this is done at
> > meminspect init time, no need for the meminspect users to do anything.
>
> Again this just doesn't really mean anything to me?
>
> >
> > This version of the meminspect patch series includes two drivers that
> > make use of it: one is the Qualcomm Minidump, and the other one is the
> > Debug Kinfo backend for Android devices, reworked from this source here:
> > https://android.googlesource.com/kernel/common/+/refs/heads/android-mainline/drivers/android/debug_kinfo.c
> > written originally by Jone Chou <jonechou@google.com>
>
> This feels rather like you've taken a specific use case you have, and
> worked backwards from it to changes to core, honestly.
>
> >
> > Tested on Qualcomm SA8775P (Lemans EVK) on next-20260707 with the
> > minidump backend: kernel crash dump regions correctly captured
> > via firmware.
>
> What is a minidump backend? There's no detail about the testing here
> either. Does anybody outside of Qualcomm care about this?
>
> >
> > This series introduces a new cross-subsystem framework and, to
> > avoid merge ordering issues, I suggest the entire series be taken
> > via the mm tree. Subsystem maintainers for touched files have
> > been CC'd; I request an Acked-by from them if the respective
> > patches look fine from their side.
>
> Don't put stuff about mechanics of merge in the middle of a cover letter
> that will go into the git log, put this and the stuff about the video in a
> block of text below the main text, you can tag it 'REVIEWERS NOTES' or
> similar.
>
> Not only A-b for touched files, but as this is ostensibly an mm feature
> you'll need tags from mm maintainers and acceptance of the feature overall
> for it to be accepted.
>
> >
> > Alternatively, the qcom backend patches (22-24) can be deferred
> > to Bjorn's qcom tree in a follow-on series once the core
> > meminspect framework lands.
>
> I think that would be better yes, you shouldn't be adding new driver
> changes in a core series like this, only touching stuff you have to touch
> as a result of the core change.
>
> Anything else should be saved for later series. You can express ordering
> requirements in the cover letter...
>
> >
> > *** How to use meminspect with minidump backend on Qualcomm platform guide ***
>
> Odd to put a specific qualcomm TODO in a cover letter for a mainline
> feature...
>
> Again this makes it feels like this is something you want for your driver,
> and the core changes are just a means of getting there, which is not an
> acceptable justification for core changes.
>
> You have to rework this entire cover letter to sell it as a GENERAL
> feature.
>
> I'm really not convinced we want to give drivers (which are great at doing
> exactly the wrong thing with mm APIs) the ability to do invasive things in
> mm.
>
> >
> > Prerequisites:
> > Crash tool compiled with target=ARM64.
> >
> > Target kernel must be built with: CONFIG_DEBUG_INFO_REDUCED=n;
> > this will have vmlinux include all the debugging information
> > needed for the crash tool and CONFIG_MEMINSPECT,
> > CONFIG_CRASH_DUMP, and the driver CONFIG_QCOM_MINIDUMP.
> > Kernel arguments: Kernel firmware must be set to mode 'mini' by kernel
> > module parameter like this : qcom_scm.download_mode=mini
> >
> > After the kernel boots and the minidump module is loaded,
> > everything is ready for a possible crash. Upon triggering a
> > forced kernel crash, the target board will wait in download mode,
> > where QDL (https://github.com/linux-msm/qdl) running on the host
> > connected to the target (here, Lemans EVK) can be used to collect
> > minidump.elf from the target device onto the host.
> >
> > Currently, --minimal mode is being used to get dmesg log from
> > crashed device.
> >
> > Without --minimal mode, the crash tool needs to be patched to
> > not crash on missing symbols and needs to be tuned, which I am
> > currently working on in parallel.
> >
> > crash> log
> > [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x514f0014]
> > [    0.000000] Linux version 7.0.0-rc3-next-20260309-00028-g528b3c656121 (@21e3bca4168f) (aarch64-linux-gnu-gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #5 SMP PREEMPT Tue Mar 10 18:18:41 UTC 2026
> >
> > *** Debug Kinfo backend driver ***
> > I need help with the testing of this driver, Anyone who actually wants
>
> Err you're putting forward a non-RFC series to mainline and also saying
> essentially it's untested at least in one respect?
>
> This is signal that this should _remain_ RFC.
>
> > to test this, feel free to reply to the patch. we have also written a
> > simple DT binding for the driver.
> >
> > Thanks in advance for the review, and apologies if I missed addressing any comment.
> >
> > -Mukesh
> >
> > Changes in v3: https://lore.kernel.org/lkml/20260311-minidump-v2-v2-0-f91cedc6f99e@oss.qualcomm.com/
>
> And again, ->v2 but you label it v3...!
>
> > - Addressed most of doc. comments and binding and 0-day kernel
> >   test robot warning.
> > - Add timekeeping: Register tk_data into meminspect
> > - fixed some of the bugs identified during testing.
> > - Fix missing return before dev_err_probe() in qcom_md_probe(); all
> >   three error paths (SMEM lookup, table validation, table init) now
> >   correctly abort probe on failure
> > - Fix meminspect_traverse() kernel-doc: @priv description corrected
> > - Fix meminspect.rst: replace stale MEMINSPECT_ITERATOR_CB type name
> >   with the actual meminspect_iter_cb_t typedef
> > - Add kernel-doc for meminspect_iter_cb_t typedef
> > - Lot of code formating and style change as per coding standard.
> >
> > Changes in v2: https://lore.kernel.org/lkml/20251119154427.1033475-1-eugen.hristev@linaro.org/
>
> The link is to v1... what a mess!
>
> >  - Fixed doc warnings
> >  - Fixed kernel-test robot warnings.
> >  - Took Mike suggestion to remove mark inspect flag for dynamic memory.
> >  - Added R-b for printk patch.
> >  - Modified some commit messages for clarity.
> >  - corrected binding change for debug-kinfo as per Rob suggestion.
> >
> > Changelog for meminspect v1:
>
> You don't include a link to RFC v3 at all?
>
> > - rename to meminspect
> > - start on top of v2 actually, with the section and all.
> > - remove the backend thing, change the API to access the table
> > - move everything to kernel/
> > - add dependency to CRASH_DUMP instead of a separate knob
> > - move the minidump driver to soc/qcom
> > - integrate the meminspect better into memblock by using a new memblock flag
> > - minor fixes : use dev_err_probe everywhere, rearrange variable declarations,
> > remove some useless code, etc.
> >
> > Changelog for RFC v3:
> > - V2 available here : https://lore.kernel.org/all/20250724135512.518487-1-eugen.hristev@linaro.org/
>
> Same comment as below. Put links for changelogs with the version you're changing
> it's a total nightmare trying to follow this.
>
> And I literally cannot find RFC v3 on list, did you mislabel it?
>
> > - Removed the .section as requested by David Hildenbrand.
> > - Moved all kmemdump registration(when possible) to vmcoreinfo.
> > - Because of this, some of the variables that I was registering had to be non-static
> > so I had to modify this as per David Hildenbrand suggestion.
> > - Fixed minor things in the Kinfo driver: one field was broken, fixed some
> > compiler warnings, fixed the copyright and remove some useless includes.
> > - Moved the whole kmemdump from drivers/debug into mm/ and Kconfigs into mm/Kconfig.debug
> > and it's now available in kernel hacking, as per Randy Dunlap review
> > - Reworked some of the Documentation as per review from Jon Corbet
> >
> > Changelog for RFC v2:
> > - V1 available here: https://lore.kernel.org/lkml/20250422113156.575971-1-eugen.hristev@linaro.org/
>
> Why are you linking the previous version here, it's strange.
>
> Just put RFC v1: with the link below, same goes for other cases.
>
> > - Reworked the whole minidump implementation based on suggestions from Thomas Gleixner.
> > This means new API, macros, new way to store the regions inside kmemdump
> > (ditched the IDR, moved to static allocation, have a static default backend, etc)
> > - Reworked qcom_minidump driver based on review from Bjorn Andersson
> > - Reworked printk log buffer registration based on review from Petr Mladek.
> >
> > ---
> > Eugen Hristev (21):
> >       kernel: Introduce meminspect
> >       init/version: Annotate static information into meminspect
> >       mm/percpu: Annotate static information into meminspect
> >       cpu: Annotate static information into meminspect
> >       genirq/irqdesc: Annotate static information into meminspect
> >       timers: Annotate static information into meminspect
> >       kernel/fork: Annotate static information into meminspect
> >       mm/page_alloc: Annotate static information into meminspect
> >       mm/show_mem: Annotate static information into meminspect
> >       mm/swapfile: Annotate static information into meminspect
> >       kernel/vmcore_info: Register dynamic information into meminspect
> >       kernel/configs: Register dynamic information into meminspect
> >       mm/init-mm: Annotate static information into meminspect
> >       panic: Annotate static information into meminspect
> >       kallsyms: Annotate static information into meminspect
> >       mm/mm_init: Annotate static information into meminspect
> >       sched/core: Annotate runqueues into meminspect
> >       remoteproc: qcom: Move minidump data structures into its own header
> >       soc: qcom: Add minidump backend driver
> >       soc: qcom: smem: Add minidump platform device
> >       meminspect: Add debug kinfo compatible driver
> >
> > Mukesh Ojha (5):
> >       timekeeping: Register tk_data into meminspect
> >       mm/numa: Register node data information into meminspect
> >       mm/sparse: Register information into meminspect
> >       printk: Register information into meminspect
> >       dt-bindings: reserved-memory: Add Google Kinfo Pixel reserved memory
> >
> >  Documentation/dev-tools/index.rst                  |   1 +
> >  Documentation/dev-tools/meminspect.rst             | 144 +++++++
> >  .../reserved-memory/google,debug-kinfo.yaml        |  48 +++
> >  MAINTAINERS                                        |  16 +
> >  drivers/of/platform.c                              |   1 +
> >  drivers/remoteproc/qcom_common.c                   |  55 +--
> >  drivers/soc/qcom/Kconfig                           |  13 +
> >  drivers/soc/qcom/Makefile                          |   1 +
> >  drivers/soc/qcom/minidump.c                        | 271 ++++++++++++
> >  drivers/soc/qcom/smem.c                            |  10 +
>
> Yeah I hate that you're adding a wholy unrelated driver feature as part of this.
>
> Let's not.
>
> >  include/asm-generic/vmlinux.lds.h                  |  13 +
> >  include/linux/meminspect.h                         | 271 ++++++++++++
> >  include/linux/soc/qcom/minidump.h                  |  70 +++
> >  init/Kconfig                                       |   1 +
> >  init/version-timestamp.c                           |   3 +
> >  init/version.c                                     |   3 +
> >  kernel/Makefile                                    |   1 +
> >  kernel/configs.c                                   |   6 +
> >  kernel/cpu.c                                       |   5 +
> >  kernel/fork.c                                      |   3 +
> >  kernel/irq/irqdesc.c                               |   2 +
> >  kernel/kallsyms.c                                  |   9 +
> >  kernel/meminspect/Kconfig                          |  29 ++
> >  kernel/meminspect/Makefile                         |   4 +
> >  kernel/meminspect/kinfo.c                          | 257 +++++++++++
> >  kernel/meminspect/meminspect.c                     | 474 +++++++++++++++++++++
> >  kernel/panic.c                                     |   4 +
> >  kernel/printk/printk.c                             |  12 +
> >  kernel/sched/core.c                                |   2 +
> >  kernel/time/timekeeping.c                          |   2 +
> >  kernel/time/timer.c                                |   2 +
> >  kernel/vmcore_info.c                               |   4 +
> >  mm/init-mm.c                                       |  12 +
> >  mm/mm_init.c                                       |   2 +
> >  mm/numa.c                                          |   2 +
> >  mm/page_alloc.c                                    |   2 +
> >  mm/percpu.c                                        |   5 +
> >  mm/show_mem.c                                      |   2 +
> >  mm/sparse.c                                        |   3 +
> >  mm/swapfile.c                                      |   2 +
> >  40 files changed, 1713 insertions(+), 54 deletions(-)
> > ---
> > base-commit: 5c73cd9f0819c1c44e373e3dabb68318b1de1a12
> > change-id: 20260708-meminspect-v3-76dd8166c4f1
> >
> > Best regards,
> > --
> > -Mukesh Ojha
> >
>
> Thanks, Lorenzo

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 01/26] kernel: Introduce meminspect
  2026-07-08  7:38   ` Lorenzo Stoakes
@ 2026-07-08 13:33     ` Mukesh Ojha
  0 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08 13:33 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree

On Wed, Jul 08, 2026 at 08:38:13AM +0100, Lorenzo Stoakes wrote:
> This is an unmergeable mess of a patch but I have broader concerns:
> 
> * I'm very concerned that this is just one giant workaround to
>   EXPORT_SYMBOLS() for unexported memory, or really just a way for drivers
>   to stuff arbitrary VAs/PAs in some global region.
> 
> * I'm also very concerned about memory lifecycle - saying a physical range
>   X-Y is Z doesn't mean it's forever that? And for virtual addresses it's
>   even more problematic - are you going to put vmalloc pointers there that
>   can get unmapped? Or direct map ranges that might end up unmapped for
>   various reasons? What about memory hotplug?...

Static entries (patches 02–21) are all kernel .data/.bss symbols
 init_mm, cpu masks, kallsyms arrays, printk ring buffer descriptors,
etc. These are never freed, never remapped, and live for the full kernel
lifetime. There is no lifecycle issue for these.

The unregister API exists precisely for lifecycle management.  No
vmalloc memory is registered in this series. The only dynamic
registrations today are the ELF header (CMA allocation,
intentionally never freed) and vmcoreinfo (a static kernel
buffer).

Memory hotplug is a legitimate gap for the NUMA node_data registration.
Currently, all the tagged region are required by crash-utility
to launch and get dmesg from the collected elf.

> 
> * I hate the idea of exposing information about physical (and virtual!)
>   memory ranges to drivers arbitrarily, drivers are notorious for doing the
>   wrong thing (TM) and this is just asking for people to do 'interesting'
>   things with this stuff.

flow:

  kernel subsystems (owners of the data)
       │  annotate their own symbols
       ▼
  meminspect table  (PA + size, kernel-internal)
       │  pushed to registered backends only
       ▼
  platform backend driver  (e.g. qcom-minidump)
       │  writes PA+size pairs to SMEM
       ▼
  firmware   ── actual consumer
       │  reads kernel memory directly via hardware privilege
       ▼
  crash dump

The driver should not dereference the addresses. It should not "do the wrong
thing" with them beyond writing them into a firmware-readable table —
which is its entire purpose.

The closest upstream analogy is /proc/vmcoreinfo, which already exposes
kernel symbol addresses, struct offsets, and memory layout to crash
analysis tools. meminspect is a more selective, machine-readable variant
of the same concept, scoped to platforms where kdump and pstore are not
viable (no kexec support, RAM contents lost on reboot, no persistent
storage).

I can further fine tune only restrict to specific backend or remove traverse
or notifier API that arbitrary code can call. The registration can be gated by
backend platform driver, not by an open subscription API.

If the concern is that future drivers will misuse the framework beyond
its intended purpose i.e., a valid long-term worry, and I am  open
to adding documentation constraints or restricting the API further
(e.g., limiting to a single backend registration).

> 
> On Wed, Jul 08, 2026 at 11:01:40AM +0530, Mukesh Ojha wrote:
> > From: Eugen Hristev <ehristev@kernel.org>
> >
> > Memory inspection mechanism allows registration of a specific
> > memory area (or object) for later inspection purposes. Ranges are
> > added into an inspection table, which can be requested and
> > analyzed by specific drivers. Drivers would interface with any
> > hardware mechanism that will allow inspection of the data,
> > including but not limited to: dumping for debugging, creating a
> > core dump, analysis, or statistical information. Drivers can
> > register a notifier to know when new objects are registered, or
> > to traverse an existing inspection table. The inspection table is
> > created ahead of time such that it can be later used regardless
> > of the state of the kernel (running, frozen, crashed, or any
> > particular state).
> 
> This is the complete opposite of what a commit message should be...
> 
> Firstly it's an totally unacceptable, unreadable wall of text.
> 
> Secondly you're not at all describing what you're doing in this commit
> here.
> 
> As far as I can tell from the code here, you're explicitly only supporting
> ELF registered ranges (perhaps static also?)
> 
> I mean this is clearly not the whole thing, despite what the commit msg
> suggests, as you have 25 further commits (!)
> 
> The commit message should explain WHAT THE PATCH IS DOING, the trade-offs,
> the motivation, anything that needs to be called out.
> 
> It does absolutely none of that and instead you get what seems like
> marketing copy in a giant unbroken, unreadable, paragraph.

Surely, I could have explained more about the problem and how it
tries to solve it, and its limitations if any, instead of just
the introduction part.

> 
> >
> > Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> 
> This patch is seriously far from being even vaguely upstreamable, and for
> an effective v5 this is concerning.
> 
> > ---
> >  Documentation/dev-tools/index.rst      |   1 +
> >  Documentation/dev-tools/meminspect.rst | 144 ++++++++++
> >  MAINTAINERS                            |   9 +
> >  include/asm-generic/vmlinux.lds.h      |  13 +
> >  include/linux/meminspect.h             | 270 +++++++++++++++++++
> >  init/Kconfig                           |   1 +
> >  kernel/Makefile                        |   1 +
> >  kernel/meminspect/Kconfig              |  18 ++
> >  kernel/meminspect/Makefile             |   3 +
> >  kernel/meminspect/meminspect.c         | 474 +++++++++++++++++++++++++++++++++
> >  10 files changed, 934 insertions(+)
> 
> This changelog is completely ridiculous for a single patch.
> 
> This is kernel 101 stuff... you don't send everything in a single commit
> including documentation + MAINTAINERS changes...!
> 
> You have to split things up into logical parts.
>

I surely did a very poor job not changing too much from version
v1. It is indeed waiting for such comments to be addressed for it
to be on the right path, thank you, will split  it logically.

> >
> > diff --git a/Documentation/dev-tools/index.rst b/Documentation/dev-tools/index.rst
> > index 59cbb77b33ff..ea2989ca1566 100644
> > --- a/Documentation/dev-tools/index.rst
> > +++ b/Documentation/dev-tools/index.rst
> > @@ -40,3 +40,4 @@ Documentation/process/debugging/index.rst
> >     autofdo
> >     propeller
> >     container
> > +   meminspect
> > diff --git a/Documentation/dev-tools/meminspect.rst b/Documentation/dev-tools/meminspect.rst
> > new file mode 100644
> > index 000000000000..4ca10e33e4fd
> > --- /dev/null
> > +++ b/Documentation/dev-tools/meminspect.rst
> > @@ -0,0 +1,144 @@
> > +.. SPDX-License-Identifier: GPL-2.0
> > +
> > +==========
> > +meminspect
> > +==========
> > +
> > +This document provides information about the meminspect feature.
> > +
> > +Overview
> > +========
> > +
> > +meminspect is a mechanism that allows the kernel to register a chunk of
> > +memory into a table, to be used at a later time for a specific
> > +inspection purpose like debugging, memory dumping or statistics.
> 
> What's a chunk of memory? Physical memory? MMIO ranges? Virtual ranges? Direct
> map? Vmalloc?
> 
> Be more specific.

That's a valid concern to be addressed; it should be a directly
mapped region and should be documented and WARN on if it is not
directly mapped memory.

> 
> > +
> > +meminspect allows drivers to traverse the inspection table on demand,
> > +or to register a notifier to be called whenever a new entry is being added
> > +or removed.
> 
> I absolutely hate the idea of exposing a table of pointers to 'memory' that has
> lifetime information to drivers with arbitrary context.
> 
> What about security?

I see a point with the current implementation: meminspect core is
more open in such a sense that anybody can register a notifier
and traverse the table, so it really need not be a device.
However, current users like qcom minidump and google debug-kinfo
are platform drivers. I can fix that by removing notifiers and
having the backend supply ops callbacks, like how the pstore
backend does it.


> 
> > +
> > +The reasoning for meminspect is also to minimize the required information
> > +in case of a kernel problem. For example a traditional debug method involves
> > +dumping the whole kernel memory and then inspecting it. Meminspect allows the
> > +users to select which memory is of interest, in order to help this specific
> > +use case in production, where memory and connectivity are limited.
> 
> Again this is so vague it's uselses...

The intention of meminspect is to get minimal information from
the kernel that gets registered with any backend firmware so that
the firmware can dump it from a field device such as a mobile
phone or any device..

> 
> > +
> > +Although the kernel has multiple internal mechanisms, meminspect fits
> > +a particular model which is not covered by the others.
> 
> This is nebulous nonsense you have to explain WHY and what exactly it gives that
> others don't.
> 
> You can very well inspect specific areas of memory using

Ack, it should rightly explain why the other models do not fit.

> 
> > +
> > +meminspect Internals
> > +====================
> > +
> > +API
> > +---
> > +
> > +Static memory can be registered at compile time, by instructing the compiler
> > +to create a separate section with annotation info.
> > +For each such annotated memory (variables usually), a dedicated struct
> > +is created with the required information.
> > +To achieve this goal, some basic APIs are available:
> > +
> > +* MEMINSPECT_ENTRY(idx, sym, sz)
> > +  is the basic macro that takes an ID, the symbol, and a size.
> > +
> > +To make it easier, some wrappers are also defined
> > +
> > +* MEMINSPECT_SIMPLE_ENTRY(sym)
> > +  uses the dedicated MEMINSPECT_ID_##sym with a size equal to sizeof(sym)
> > +
> > +* MEMINSPECT_NAMED_ENTRY(name, sym)
> > +  is a simple entry that has an id that cannot be derived from the sym,
> > +  so a name has to be provided
> > +
> > +* MEMINSPECT_AREA_ENTRY(sym, sz)
> > +  registers sym, but with the size given as sz, useful for e.g.
> > +  arrays which do not have a fixed size at compile time.
> > +
> > +For dynamically allocated memory, or for other cases, the following APIs
> > +are defined::
> > +
> > +  meminspect_register_id_pa(enum meminspect_uid id, phys_addr_t zone,
> > +                            size_t size, unsigned int type);
> > +
> > +which takes the ID and the physical address.
> 
> What about lifetime?...
> 
> Exposing arbitrary physical memory to drivers is just a big nope.


> 
> > +
> > +Similarly there are variations:
> > +
> > + * meminspect_register_pa() omits the ID
> > + * meminspect_register_id_va() requires the ID but takes a virtual address
> > + * meminspect_register_va() omits the ID and requires a virtual address
> > +
> > +If the ID is not given, the next available dynamic ID is allocated.
> > +
> > +To unregister a dynamic entry, some APIs are defined:
> > + * meminspect_unregister_pa(phys_addr_t zone, size_t size);
> > + * meminspect_unregister_id(enum meminspect_uid id);
> > + * meminspect_unregister_va(va, size);
> > +
> > +All of the above have a lock variant that ensures the lock on the table
> > +is taken.
> > +
> > +
> > +meminspect drivers
> > +------------------
> > +
> > +Drivers are free to traverse the table by using a dedicated function::
> > +
> > + meminspect_traverse(void *priv, meminspect_iter_cb_t cb)
> > +
> > +The callback is called for each entry in the table.
> > +
> > +Drivers can also register a notifier with meminspect_notifier_register()
> > +and unregister with meminspect_notifier_unregister() to be called when a new
> > +entry is added or removed.
> > +
> > +Data structures
> > +---------------
> > +
> > +The regions are stored in a simple fixed size array. It avoids
> > +memory allocation overhead. This is not performance critical nor does
> > +allocating a few hundred entries create a memory consumption problem.
> > +
> > +The static variables registered into meminspect are annotated into
> > +a dedicated .inspect_table memory section. This is then walked by meminspect
> > +at a later time and each variable is then copied to the whole inspect table.
> > +
> > +meminspect Initialization
> > +-------------------------
> > +
> > +At any time, meminspect is ready to accept region registration
> > +from any part of the kernel. The table does not require any initialization.
> 
> 
> 
> > +In case CONFIG_CRASH_DUMP is enabled, meminspect creates an ELF header
> > +corresponding to a core dump image, in which each region is added as a
> > +program header. In this scenario, the first region is this ELF header, and
> > +the second region is the vmcoreinfo ELF note.
> > +By using this mechanism, all the meminspect table, if dumped, can be
> > +concatenated to obtain a core image that is loadable with the `crash` tool.
> > +
> > +meminspect example
> > +==================
> > +
> > +A simple scenario for meminspect is the following:
> > +The kernel registers the linux_banner variable into meminspect with
> > +a simple annotation like::
> > +
> > +  MEMINSPECT_SIMPLE_ENTRY(linux_banner);
> > +
> > +The meminspect late initcall will parse the compile-time table
> > +and copy the entry information into the inspection table.
> > +At a later point, any interested driver can call the traverse function to
> > +find out all entries in the table.
> > +A specific driver will then note into a specific table the address of the
> > +banner and the size of it.
> > +The specific table is then written to a shared memory area that can be
> > +read by upper level firmware.
> 
> This feels like you're finding a way to export things that aren't exported...?!

Umm... The intention was to share this information for debugging
purposes.

> 
> > +When the kernel freezes (hypothetically), the kernel will no longer feed
> > +the watchdog. The watchdog will trigger a higher exception level interrupt
> > +which will be handled by the upper level firmware. This firmware will then
> > +read the shared memory table and find an entry with the start and size of
> > +the banner. It will then copy it for debugging purpose. The upper level
> 
> This feels like a giant workaround to provide EXPORT_SYMBOLS()

Well, it was not an intention to share this with everybody but
with the backend device representing a platform device.

> 
> > +firmware will then be able to provide useful debugging information,
> > +like in this example, the banner.
> > +
> > +As seen here, meminspect facilitates the interaction between the kernel
> > +and a specific firmware.
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index c3f72058a2f2..fdad8ef377c8 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -16892,6 +16892,15 @@ F:	arch/*/include/asm/sync_core.h
> >  F:	include/uapi/linux/membarrier.h
> >  F:	kernel/sched/membarrier.c
> >
> > +MEMINSPECT
> > +M:	Eugen Hristev <eugen.hristev@linaro.org>
> > +M:	Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > +L:	linux-kernel@vger.kernel.org
> > +S:	Maintained
> > +F:	Documentation/dev-tools/meminspect.rst
> > +F:	include/linux/meminspect.h
> > +F:	kernel/meminspect/*
> > +
> >  MEMBLOCK AND MEMORY MANAGEMENT INITIALIZATION
> >  M:	Mike Rapoport <rppt@kernel.org>
> >  L:	linux-mm@kvack.org
> > diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> > index 5659f4b5a125..3122ddf5517a 100644
> > --- a/include/asm-generic/vmlinux.lds.h
> > +++ b/include/asm-generic/vmlinux.lds.h
> > @@ -506,6 +506,8 @@
> >  	FW_LOADER_BUILT_IN_DATA						\
> >  	TRACEDATA							\
> >  									\
> > +	MEMINSPECT_TABLE						\
> > +									\
> >  	PRINTK_INDEX							\
> >  									\
> >  	/* Kernel symbol table */					\
> > @@ -904,6 +906,17 @@
> >  #define TRACEDATA
> >  #endif
> >
> > +#ifdef CONFIG_MEMINSPECT
> > +#define MEMINSPECT_TABLE						\
> > +	. = ALIGN(8);							\
> > +	.inspect_table : AT(ADDR(.inspect_table) - LOAD_OFFSET) {	\
> > +		BOUNDED_SECTION_POST_LABEL(.inspect_table,		\
> > +					   __inspect_table, , _end)	\
> > +	}
> > +#else
> > +#define MEMINSPECT_TABLE
> > +#endif
> > +
> >  #ifdef CONFIG_PRINTK_INDEX
> >  #define PRINTK_INDEX							\
> >  	.printk_index : AT(ADDR(.printk_index) - LOAD_OFFSET) {		\
> > diff --git a/include/linux/meminspect.h b/include/linux/meminspect.h
> > new file mode 100644
> > index 000000000000..a9eb93c6ea2f
> > --- /dev/null
> > +++ b/include/linux/meminspect.h
> > @@ -0,0 +1,270 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +#ifndef _MEMINSPECT_H
> > +#define _MEMINSPECT_H
> > +
> > +#include <asm/page.h>
> > +#include <linux/notifier.h>
> > +
> > +enum meminspect_uid {
> > +	MEMINSPECT_ID_NONE = 0,
> > +	MEMINSPECT_ID_ELF,
> > +	MEMINSPECT_ID_VMCOREINFO,
> > +	MEMINSPECT_ID_CONFIG,
> > +	MEMINSPECT_ID__totalram_pages,
> > +	MEMINSPECT_ID___cpu_possible_mask,
> > +	MEMINSPECT_ID___cpu_present_mask,
> > +	MEMINSPECT_ID___cpu_online_mask,
> > +	MEMINSPECT_ID___cpu_active_mask,
> > +	MEMINSPECT_ID_mem_section,
> > +	MEMINSPECT_ID_jiffies_64,
> > +	MEMINSPECT_ID_linux_banner,
> > +	MEMINSPECT_ID_nr_threads,
> > +	MEMINSPECT_ID_total_nr_irqs,
> > +	MEMINSPECT_ID_tainted_mask,
> > +	MEMINSPECT_ID_taint_flags,
> > +	MEMINSPECT_ID_node_states,
> > +	MEMINSPECT_ID___per_cpu_offset,
> > +	MEMINSPECT_ID_nr_swapfiles,
> > +	MEMINSPECT_ID_init_uts_ns,
> > +	MEMINSPECT_ID_printk_rb_static,
> > +	MEMINSPECT_ID_printk_rb_dynamic,
> > +	MEMINSPECT_ID_prb,
> > +	MEMINSPECT_ID_prb_descs,
> > +	MEMINSPECT_ID_prb_infos,
> > +	MEMINSPECT_ID_prb_data,
> > +	MEMINSPECT_ID_clear_seq,
> > +	MEMINSPECT_ID_high_memory,
> > +	MEMINSPECT_ID_init_mm,
> > +	MEMINSPECT_ID__sinittext,
> > +	MEMINSPECT_ID__einittext,
> > +	MEMINSPECT_ID__end,
> > +	MEMINSPECT_ID__text,
> > +	MEMINSPECT_ID__stext,
> > +	MEMINSPECT_ID__etext,
> > +	MEMINSPECT_ID_kallsyms_num_syms,
> > +	MEMINSPECT_ID_kallsyms_offsets,
> > +	MEMINSPECT_ID_kallsyms_names,
> > +	MEMINSPECT_ID_kallsyms_token_table,
> > +	MEMINSPECT_ID_kallsyms_token_index,
> > +	MEMINSPECT_ID_kallsyms_markers,
> > +	MEMINSPECT_ID_kallsyms_seqs_of_names,
> > +	MEMINSPECT_ID_swapper_pg_dir,
> > +	MEMINSPECT_ID_DYNAMIC,
> > +	MEMINSPECT_ID_MAX = 201,
> 
> Err why 201?

Ideally, there should not be any limit, but to add more context,
this was one of the backend limitation and should be removed from
here.

> 
> > +};
> 
> This feels like a bunch of stuff you didn't document?

If it looks worth documenting, I will do it..

> 
> > +
> > +#define MEMINSPECT_TYPE_REGULAR		0
> > +
> > +#define MEMINSPECT_NOTIFIER_ADD		0
> > +#define MEMINSPECT_NOTIFIER_REMOVE	1
> 
> Broken indentation...

Ack.

> 
> > +
> > +/**
> > + * struct inspect_entry - memory inspect entry information
> > + * @id: unique id for this entry
> > + * @va: virtual address for the memory (pointer)
> 
> Err what?? Virtual address as mapped how? Are you now assuming things are
> mapped?

It should be directly mapped virtual addresses and should be
documented.

> 
> > + * @pa: physical address for the memory
> > + * @size: size of the memory area of this entry
> > + * @type: type of the entry (class)
> 
> 'Class'?

Ack.

> 
> > + */
> > +struct inspect_entry {
> > +	enum meminspect_uid	id;
> > +	void			*va;
> > +	phys_addr_t		pa;
> > +	size_t			size;
> > +	unsigned int		type;
> > +};
> > +
> > +/**
> > + * typedef meminspect_iter_cb_t - Iterator callback for meminspect traversal
> > + * @priv: private data passed through from the caller of meminspect_traverse()
> > + * @ie:   pointer to the current inspect_entry; read-only, table lock held
> > + *
> > + * The table lock is held by the caller; the callback must not call any
> > + * meminspect_table_lock() or meminspect_table_unlock() variants.
> > + */
> > +typedef void (*meminspect_iter_cb_t)(void *priv, const struct inspect_entry *ie);
> 
> So drivers can now just access some tagged region, with a VA that err I
> guess we just assume is valid when accessed and a PA that err I guess we
> just assume is still being used for what it was tagged for?
> 

Currently, all the tagged one are trusted as directly mapped
one.

> This seems insane?
> 
> > +
> > +#ifdef CONFIG_MEMINSPECT
> > +/* .inspect_table section table markers*/
> > +extern const struct inspect_entry __inspect_table[];
> > +extern const struct inspect_entry __inspect_table_end[];
> > +
> > +/*
> > + * Annotate a static variable into inspection table.
> > + * Can be called multiple times for the same ID, in which case
> > + * multiple table entries will be created
> > + */
> > +#define MEMINSPECT_ENTRY(idx, sym, sz)						\
> > +	static const struct inspect_entry __UNIQUE_ID(__inspect_entry_##idx)	\
> > +	__used __section(".inspect_table") = {					\
> > +		.id = idx,							\
> > +		.va = (void *)&(sym),						\
> > +		.size = (sz),							\
> > +	}
> > +/*
> > + * A simple entry is just a variable, the size of the entry is the variable size
> > + * The variable can also be a pointer, the pointer itself is being added in this
> > + * case.
> > + */
> > +#define MEMINSPECT_SIMPLE_ENTRY(sym)	\
> > +	MEMINSPECT_ENTRY(MEMINSPECT_ID_##sym, sym, sizeof(sym))
> > +/*
> > + * In the case when `sym` is not a variable, but a member of a struct e.g.,
> > + * and we cannot derive a name from it, a name must be provided.
> > + */
> > +#define MEMINSPECT_NAMED_ENTRY(name, sym)	\
> > +	MEMINSPECT_ENTRY(MEMINSPECT_ID_##name, sym, sizeof(sym))
> > +/*
> > + * Create a more complex entry, by registering an arbitrary memory starting
> > + * at sym. The size is provided as a parameter.
> > + * This is used e.g. when the symbol is a start of an unknown sized array.
> > + */
> > +#define MEMINSPECT_AREA_ENTRY(sym, sz) \
> > +	MEMINSPECT_ENTRY(MEMINSPECT_ID_##sym, sym, sz)
> > +
> > +/* Iterate through .inspect_table section entries */
> > +#define for_each_meminspect_entry(__entry)		\
> > +	for (__entry = __inspect_table;			\
> > +	     __entry < __inspect_table_end;		\
> > +	     __entry++)
> > +
> > +#else
> > +#define MEMINSPECT_ENTRY(...)
> > +#define MEMINSPECT_SIMPLE_ENTRY(...)
> > +#define MEMINSPECT_NAMED_ENTRY(...)
> > +#define MEMINSPECT_AREA_ENTRY(...)
> > +#endif
> > +
> > +#ifdef CONFIG_MEMINSPECT
> > +
> > +/*
> > + * Dynamic helpers to register entries.
> > + * These do not lock the table, so use with caution.
> > + */
> > +void meminspect_register_id_pa(enum meminspect_uid id, phys_addr_t zone,
> > +			       size_t size, unsigned int type);
> > +void meminspect_table_lock(void);
> > +void meminspect_table_unlock(void);
> > +
> > +#define meminspect_register_pa(...) \
> > +	meminspect_register_id_pa(MEMINSPECT_ID_DYNAMIC, __VA_ARGS__, MEMINSPECT_TYPE_REGULAR)
> > +
> > +#define meminspect_register_id_va(id, va, size) \
> > +	meminspect_register_id_pa(id, virt_to_phys(va), size, MEMINSPECT_TYPE_REGULAR)
> > +
> > +#define meminspect_register_va(...) \
> > +	meminspect_register_id_va(MEMINSPECT_ID_DYNAMIC, __VA_ARGS__)
> > +
> > +void meminspect_unregister_pa(phys_addr_t zone, size_t size);
> > +void meminspect_unregister_id(enum meminspect_uid id);
> > +
> > +#define meminspect_unregister_va(va, size) \
> > +	meminspect_unregister_pa(virt_to_phys(va), size)
> > +
> > +void meminspect_traverse(void *priv, meminspect_iter_cb_t cb);
> > +
> > +/*
> > + * Producers, or registrators, are advised to use the locked API below
> > + */
> > +#define meminspect_lock_register_pa(...)			\
> > +	do {							\
> > +		meminspect_table_lock();			\
> > +		meminspect_register_pa(__VA_ARGS__);		\
> > +		meminspect_table_unlock();			\
> > +	} while (0)
> > +
> > +#define meminspect_lock_register_id_va(...)			\
> > +	do {							\
> > +		meminspect_table_lock();			\
> > +		meminspect_register_id_va(__VA_ARGS__);		\
> > +		meminspect_table_unlock();			\
> > +	} while (0)
> > +
> > +#define meminspect_lock_register_va(...)			\
> > +	do {							\
> > +		meminspect_table_lock();			\
> > +		meminspect_register_va(__VA_ARGS__);		\
> > +		meminspect_table_unlock();			\
> > +	} while (0)
> > +
> > +#define meminspect_lock_unregister_pa(...)			\
> > +	do {							\
> > +		meminspect_table_lock();			\
> > +		meminspect_unregister_pa(__VA_ARGS__);		\
> > +		meminspect_table_unlock();			\
> > +	} while (0)
> > +
> > +#define meminspect_lock_unregister_va(...)			\
> > +	do {							\
> > +		meminspect_table_lock();			\
> > +		meminspect_unregister_va(__VA_ARGS__);		\
> > +		meminspect_table_unlock();			\
> > +	} while (0)
> > +
> > +#define meminspect_lock_unregister_id(...)			\
> > +	do {							\
> > +		meminspect_table_lock();			\
> > +		meminspect_unregister_id(__VA_ARGS__);		\
> > +		meminspect_table_unlock();			\
> > +	} while (0)
> > +
> > +#define meminspect_lock_traverse(...)				\
> > +	do {							\
> > +		meminspect_table_lock();			\
> > +		meminspect_traverse(__VA_ARGS__);		\
> > +		meminspect_table_unlock();			\
> > +	} while (0)
> > +
> > +int meminspect_notifier_register(struct notifier_block *n);
> > +int meminspect_notifier_unregister(struct notifier_block *n);
> > +
> > +#else
> > +static inline void meminspect_register_id_pa(enum meminspect_uid id,
> > +					     phys_addr_t zone,
> > +					     size_t size, unsigned int type)
> > +{
> > +}
> > +
> > +static inline void meminspect_table_lock(void)
> > +{
> > +}
> > +
> > +static inline void meminspect_table_unlock(void)
> > +{
> > +}
> > +
> > +static inline void meminspect_unregister_pa(phys_addr_t zone, size_t size)
> > +{
> > +}
> > +
> > +static inline void meminspect_unregister_id(enum meminspect_uid id)
> > +{
> > +}
> > +
> > +static inline void meminspect_traverse(void *priv, meminspect_iter_cb_t cb)
> > +{
> > +}
> > +
> > +static inline int meminspect_notifier_register(struct notifier_block *n)
> > +{
> > +	return 0;
> > +}
> > +
> > +static inline int meminspect_notifier_unregister(struct notifier_block *n)
> > +{
> > +	return 0;
> > +}
> > +
> > +#define meminspect_register_pa(...)		do { } while (0)
> > +#define meminspect_register_id_va(...)		do { } while (0)
> > +#define meminspect_register_va(...)		do { } while (0)
> > +#define meminspect_lock_register_pa(...)	do { } while (0)
> > +#define meminspect_lock_register_va(...)	do { } while (0)
> > +#define meminspect_lock_register_id_va(...)	do { } while (0)
> > +#define meminspect_lock_traverse(...)		do { } while (0)
> > +#define meminspect_lock_unregister_va(...)	do { } while (0)
> > +#define meminspect_lock_unregister_pa(...)	do { } while (0)
> > +#define meminspect_lock_unregister_id(...)	do { } while (0)
> > +#endif
> > +
> > +#endif
> > diff --git a/init/Kconfig b/init/Kconfig
> > index fa42fb264c9c..adbe607b7b62 100644
> > --- a/init/Kconfig
> > +++ b/init/Kconfig
> > @@ -2294,6 +2294,7 @@ config TRACEPOINTS
> >  source "kernel/Kconfig.kexec"
> >
> >  source "kernel/liveupdate/Kconfig"
> > +source "kernel/meminspect/Kconfig"
> >
> >  endmenu		# General setup
> >
> > diff --git a/kernel/Makefile b/kernel/Makefile
> > index 1e1a31673577..7c74a4f94a81 100644
> > --- a/kernel/Makefile
> > +++ b/kernel/Makefile
> > @@ -52,6 +52,7 @@ obj-y += locking/
> >  obj-y += power/
> >  obj-y += printk/
> >  obj-y += irq/
> > +obj-y += meminspect/
> >  obj-y += rcu/
> >  obj-y += livepatch/
> >  obj-y += liveupdate/
> > diff --git a/kernel/meminspect/Kconfig b/kernel/meminspect/Kconfig
> > new file mode 100644
> > index 000000000000..18ff511ad4cf
> > --- /dev/null
> > +++ b/kernel/meminspect/Kconfig
> > @@ -0,0 +1,18 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +config MEMINSPECT
> > +	bool "Allow the kernel to register memory regions for inspection purpose"
> > +	depends on !CRASH_DUMP || DMA_CMA
> 
> Why does it depend on CONFIG_DMA_CMA?

It uses CMA for contiguous memory to store ELF metadata for all
segments, which will be the very first entry in the table. The
dma_alloc_from_contiguous() and dma_common_contiguous_remap()
APIs are used for this purpose.

> 
> > +	help
> > +	  Inspection mechanism allows registration of a specific memory
> > +	  area (or object) for later inspection purposes. Ranges are added
> > +	  into an inspection table, which can be requested and analyzed by
> > +	  specific drivers. Drivers would interface any hardware mechanism
> > +	  that will allow inspection of the data, including but not limited
> > +	  to: dumping for debugging, creating a coredump, analysis, or
> > +	  statistical information.  The inspection table is created ahead
> > +	  of time such that it can be later used regardless of the state of
> > +	  the kernel (running, frozen, crashed, or any particular state).
> 
> Another wall of text and it's not at all clear what this is suppose to do,
> this needs to be completely reworked.

Ack.

> 
> > +
> > +	  Note that modules using this feature must be rebuilt if this
> > +	  option changes.
> > diff --git a/kernel/meminspect/Makefile b/kernel/meminspect/Makefile
> > new file mode 100644
> > index 000000000000..09fd55e6d9cf
> > --- /dev/null
> > +++ b/kernel/meminspect/Makefile
> > @@ -0,0 +1,3 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +obj-$(CONFIG_MEMINSPECT) += meminspect.o
> > diff --git a/kernel/meminspect/meminspect.c b/kernel/meminspect/meminspect.c
> > new file mode 100644
> > index 000000000000..d9d38f484f1f
> > --- /dev/null
> > +++ b/kernel/meminspect/meminspect.c
> > @@ -0,0 +1,474 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +
> > +#include <linux/crash_core.h>
> > +#include <linux/dma-map-ops.h>
> > +#include <linux/errno.h>
> > +#include <linux/meminspect.h>
> > +#include <linux/notifier.h>
> > +#include <linux/vmcore_info.h>
> > +
> > +static DEFINE_MUTEX(meminspect_lock);
> > +static struct inspect_entry inspect_entries[MEMINSPECT_ID_MAX];
> > +
> > +static ATOMIC_NOTIFIER_HEAD(meminspect_notifier_list);
> > +
> > +#ifdef CONFIG_CRASH_DUMP
> > +
> > +#define CORE_STR "CORE"
> > +
> > +static struct elfhdr *ehdr;
> > +static size_t elf_offset;
> > +static bool elf_hdr_ready;
> > +
> > +static void append_kcore_note(char *notes, size_t *i, const char *name,
> > +			      unsigned int type, const void *desc,
> > +			      size_t descsz)
> > +{
> > +	struct elf_note *note = (struct elf_note *)&notes[*i];
> > +
> > +	note->n_namesz = strlen(name) + 1;
> > +	note->n_descsz = descsz;
> > +	note->n_type = type;
> > +	*i += sizeof(*note);
> > +	memcpy(&notes[*i], name, note->n_namesz);
> > +	*i = ALIGN(*i + note->n_namesz, 4);
> > +	memcpy(&notes[*i], desc, descsz);
> > +	*i = ALIGN(*i + descsz, 4);
> > +}
> > +
> > +static void append_kcore_note_nodesc(char *notes, size_t *i, const char *name,
> > +				     unsigned int type, size_t descsz)
> > +{
> > +	struct elf_note *note = (struct elf_note *)&notes[*i];
> > +
> > +	note->n_namesz = strlen(name) + 1;
> > +	note->n_descsz = descsz;
> > +	note->n_type = type;
> > +	*i += sizeof(*note);
> > +	memcpy(&notes[*i], name, note->n_namesz);
> > +	*i = ALIGN(*i + note->n_namesz, 4);
> > +}
> > +
> > +static struct elf_phdr *elf_phdr_entry_addr(struct elfhdr *ehdr, int idx)
> > +{
> > +	struct elf_phdr *ephdr = (struct elf_phdr *)((size_t)ehdr + ehdr->e_phoff);
> > +
> > +	return &ephdr[idx];
> > +}
> > +
> > +static int clear_elfheader(const struct inspect_entry *e)
> > +{
> > +	struct elf_phdr *phdr;
> > +	struct elf_phdr *tmp_phdr;
> > +	unsigned int phidx;
> > +	unsigned int i;
> > +
> > +	for (i = 0; i < ehdr->e_phnum; i++) {
> > +		phdr = elf_phdr_entry_addr(ehdr, i);
> > +		if (phdr->p_paddr == e->pa &&
> > +		    phdr->p_memsz == ALIGN(e->size, 4))
> > +			break;
> > +	}
> > +
> > +	if (i == ehdr->e_phnum) {
> > +		pr_debug("Cannot find program header entry in elf\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	phidx = i;
> > +
> > +	/* Clear program header */
> > +	tmp_phdr = elf_phdr_entry_addr(ehdr, phidx);
> > +	for (i = phidx; i < ehdr->e_phnum - 1; i++) {
> > +		tmp_phdr = elf_phdr_entry_addr(ehdr, i + 1);
> > +		phdr = elf_phdr_entry_addr(ehdr, i);
> > +		memcpy(phdr, tmp_phdr, sizeof(*phdr));
> > +		phdr->p_offset = phdr->p_offset - ALIGN(e->size, 4);
> > +	}
> > +	memset(tmp_phdr, 0, sizeof(*tmp_phdr));
> > +	ehdr->e_phnum--;
> > +
> > +	elf_offset -= ALIGN(e->size, 4);
> > +
> > +	return 0;
> > +}
> > +
> > +static void update_elfheader(const struct inspect_entry *e)
> > +{
> > +	struct elf_phdr *phdr;
> > +
> > +	phdr = elf_phdr_entry_addr(ehdr, ehdr->e_phnum++);
> > +
> > +	phdr->p_type = PT_LOAD;
> > +	phdr->p_offset = elf_offset;
> > +	phdr->p_vaddr = (elf_addr_t)e->va;
> > +	if (e->pa)
> > +		phdr->p_paddr = (elf_addr_t)e->pa;
> > +	else
> > +		phdr->p_paddr = (elf_addr_t)virt_to_phys(e->va);
> > +
> > +	phdr->p_filesz = ALIGN(e->size, 4);
> > +	phdr->p_memsz = ALIGN(e->size, 4);
> > +	phdr->p_flags = PF_R | PF_W;
> > +	elf_offset += ALIGN(e->size, 4);
> > +}
> > +
> > +/*
> > + * This function prepares the elf header for the coredump image.
> > + * Initially there is a single program header for the elf NOTE.
> > + * The note contains the usual core dump information, and the vmcoreinfo.
> > + */
> > +static int init_elfheader(void)
> > +{
> > +	struct elf_phdr *phdr;
> > +	void *notes;
> > +	unsigned int elfh_size, buf_sz;
> > +	unsigned int phdr_off;
> > +	size_t note_len, i = 0;
> > +	struct page *p;
> > +
> > +	struct elf_prstatus prstatus = {};
> > +	struct elf_prpsinfo prpsinfo = {
> > +		.pr_sname = 'R',
> > +		.pr_fname = "vmlinux",
> > +	};
> > +
> > +	/*
> > +	 * Header buffer contains:
> > +	 * ELF header, Note entry with PR status, PR ps info, and vmcoreinfo.
> > +	 * Also, MEMINSPECT_ID_MAX program headers.
> > +	 */
> > +	elfh_size = sizeof(*ehdr);
> > +	elfh_size += sizeof(struct elf_prstatus);
> > +	elfh_size += sizeof(struct elf_prpsinfo);
> > +	elfh_size += sizeof(VMCOREINFO_NOTE_NAME);
> > +	elfh_size += ALIGN(vmcoreinfo_size, 4);
> > +	elfh_size += (sizeof(*phdr)) * (MEMINSPECT_ID_MAX);
> > +
> > +	elfh_size = ALIGN(elfh_size, 4);
> > +
> > +	/* Length of the note is made of :
> > +	 * 3 elf notes structs (prstatus, prpsinfo, vmcoreinfo)
> > +	 * 3 notes names (2 core strings, 1 vmcoreinfo name)
> > +	 * sizeof each note
> > +	 */
> > +	note_len = (3 * sizeof(struct elf_note) +
> > +		    2 * ALIGN(sizeof(CORE_STR), 4) +
> > +		    VMCOREINFO_NOTE_NAME_BYTES +
> > +		    ALIGN(sizeof(struct elf_prstatus), 4) +
> > +		    ALIGN(sizeof(struct elf_prpsinfo), 4) +
> > +		    ALIGN(vmcoreinfo_size, 4));
> > +
> > +	buf_sz = elfh_size + note_len - ALIGN(vmcoreinfo_size, 4);
> > +
> > +	/* Never freed */
> > +	p = dma_alloc_from_contiguous(NULL, buf_sz >> PAGE_SHIFT,
> > +				      get_order(buf_sz), true);
> > +	if (!p)
> > +		return -ENOMEM;
> > +
> > +	ehdr = dma_common_contiguous_remap(p, buf_sz,
> > +					   pgprot_decrypted(pgprot_dmacoherent(PAGE_KERNEL)),
> > +					   __builtin_return_address(0));
> > +	if (!ehdr) {
> > +		dma_release_from_contiguous(NULL, p, buf_sz >> PAGE_SHIFT);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	memset(ehdr, 0, elfh_size);
> > +
> > +	/* Assign Program headers offset, it's right after the elf header. */
> > +	phdr = (struct elf_phdr *)(ehdr + 1);
> > +	phdr_off = sizeof(*ehdr);
> > +
> > +	memcpy(ehdr->e_ident, ELFMAG, SELFMAG);
> > +	ehdr->e_ident[EI_CLASS] = ELF_CLASS;
> > +	ehdr->e_ident[EI_DATA] = ELF_DATA;
> > +	ehdr->e_ident[EI_VERSION] = EV_CURRENT;
> > +	ehdr->e_ident[EI_OSABI] = ELF_OSABI;
> > +	ehdr->e_type = ET_CORE;
> > +	ehdr->e_machine = ELF_ARCH;
> > +	ehdr->e_version = EV_CURRENT;
> > +	ehdr->e_ehsize = sizeof(*ehdr);
> > +	ehdr->e_phentsize = sizeof(*phdr);
> > +
> > +	elf_offset = elfh_size;
> > +
> > +	notes = (void *)(((char *)ehdr) + elf_offset);
> > +
> > +	/* we have a single program header now */
> > +	ehdr->e_phnum = 1;
> > +
> > +	phdr->p_type = PT_NOTE;
> > +	phdr->p_offset = elf_offset;
> > +	phdr->p_filesz = note_len;
> > +
> > +	/* advance elf offset */
> > +	elf_offset += note_len;
> > +
> > +	strscpy(prpsinfo.pr_psargs, saved_command_line,
> > +		sizeof(prpsinfo.pr_psargs));
> > +
> > +	append_kcore_note(notes, &i, CORE_STR, NT_PRSTATUS, &prstatus,
> > +			  sizeof(prstatus));
> > +	append_kcore_note(notes, &i, CORE_STR, NT_PRPSINFO, &prpsinfo,
> > +			  sizeof(prpsinfo));
> > +	append_kcore_note_nodesc(notes, &i, VMCOREINFO_NOTE_NAME, 0,
> > +				 ALIGN(vmcoreinfo_size, 4));
> > +
> > +	ehdr->e_phoff = phdr_off;
> > +
> > +	/* This is the first coredump region, the ELF header */
> > +	meminspect_register_id_pa(MEMINSPECT_ID_ELF, page_to_phys(p),
> > +				  buf_sz, MEMINSPECT_TYPE_REGULAR);
> > +
> > +	/*
> > +	 * The second region is the vmcoreinfo, which goes right after.
> > +	 * It's being registered through vmcoreinfo.
> > +	 */
> > +
> > +	return 0;
> > +}
> > +#endif
> 
> Put /* <condition> */ on the end of big #endif blocks please.

Ack.

> 
> > +
> > +/**
> > + * meminspect_unregister_id() - Unregister region from inspection table.
> > + * @id: region's id in the table
> > + *
> > + * Return: None
> > + */
> > +void meminspect_unregister_id(enum meminspect_uid id)
> > +{
> > +	struct inspect_entry *e;
> > +
> > +	WARN_ON(!mutex_is_locked(&meminspect_lock));
> > +
> > +	e = &inspect_entries[id];
> > +	if (!e->id)
> > +		return;
> > +
> > +	atomic_notifier_call_chain(&meminspect_notifier_list,
> > +				   MEMINSPECT_NOTIFIER_REMOVE, e);
> > +#ifdef CONFIG_CRASH_DUMP
> > +	if (elf_hdr_ready)
> > +		clear_elfheader(e);
> > +#endif
> > +	memset(e, 0, sizeof(*e));
> > +}
> > +EXPORT_SYMBOL_GPL(meminspect_unregister_id);
> > +
> > +/**
> > + * meminspect_unregister_pa() - Unregister region from inspection table.
> > + * @pa: Physical address of the memory region to remove
> > + * @size: Size of the memory region to remove
> > + *
> > + * Return: None
> > + */
> > +void meminspect_unregister_pa(phys_addr_t pa, size_t size)
> > +{
> > +	struct inspect_entry *e;
> > +	enum meminspect_uid i;
> > +
> > +	WARN_ON(!mutex_is_locked(&meminspect_lock));
> > +
> > +	for (i = MEMINSPECT_ID_ELF; i < MEMINSPECT_ID_MAX; i++) {
> > +		e = &inspect_entries[i];
> > +		if (e->pa != pa)
> > +			continue;
> > +		if (e->size != size)
> > +			continue;
> > +		meminspect_unregister_id(e->id);
> > +		return;
> > +	}
> > +}
> > +EXPORT_SYMBOL_GPL(meminspect_unregister_pa);
> > +
> > +/**
> > + * meminspect_register_id_pa() - Register region into inspection table
> > + *		 with given ID and physical address.
> > + * @req_id: Requested unique meminspect_uid that identifies the region
> > + *	This can be MEMINSPECT_ID_DYNAMIC, in which case the function will
> > + *	find an unused ID and register with it.
> > + * @pa: physical address of the memory region
> > + * @size: region size
> > + * @type: region type
> > + *
> > + * Return: None
> > + */
> > +void meminspect_register_id_pa(enum meminspect_uid req_id, phys_addr_t pa,
> > +			       size_t size, unsigned int type)
> > +{
> > +	struct inspect_entry *e;
> > +	enum meminspect_uid uid = req_id;
> > +
> > +	WARN_ON(!mutex_is_locked(&meminspect_lock));
> > +
> > +	if (uid <= MEMINSPECT_ID_NONE || uid >= MEMINSPECT_ID_MAX)
> > +		return;
> > +
> > +	if (uid == MEMINSPECT_ID_DYNAMIC)
> > +		while (uid < MEMINSPECT_ID_MAX) {
> > +			if (!inspect_entries[uid].id)
> > +				break;
> > +			uid++;
> > +		}
> > +
> > +	if (uid == MEMINSPECT_ID_MAX)
> > +		return;
> > +
> > +	e = &inspect_entries[uid];
> > +
> > +	if (e->id)
> > +		meminspect_unregister_id(e->id);
> > +
> > +	e->pa = pa;
> > +	e->va = phys_to_virt(pa);
> > +	e->size = size;
> > +	e->id = uid;
> > +	e->type = type;
> > +#ifdef CONFIG_CRASH_DUMP
> > +	if (elf_hdr_ready)
> > +		update_elfheader(e);
> > +#endif
> > +	atomic_notifier_call_chain(&meminspect_notifier_list,
> > +				   MEMINSPECT_NOTIFIER_ADD, e);
> > +}
> > +EXPORT_SYMBOL_GPL(meminspect_register_id_pa);
> > +
> > +/**
> > + * meminspect_table_lock() - Lock the mutex on the inspection table
> > + *
> > + * Return: None
> > + */
> > +void meminspect_table_lock(void)
> > +{
> > +	mutex_lock(&meminspect_lock);
> > +}
> > +EXPORT_SYMBOL_GPL(meminspect_table_lock);
> > +
> > +/**
> > + * meminspect_table_unlock() - Unlock the mutex on the inspection table
> > + *
> > + * Return: None
> > + */
> > +void meminspect_table_unlock(void)
> > +{
> > +	mutex_unlock(&meminspect_lock);
> > +}
> > +EXPORT_SYMBOL_GPL(meminspect_table_unlock);
> > +
> > +/**
> > + * meminspect_traverse() - Traverse the meminspect table and call the
> > + *		callback function for each valid entry.
> > + * @priv: private data to be passed to the callback
> > + * @cb: meminspect iterator callback that should be called for each entry
> > + *
> > + * Return: None
> > + */
> > +void meminspect_traverse(void *priv, meminspect_iter_cb_t cb)
> > +{
> > +	const struct inspect_entry *e;
> > +	int i;
> > +
> > +	WARN_ON(!mutex_is_locked(&meminspect_lock));
> > +
> > +	for (i = MEMINSPECT_ID_ELF; i < MEMINSPECT_ID_MAX; i++) {
> > +		e = &inspect_entries[i];
> > +		if (e->id)
> > +			cb(priv, e);
> > +	}
> > +}
> > +EXPORT_SYMBOL_GPL(meminspect_traverse);
> > +
> > +/**
> > + * meminspect_notifier_register() - Register a notifier to meminspect table
> > + * @n: notifier block to register. This will be called whenever an entry
> > + *		is being added or removed.
> > + *
> > + * Return: errno
> > + */
> > +int meminspect_notifier_register(struct notifier_block *n)
> > +{
> > +	return atomic_notifier_chain_register(&meminspect_notifier_list, n);
> > +}
> > +EXPORT_SYMBOL_GPL(meminspect_notifier_register);
> > +
> > +/**
> > + * meminspect_notifier_unregister() - Unregister a previously registered
> > + *		notifier from meminspect table.
> > + * @n: notifier block to unregister.
> > + *
> > + * Return: errno
> > + */
> > +int meminspect_notifier_unregister(struct notifier_block *n)
> > +{
> > +	return atomic_notifier_chain_unregister(&meminspect_notifier_list, n);
> > +}
> > +EXPORT_SYMBOL_GPL(meminspect_notifier_unregister);
> > +
> > +#ifdef CONFIG_CRASH_DUMP
> > +static int __init meminspect_prepare_crashdump(void)
> > +{
> > +	const struct inspect_entry *e;
> > +	int ret;
> > +	enum meminspect_uid i;
> > +
> > +	ret = init_elfheader();
> > +
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	/*
> > +	 * Some regions may have been registered very early.
> > +	 * Update the elf header for all existing regions,
> > +	 * except for MEMINSPECT_ID_ELF and MEMINSPECT_ID_VMCOREINFO,
> > +	 * those are included in the ELF header upon its creation.
> > +	 */
> > +	for (i = MEMINSPECT_ID_VMCOREINFO + 1; i < MEMINSPECT_ID_MAX; i++) {
> > +		e = &inspect_entries[i];
> > +		if (e->id)
> > +			update_elfheader(e);
> > +	}
> > +
> > +	elf_hdr_ready = true;
> > +
> > +	return 0;
> > +}
> > +#endif
> > +
> > +static int __init meminspect_prepare_table(void)
> > +{
> > +	const struct inspect_entry *e;
> > +	enum meminspect_uid i;
> > +	int ret;
> > +
> > +	meminspect_table_lock();
> > +	/*
> > +	 * First, copy all entries from the compiler built table
> > +	 * In case some entries are registered multiple times,
> > +	 * the last chronological entry will be stored.
> > +	 * Previously registered entries will be dropped.
> > +	 */
> > +	for_each_meminspect_entry(e) {
> > +		inspect_entries[e->id] = *e;
> > +		if (!inspect_entries[e->id].pa && inspect_entries[e->id].va)
> > +			inspect_entries[e->id].pa = virt_to_phys(inspect_entries[e->id].va);
> > +	}
> > +#ifdef CONFIG_CRASH_DUMP
> > +	ret = meminspect_prepare_crashdump();
> > +	if (ret)
> > +		pr_warn("meminspect: failed to prepare crashdump ELF header: %d\n", ret);
> > +#endif
> > +	/* if we have early notifiers registered, call them now */
> > +	for (i = MEMINSPECT_ID_ELF; i < MEMINSPECT_ID_MAX; i++)
> > +		if (inspect_entries[i].id)
> > +			atomic_notifier_call_chain(&meminspect_notifier_list,
> > +						   MEMINSPECT_NOTIFIER_ADD,
> > +						   &inspect_entries[i]);
> > +	meminspect_table_unlock();
> > +
> > +	pr_debug("Memory inspection table initialized\n");
> > +
> > +	return 0;
> > +}
> > +late_initcall(meminspect_prepare_table);
> >
> > --
> > 2.53.0
> >
> 
> Thanks, Lorenzo

-- 
-Mukesh Ojha

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 26/26] meminspect: Add debug kinfo compatible driver
  2026-07-08  8:06   ` Lorenzo Stoakes
@ 2026-07-08 18:46     ` Mukesh Ojha
  0 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08 18:46 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: akpm, anna-maria, arnd, andersson, chrisl, cl, conor+dt, david,
	dennis, devicetree, ehristev, frederic, mingo, jstultz, corbet,
	juri.lelli, kasong, kees, konradybcio, krzk+dt, linux-arch,
	linux-arm-msm, linux-doc, linux-kernel, linux-mm,
	linux-remoteproc, mathieu.poirier, peterz, pmladek, robh,
	saravanak, tj, tglx, vincent.guittot, workflows, atomlin, ast,
	aliceryhl, linux.amoon, ardb, baoquan.he, baohua, bsegall,
	jackmanb, leitao, brauner, coxu, dietmar.eggemann, dianders,
	ebiggers, feng.tang, yangfeng, gary, guohanjun, jack,
	wangjinchao600, joel.granados, hannes, john.ogness, jpoimboe,
	shikemeng, kas, kprateek.nayak, liam, elver, mgorman, mhocko,
	ojeda, rppt, namcao, nathan, nphamcs, n.schier, pasha.tatashin,
	petr.pavlu, pnina.feder, rdunlap, rioo.tsukatsukii, senozhatsky,
	skhan, sboyd, rostedt, surenb, thomas.weissschuh, vschneid,
	vbabka, youngjun.park, zhengyejian, ziy, Eugen Hristev

On Wed, Jul 08, 2026 at 09:06:52AM +0100, Lorenzo Stoakes wrote:
> On Wed, Jul 08, 2026 at 12:38:09PM +0530, Mukesh Ojha wrote:
> > From: Eugen Hristev <eugen.hristev@linaro.org>
> >
> > With this driver, the registered regions are copied to a shared memory
> > zone at register time. The shared memory zone is supplied via OF. This
> > driver will select only regions that are of interest, and keep only
> > addresses. The format of the list is Kinfo compatible, with devices like
> > Google Pixel phone. The firmware is only interested in some symbols'
> > addresses.
> >
> > Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> 
> Hang on, this is a driver that exposes internal kernel symbol information in a
> shared memory region for anybody who wants to access it?
>

Yes, this was one of the others we could find in the Android
kernel, which could be another use case of the meminspect
backend.

https://android.googlesource.com/kernel/common/+/refs/heads/android-mainline/drivers/android/debug_kinfo.c

-Mukesh

> This doesn't really seem sane?
> 
> Looking through the code it seems you are only exposing things that are already
> otherwise exposed, so maybe it's not so bad, but it seems as if a registered
> meminfo driver could in any case get access to things they shouldn't?

> 
> > ---
> >  MAINTAINERS                |   1 +
> >  drivers/of/platform.c      |   1 +
> >  kernel/meminspect/Kconfig  |  11 ++
> >  kernel/meminspect/Makefile |   1 +
> >  kernel/meminspect/kinfo.c  | 257 +++++++++++++++++++++++++++++++++++++
> >  5 files changed, 271 insertions(+)
> >  create mode 100644 kernel/meminspect/kinfo.c
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 2d816d783024..d805ff9fedac 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -16906,6 +16906,7 @@ M:	Eugen Hristev <eugen.hristev@linaro.org>
> >  M:	Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> >  S:	Maintained
> >  F:	Documentation/devicetree/bindings/reserved-memory/google,debug-kinfo.yaml
> > +F:	kernel/meminspect/kinfo.c
> >
> >  MEMBLOCK AND MEMORY MANAGEMENT INITIALIZATION
> >  M:	Mike Rapoport <rppt@kernel.org>
> > diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> > index 53bca8c6f781..f80bd25fc481 100644
> > --- a/drivers/of/platform.c
> > +++ b/drivers/of/platform.c
> > @@ -494,6 +494,7 @@ static const struct of_device_id reserved_mem_matches[] = {
> >  	{ .compatible = "qcom,smem" },
> >  	{ .compatible = "ramoops" },
> >  	{ .compatible = "nvmem-rmem" },
> > +	{ .compatible = "google,debug-kinfo" },
> >  	{ .compatible = "google,open-dice" },
> >  	{}
> >  };
> > diff --git a/kernel/meminspect/Kconfig b/kernel/meminspect/Kconfig
> > index 18ff511ad4cf..7f6436c3344b 100644
> > --- a/kernel/meminspect/Kconfig
> > +++ b/kernel/meminspect/Kconfig
> > @@ -16,3 +16,14 @@ config MEMINSPECT
> >
> >  	  Note that modules using this feature must be rebuilt if this
> >  	  option changes.
> > +
> > +config MEMINSPECT_KINFO
> > +	tristate "Shared memory KInfo compatible driver"
> > +	depends on MEMINSPECT
> > +	help
> > +	  Say y here to enable the Shared memory KInfo compatible driver.
> > +	  With this driver, the registered regions are copied to a shared
> > +	  memory zone at register time.
> > +	  The shared memory zone is supplied via OF.
> > +	  This driver will select only regions that are of interest,
> > +	  and keep only addresses. The format of the list is Kinfo compatible.
> > diff --git a/kernel/meminspect/Makefile b/kernel/meminspect/Makefile
> > index 09fd55e6d9cf..283604d892e5 100644
> > --- a/kernel/meminspect/Makefile
> > +++ b/kernel/meminspect/Makefile
> > @@ -1,3 +1,4 @@
> >  # SPDX-License-Identifier: GPL-2.0
> >
> >  obj-$(CONFIG_MEMINSPECT) += meminspect.o
> > +obj-$(CONFIG_MEMINSPECT_KINFO) += kinfo.o
> > diff --git a/kernel/meminspect/kinfo.c b/kernel/meminspect/kinfo.c
> > new file mode 100644
> > index 000000000000..7451c13bc316
> > --- /dev/null
> > +++ b/kernel/meminspect/kinfo.c
> > @@ -0,0 +1,257 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + *
> > + * Copyright 2002 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
> > + * Copyright 2021 Google LLC
> > + * Copyright 2025 Linaro Ltd. Eugen Hristev <eugen.hristev@linaro.org>
> > + */
> > +#include <linux/container_of.h>
> > +#include <linux/kallsyms.h>
> > +#include <linux/meminspect.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_reserved_mem.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/utsname.h>
> > +
> > +#define BUILD_INFO_LEN		256
> > +#define DEBUG_KINFO_MAGIC	0xcceeddff
> > +
> > +/*
> > + * Header structure must be byte-packed, since the table is provided to
> > + * bootloader.
> > + */
> > +struct kernel_info {
> > +	/* For kallsyms */
> > +	u8 enabled_all;
> > +	u8 enabled_base_relative;
> > +	u8 enabled_absolute_percpu;
> > +	u8 enabled_cfi_clang;
> > +	u32 num_syms;
> > +	u16 name_len;
> > +	u16 bit_per_long;
> > +	u16 module_name_len;
> > +	u16 symbol_len;
> > +	u64 _relative_pa;
> > +	u64 _text_pa;
> > +	u64 _stext_pa;
> > +	u64 _etext_pa;
> > +	u64 _sinittext_pa;
> > +	u64 _einittext_pa;
> > +	u64 _end_pa;
> > +	u64 _offsets_pa;
> > +	u64 _names_pa;
> > +	u64 _token_table_pa;
> > +	u64 _token_index_pa;
> > +	u64 _markers_pa;
> > +	u64 _seqs_of_names_pa;
> > +
> > +	/* For frame pointer */
> > +	u32 thread_size;
> > +
> > +	/* For virt_to_phys */
> > +	u64 swapper_pg_dir_pa;
> > +
> > +	/* For linux banner */
> > +	u8 last_uts_release[__NEW_UTS_LEN];
> > +
> > +	/* For module kallsyms */
> > +	u32 enabled_modules_tree_lookup;
> > +	u32 mod_mem_offset;
> > +	u32 mod_kallsyms_offset;
> > +} __packed;
> > +
> > +struct kernel_all_info {
> > +	u32 magic_number;
> > +	u32 combined_checksum;
> > +	struct kernel_info info;
> > +} __packed;
> > +
> > +struct debug_kinfo {
> > +	struct device *dev;
> > +	void *all_info_addr;
> > +	size_t all_info_size;
> > +	struct notifier_block nb;
> > +};
> > +
> > +static void update_kernel_all_info(struct kernel_all_info *all_info)
> > +{
> > +	struct kernel_info *info;
> > +	u32 *checksum_info;
> > +	int index;
> > +
> > +	all_info->magic_number = DEBUG_KINFO_MAGIC;
> > +	all_info->combined_checksum = 0;
> > +
> > +	info = &all_info->info;
> > +	checksum_info = (u32 *)info;
> > +	for (index = 0; index < sizeof(*info) / sizeof(u32); index++)
> > +		all_info->combined_checksum ^= checksum_info[index];
> > +}
> > +
> > +static void __maybe_unused register_kinfo_region(void *priv,
> > +						 const struct inspect_entry *e)
> > +{
> > +	struct debug_kinfo *kinfo = priv;
> > +	struct kernel_all_info *all_info = kinfo->all_info_addr;
> > +	struct kernel_info *info = &all_info->info;
> > +	struct uts_namespace *uts;
> > +	u64 paddr;
> > +
> > +	if (e->pa)
> > +		paddr = e->pa;
> > +	else
> > +		paddr = __pa(e->va);
> > +
> > +	switch (e->id) {
> > +	case MEMINSPECT_ID__sinittext:
> > +		info->_sinittext_pa = paddr;
> > +		break;
> > +	case MEMINSPECT_ID__einittext:
> > +		info->_einittext_pa = paddr;
> > +		break;
> > +	case MEMINSPECT_ID__end:
> > +		info->_end_pa = paddr;
> > +		break;
> > +	case MEMINSPECT_ID__text:
> > +		info->_text_pa = paddr;
> > +		break;
> > +	case MEMINSPECT_ID__stext:
> > +		info->_stext_pa = paddr;
> > +		break;
> > +	case MEMINSPECT_ID__etext:
> > +		info->_etext_pa = paddr;
> > +		break;
> > +	case MEMINSPECT_ID_kallsyms_num_syms:
> > +		info->num_syms = *(__u32 *)e->va;
> > +		break;
> > +	case MEMINSPECT_ID_kallsyms_offsets:
> > +		info->_offsets_pa = paddr;
> > +		break;
> > +	case MEMINSPECT_ID_kallsyms_names:
> > +		info->_names_pa = paddr;
> > +		break;
> > +	case MEMINSPECT_ID_kallsyms_token_table:
> > +		info->_token_table_pa = paddr;
> > +		break;
> > +	case MEMINSPECT_ID_kallsyms_token_index:
> > +		info->_token_index_pa = paddr;
> > +		break;
> > +	case MEMINSPECT_ID_kallsyms_markers:
> > +		info->_markers_pa = paddr;
> > +		break;
> > +	case MEMINSPECT_ID_kallsyms_seqs_of_names:
> > +		info->_seqs_of_names_pa = paddr;
> > +		break;
> > +	case MEMINSPECT_ID_swapper_pg_dir:
> > +		info->swapper_pg_dir_pa = paddr;
> > +		break;
> > +	case MEMINSPECT_ID_init_uts_ns:
> > +		if (!e->va)
> > +			return;
> > +		uts = e->va;
> > +		strscpy(info->last_uts_release, uts->name.release, __NEW_UTS_LEN);
> > +		break;
> > +	default:
> > +		break;
> > +	};
> > +
> > +	update_kernel_all_info(all_info);
> > +}
> > +
> > +static int kinfo_notifier_cb(struct notifier_block *nb,
> > +			     unsigned long code, void *entry)
> > +{
> > +	struct debug_kinfo *kinfo = container_of(nb, struct debug_kinfo, nb);
> > +
> > +	if (code == MEMINSPECT_NOTIFIER_ADD)
> > +		register_kinfo_region(kinfo, entry);
> > +
> > +	return NOTIFY_DONE;
> > +}
> > +
> > +static int debug_kinfo_probe(struct platform_device *pdev)
> > +{
> > +	struct kernel_all_info *all_info;
> > +	struct device *dev = &pdev->dev;
> > +	struct reserved_mem *rmem;
> > +	struct debug_kinfo *kinfo;
> > +	struct kernel_info *info;
> > +
> > +	rmem = of_reserved_mem_lookup(dev->of_node);
> > +	if (!rmem)
> > +		return dev_err_probe(dev, -ENODEV, "no such reserved mem of node name %s\n",
> > +			      dev->of_node->name);
> > +
> > +	/* Need to wait for reserved memory to be mapped */
> > +	if (!rmem->priv)
> > +		return -EPROBE_DEFER;
> > +
> > +	if (!rmem->base || !rmem->size)
> > +		dev_err_probe(dev, -EINVAL, "unexpected reserved memory\n");
> > +
> > +	if (rmem->size < sizeof(struct kernel_all_info))
> > +		dev_err_probe(dev, -EINVAL, "reserved memory size too small\n");
> > +
> > +	kinfo = devm_kzalloc(dev, sizeof(*kinfo), GFP_KERNEL);
> > +	if (!kinfo)
> > +		return -ENOMEM;
> > +
> > +	platform_set_drvdata(pdev, kinfo);
> > +
> > +	kinfo->dev = dev;
> > +	kinfo->all_info_addr = rmem->priv;
> > +	kinfo->all_info_size = rmem->size;
> > +
> > +	all_info = kinfo->all_info_addr;
> > +
> > +	memset(all_info, 0, sizeof(struct kernel_all_info));
> > +	info = &all_info->info;
> > +	info->enabled_all = IS_ENABLED(CONFIG_KALLSYMS_ALL);
> > +	info->enabled_absolute_percpu = IS_ENABLED(CONFIG_KALLSYMS_ABSOLUTE_PERCPU);
> > +	info->enabled_base_relative = IS_ENABLED(CONFIG_KALLSYMS_BASE_RELATIVE);
> > +	info->enabled_cfi_clang = IS_ENABLED(CONFIG_CFI_CLANG);
> > +	info->name_len = KSYM_NAME_LEN;
> > +	info->bit_per_long = BITS_PER_LONG;
> > +	info->module_name_len = MODULE_NAME_LEN;
> > +	info->symbol_len = KSYM_SYMBOL_LEN;
> > +	info->thread_size = THREAD_SIZE;
> > +	info->enabled_modules_tree_lookup = IS_ENABLED(CONFIG_MODULES_TREE_LOOKUP);
> > +	info->mod_mem_offset = offsetof(struct module, mem);
> > +	info->mod_kallsyms_offset = offsetof(struct module, kallsyms);
> > +
> > +	kinfo->nb.notifier_call = kinfo_notifier_cb;
> > +
> > +	meminspect_notifier_register(&kinfo->nb);
> > +	meminspect_lock_traverse(kinfo, register_kinfo_region);
> > +
> > +	return 0;
> > +}
> > +
> > +static void debug_kinfo_remove(struct platform_device *pdev)
> > +{
> > +	struct debug_kinfo *kinfo = platform_get_drvdata(pdev);
> > +
> > +	meminspect_notifier_unregister(&kinfo->nb);
> > +}
> > +
> > +static const struct of_device_id debug_kinfo_of_match[] = {
> > +	{ .compatible	= "google,debug-kinfo" },
> > +	{},
> > +};
> > +MODULE_DEVICE_TABLE(of, debug_kinfo_of_match);
> > +
> > +static struct platform_driver debug_kinfo_driver = {
> > +	.probe = debug_kinfo_probe,
> > +	.remove = debug_kinfo_remove,
> > +	.driver = {
> > +		.name = "debug-kinfo",
> > +		.of_match_table = debug_kinfo_of_match,
> > +	},
> > +};
> > +module_platform_driver(debug_kinfo_driver);
> > +
> > +MODULE_AUTHOR("Eugen Hristev <eugen.hristev@linaro.org>");
> > +MODULE_AUTHOR("Jone Chou <jonechou@google.com>");
> > +MODULE_DESCRIPTION("meminspect Kinfo Driver");
> > +MODULE_LICENSE("GPL");
> > --
> > 2.53.0
> >

-- 
-Mukesh Ojha

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 21/26] printk: Register information into meminspect
  2026-07-08  7:59   ` Lorenzo Stoakes
@ 2026-07-08 18:53     ` Mukesh Ojha
  2026-07-09  8:16     ` Petr Mladek
  1 sibling, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08 18:53 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree

On Wed, Jul 08, 2026 at 08:59:26AM +0100, Lorenzo Stoakes wrote:
> On Wed, Jul 08, 2026 at 11:02:00AM +0530, Mukesh Ojha wrote:
> > Annotate vital static, dynamic information into meminspect for debugging
> >
> > Static:
> >  - prb_descs
> >  - prb_infos
> >  - prb
> >  - prb_data
> >  - clear_seq
> >  - printk_rb_static
> >  - printk_rb_dynamic
> >
> > Dynamic:
> >  - new_descs
> >  - new_infos
> >  - new_log_buf
> >
> > meminspect uses a different API to annotate variables for inspection,
> > and information about these variables is stored in the inspection table.
> 
> This commit message is a mess again. You're writing what the code does, not why,
> you mention separate API but not which or why.
> 
> It's useless basically, and it's weird to list arbitrary fields like this.
> 
> Always think 'what would be useful to reviewers and people coming back to this
> patch in debug/development'.
> 
> If it just says what the code says it's useless. Put what's NOT there.

Ack., will reword this.

> 
> >
> > Reviewed-by: Petr Mladek <pmladek@suse.com>
> > Co-developed-by: Eugen Hristev <eugen.hristev@linaro.org>
> > Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
> > Reviewed-by: John Ogness <john.ogness@linutronix.de>
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> >  kernel/printk/printk.c | 12 ++++++++++++
> >  1 file changed, 12 insertions(+)
> >
> > diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> > index 2fe9a963c823..f7f32c09b9b8 100644
> > --- a/kernel/printk/printk.c
> > +++ b/kernel/printk/printk.c
> > @@ -49,6 +49,7 @@
> >  #include <linux/sched/debug.h>
> >  #include <linux/sched/task_stack.h>
> >  #include <linux/panic.h>
> > +#include <linux/meminspect.h>
> >
> >  #include <linux/uaccess.h>
> >  #include <asm/sections.h>
> > @@ -518,10 +519,17 @@ static u32 log_buf_len = __LOG_BUF_LEN;
> >  #endif
> >  _DEFINE_PRINTKRB(printk_rb_static, CONFIG_LOG_BUF_SHIFT - PRB_AVGBITS,
> >  		 PRB_AVGBITS, &__log_buf[0]);
> > +MEMINSPECT_NAMED_ENTRY(prb_descs, _printk_rb_static_descs);
> > +MEMINSPECT_NAMED_ENTRY(prb_infos, _printk_rb_static_infos);
> > +MEMINSPECT_NAMED_ENTRY(prb_data, __log_buf);
> > +MEMINSPECT_SIMPLE_ENTRY(printk_rb_static);
> >
> >  static struct printk_ringbuffer printk_rb_dynamic;
> > +MEMINSPECT_SIMPLE_ENTRY(printk_rb_dynamic);
> >
> >  struct printk_ringbuffer *prb = &printk_rb_static;
> > +MEMINSPECT_SIMPLE_ENTRY(prb);
> > +MEMINSPECT_SIMPLE_ENTRY(clear_seq);
> >
> >  /*
> >   * We cannot access per-CPU data (e.g. per-CPU flush irq_work) before
> > @@ -1238,6 +1246,10 @@ void __init setup_log_buf(int early)
> >
> >  	local_irq_restore(flags);
> >
> > +	meminspect_lock_register_va(new_log_buf, new_log_buf_len);
> > +	meminspect_lock_register_va(new_descs, new_descs_size);
> > +	meminspect_lock_register_va(new_infos, new_infos_size);
> > +
> >  	/*
> >  	 * Copy any remaining messages that might have appeared from
> >  	 * NMI context after copying but before switching to the
> >
> > --
> > 2.53.0
> >
> 
> Overall exposing live dynamic printk information to drivers seems unwise, but
> not quite as insane as some of the other stuff thus exposed...

Thanks, this is minimal information needed to collect dmesg from
crash-utility in --minimal mode.

> 
> Thanks, Lorenzo

-- 
-Mukesh Ojha

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 11/26] mm/swapfile: Annotate static information into meminspect
  2026-07-08  7:47   ` Lorenzo Stoakes
@ 2026-07-08 19:05     ` Mukesh Ojha
  2026-07-09 14:53       ` Lorenzo Stoakes
  0 siblings, 1 reply; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-08 19:05 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree

On Wed, Jul 08, 2026 at 08:47:51AM +0100, Lorenzo Stoakes wrote:
> On Wed, Jul 08, 2026 at 11:01:50AM +0530, Mukesh Ojha wrote:
> > From: Eugen Hristev <ehristev@kernel.org>
> >
> > Annotate vital static information into inspection table:
> >  - nr_swapfiles
> >
> > Information on these variables is stored in a dedicated meminspect
> > section.
> >
> > Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > ---
> >  mm/swapfile.c | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/mm/swapfile.c b/mm/swapfile.c
> > index a602e5820513..d480727e4987 100644
> > --- a/mm/swapfile.c
> > +++ b/mm/swapfile.c
> > @@ -42,6 +42,7 @@
> >  #include <linux/suspend.h>
> >  #include <linux/zswap.h>
> >  #include <linux/plist.h>
> > +#include <linux/meminspect.h>
> >
> >  #include <asm/tlbflush.h>
> >  #include <linux/leafops.h>
> > @@ -65,6 +66,7 @@ static void move_cluster(struct swap_info_struct *si,
> >   */
> >  static DEFINE_SPINLOCK(swap_lock);
> >  static unsigned int nr_swapfiles;
> > +MEMINSPECT_SIMPLE_ENTRY(nr_swapfiles);
> 
> Now the EXPORT_SYMBOL_GPL() is an EXPORT_SYMBOL() in effect no?

The whole reason we had to tag most of the MM symbols is that
the crash tool looks for this information while launching itself.

e.g.,

./crash --no_modules --no_panic --no_kmem_cache --zero_excluded ./vmlinux  ./minidump.elf


> 
> >  atomic_long_t nr_swap_pages;
> >  /*
> >   * Some modules use swappable objects and may try to swap them out under
> >
> > --
> > 2.53.0
> >

-- 
-Mukesh Ojha

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 21/26] printk: Register information into meminspect
  2026-07-08  7:59   ` Lorenzo Stoakes
  2026-07-08 18:53     ` Mukesh Ojha
@ 2026-07-09  8:16     ` Petr Mladek
  1 sibling, 0 replies; 46+ messages in thread
From: Petr Mladek @ 2026-07-09  8:16 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: Mukesh Ojha, Jonathan Corbet, Shuah Khan, Eugen Hristev,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, John Ogness,
	Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan, workflows, linux-doc, linux-kernel, linux-arch,
	linux-mm, linux-arm-msm, linux-remoteproc, devicetree

On Wed 2026-07-08 08:59:26, Lorenzo Stoakes wrote:
> On Wed, Jul 08, 2026 at 11:02:00AM +0530, Mukesh Ojha wrote:
> > Annotate vital static, dynamic information into meminspect for debugging
> >
> > Static:
> >  - prb_descs
> >  - prb_infos
> >  - prb
> >  - prb_data
> >  - clear_seq
> >  - printk_rb_static
> >  - printk_rb_dynamic
> >
> > Dynamic:
> >  - new_descs
> >  - new_infos
> >  - new_log_buf
> >
> > --- a/kernel/printk/printk.c
> > +++ b/kernel/printk/printk.c
> > @@ -49,6 +49,7 @@
> >  #include <linux/sched/debug.h>
> >  #include <linux/sched/task_stack.h>
> >  #include <linux/panic.h>
> > +#include <linux/meminspect.h>
> >
> >  #include <linux/uaccess.h>
> >  #include <asm/sections.h>
> > @@ -518,10 +519,17 @@ static u32 log_buf_len = __LOG_BUF_LEN;
> >  #endif
> >  _DEFINE_PRINTKRB(printk_rb_static, CONFIG_LOG_BUF_SHIFT - PRB_AVGBITS,
> >  		 PRB_AVGBITS, &__log_buf[0]);
> > +MEMINSPECT_NAMED_ENTRY(prb_descs, _printk_rb_static_descs);
> > +MEMINSPECT_NAMED_ENTRY(prb_infos, _printk_rb_static_infos);
> > +MEMINSPECT_NAMED_ENTRY(prb_data, __log_buf);
> > +MEMINSPECT_SIMPLE_ENTRY(printk_rb_static);
> >
> >  static struct printk_ringbuffer printk_rb_dynamic;
> > +MEMINSPECT_SIMPLE_ENTRY(printk_rb_dynamic);
> >
> >  struct printk_ringbuffer *prb = &printk_rb_static;
> > +MEMINSPECT_SIMPLE_ENTRY(prb);
> > +MEMINSPECT_SIMPLE_ENTRY(clear_seq);
> >
> >  /*
> >   * We cannot access per-CPU data (e.g. per-CPU flush irq_work) before
> > @@ -1238,6 +1246,10 @@ void __init setup_log_buf(int early)
> >
> >  	local_irq_restore(flags);
> >
> > +	meminspect_lock_register_va(new_log_buf, new_log_buf_len);
> > +	meminspect_lock_register_va(new_descs, new_descs_size);
> > +	meminspect_lock_register_va(new_infos, new_infos_size);
> > +
> >  	/*
> >  	 * Copy any remaining messages that might have appeared from
> >  	 * NMI context after copying but before switching to the
> 
> Overall exposing live dynamic printk information to drivers seems unwise, but
> not quite as insane as some of the other stuff thus exposed...

I agree that we should be careful with exporting symbols.

Well, if I get it correctly then at least the printk-related symbols
are already exported a similar way using vmcore_info.h API,
see log_buf_vmcoreinfo_setup().

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 26/26] meminspect: Add debug kinfo compatible driver
  2026-07-08  7:08 ` [PATCH v3 26/26] meminspect: Add debug kinfo compatible driver Mukesh Ojha
  2026-07-08  8:06   ` Lorenzo Stoakes
@ 2026-07-09 13:24   ` Petr Pavlu
  1 sibling, 0 replies; 46+ messages in thread
From: Petr Pavlu @ 2026-07-09 13:24 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: akpm, anna-maria, arnd, andersson, chrisl, cl, conor+dt, david,
	dennis, devicetree, ehristev, frederic, mingo, jstultz, corbet,
	juri.lelli, kasong, kees, konradybcio, krzk+dt, linux-arch,
	linux-arm-msm, linux-doc, linux-kernel, linux-mm,
	linux-remoteproc, mathieu.poirier, peterz, pmladek, robh,
	saravanak, tj, tglx, vincent.guittot, workflows, atomlin, ast,
	aliceryhl, linux.amoon, ardb, baoquan.he, baohua, bsegall,
	jackmanb, leitao, brauner, coxu, dietmar.eggemann, dianders,
	ebiggers, feng.tang, yangfeng, gary, guohanjun, jack,
	wangjinchao600, joel.granados, hannes, john.ogness, jpoimboe,
	shikemeng, kas, kprateek.nayak, liam, ljs, elver, mgorman, mhocko,
	ojeda, rppt, namcao, nathan, nphamcs, n.schier, pasha.tatashin,
	pnina.feder, rdunlap, rioo.tsukatsukii, senozhatsky, skhan, sboyd,
	rostedt, surenb, thomas.weissschuh, vschneid, vbabka,
	youngjun.park, zhengyejian, ziy, Eugen Hristev

On 7/8/26 9:08 AM, Mukesh Ojha wrote:
> From: Eugen Hristev <eugen.hristev@linaro.org>
> 
> With this driver, the registered regions are copied to a shared memory
> zone at register time. The shared memory zone is supplied via OF. This
> driver will select only regions that are of interest, and keep only
> addresses. The format of the list is Kinfo compatible, with devices like
> Google Pixel phone. The firmware is only interested in some symbols'
> addresses.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---
[...]
> diff --git a/kernel/meminspect/kinfo.c b/kernel/meminspect/kinfo.c
> new file mode 100644
> index 000000000000..7451c13bc316
> --- /dev/null
> +++ b/kernel/meminspect/kinfo.c
> @@ -0,0 +1,257 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + *
> + * Copyright 2002 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
> + * Copyright 2021 Google LLC
> + * Copyright 2025 Linaro Ltd. Eugen Hristev <eugen.hristev@linaro.org>
> + */
> +#include <linux/container_of.h>
> +#include <linux/kallsyms.h>
> +#include <linux/meminspect.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_reserved_mem.h>
> +#include <linux/platform_device.h>
> +#include <linux/utsname.h>
> +
> +#define BUILD_INFO_LEN		256
> +#define DEBUG_KINFO_MAGIC	0xcceeddff
> +
> +/*
> + * Header structure must be byte-packed, since the table is provided to
> + * bootloader.
> + */
> +struct kernel_info {
> +	/* For kallsyms */
> +	u8 enabled_all;
> +	u8 enabled_base_relative;
> +	u8 enabled_absolute_percpu;
> +	u8 enabled_cfi_clang;
> +	u32 num_syms;
> +	u16 name_len;
> +	u16 bit_per_long;
> +	u16 module_name_len;
> +	u16 symbol_len;
> +	u64 _relative_pa;
> +	u64 _text_pa;
> +	u64 _stext_pa;
> +	u64 _etext_pa;
> +	u64 _sinittext_pa;
> +	u64 _einittext_pa;
> +	u64 _end_pa;
> +	u64 _offsets_pa;
> +	u64 _names_pa;
> +	u64 _token_table_pa;
> +	u64 _token_index_pa;
> +	u64 _markers_pa;
> +	u64 _seqs_of_names_pa;
> +
> +	/* For frame pointer */
> +	u32 thread_size;
> +
> +	/* For virt_to_phys */
> +	u64 swapper_pg_dir_pa;
> +
> +	/* For linux banner */
> +	u8 last_uts_release[__NEW_UTS_LEN];
> +
> +	/* For module kallsyms */
> +	u32 enabled_modules_tree_lookup;
> +	u32 mod_mem_offset;
> +	u32 mod_kallsyms_offset;
> +} __packed;

Is this kinfo format documented anywhere? I was only able to find
a reference to the equivalent downstream Android driver [1] in the cover
letter. However, I don't quite understand what it is or what the
associated bootloader component does with this information. In
particular, I'm unclear about the purpose of the following
module-related fields:

module_name_len
enabled_modules_tree_lookup
mod_mem_offset
mod_kallsyms_offset

These appear to be exposed for reading the internals of the module
loader. Be aware that this data is not stable.

[1] https://android.googlesource.com/kernel/common/+/refs/heads/android-mainline/drivers/android/debug_kinfo.c

-- 
Thanks,
Petr

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 11/26] mm/swapfile: Annotate static information into meminspect
  2026-07-08 19:05     ` Mukesh Ojha
@ 2026-07-09 14:53       ` Lorenzo Stoakes
  2026-07-10  4:09         ` Christoph Hellwig
  0 siblings, 1 reply; 46+ messages in thread
From: Lorenzo Stoakes @ 2026-07-09 14:53 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree

On Thu, Jul 09, 2026 at 12:35:35AM +0530, Mukesh Ojha wrote:
> On Wed, Jul 08, 2026 at 08:47:51AM +0100, Lorenzo Stoakes wrote:
> > On Wed, Jul 08, 2026 at 11:01:50AM +0530, Mukesh Ojha wrote:
> > > From: Eugen Hristev <ehristev@kernel.org>
> > >
> > > Annotate vital static information into inspection table:
> > >  - nr_swapfiles
> > >
> > > Information on these variables is stored in a dedicated meminspect
> > > section.
> > >
> > > Signed-off-by: Eugen Hristev <eugen.hristev@linaro.org>
> > > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > > ---
> > >  mm/swapfile.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > >
> > > diff --git a/mm/swapfile.c b/mm/swapfile.c
> > > index a602e5820513..d480727e4987 100644
> > > --- a/mm/swapfile.c
> > > +++ b/mm/swapfile.c
> > > @@ -42,6 +42,7 @@
> > >  #include <linux/suspend.h>
> > >  #include <linux/zswap.h>
> > >  #include <linux/plist.h>
> > > +#include <linux/meminspect.h>
> > >
> > >  #include <asm/tlbflush.h>
> > >  #include <linux/leafops.h>
> > > @@ -65,6 +66,7 @@ static void move_cluster(struct swap_info_struct *si,
> > >   */
> > >  static DEFINE_SPINLOCK(swap_lock);
> > >  static unsigned int nr_swapfiles;
> > > +MEMINSPECT_SIMPLE_ENTRY(nr_swapfiles);
> >
> > Now the EXPORT_SYMBOL_GPL() is an EXPORT_SYMBOL() in effect no?
>
> The whole reason we had to tag most of the MM symbols is that
> the crash tool looks for this information while launching itself.

You're missing the point.

EXPORT_SYMBOL_GPL() != EXPORT_SYMBOL().

We cannot and will not allow symbols that are GPL-only to be exported by the
back door to non-GPL modules.

Meminspect seems to ignore all of this and just exports symbols another way
overriding kernel mechanisms which is just not acceptable...

I also don't really understand what you're saying here either, what has what
crash looks up on startup got to do with anything?

>
> e.g.,
>
> ./crash --no_modules --no_panic --no_kmem_cache --zero_excluded ./vmlinux  ./minidump.elf
>
>
> >
> > >  atomic_long_t nr_swap_pages;
> > >  /*
> > >   * Some modules use swappable objects and may try to swap them out under
> > >
> > > --
> > > 2.53.0
> > >
>
> --
> -Mukesh Ojha

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 00/26] Introduce meminspect
  2026-07-08  8:18   ` Lorenzo Stoakes
@ 2026-07-09 20:42     ` Mukesh Ojha
  0 siblings, 0 replies; 46+ messages in thread
From: Mukesh Ojha @ 2026-07-09 20:42 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Liam R. Howlett,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree,
	Jason Gunthorpe

On Wed, Jul 08, 2026 at 09:18:36AM +0100, Lorenzo Stoakes wrote:
> Having had a look through, thoughts:
> 
> I'm very concerned that this (whether intended or not) is a work around for
> drivers to get access to symbols that are not exported.
> 
> In many cases you are adding meminspect instrumentation for stuff that's already
> exported (fine). In some cases it's stuff that's only GPL-exported (not fine),
> and in some cases you are exporting totally unexpected symbols (very very very
> not fine).
> 
> A driver that hooks on to meminspect then gets the PA and VA for these and can
> access these symbols as far as I can tell.
> 
> On that basis I really question the whole approach. It feels like you want to
> have essentially richer symbol information here, so the approach should perhaps
> be built on the existing mechanism for symbols rather than arbitrarily +
> invasively stuck into core kernel logic?

Lorenzo, thank you for the thorough review. You raise a number of
valid points and I do not disagree.

Quoting the lines from our LPC 2023 presentation of Minidump
which is exact problem we are trying to address.
https://lpc.events/event/17/contributions/1468/

"Devices in engineering mode frequently provide a mechanism for
generating full system DDR dump. However, for end user devices, it is
not feasible to capture the entire DDR content and transfer them
electronically. Now a days, typical size of DDR on a premium tier
phones is 12 GB and growing, so the problem is going to be
worse."

The reason for using a physical address is to get the content
directly from where it is present, and not rely on a pstore kind
of mechanism where data gets streamed or written to a RAM
backend, which may not even get a chance to run for non-kernel
crashes, or in some hung state of the device where a watchdog
bite triggers crash dump collection.

So, if we tell the firmware upfront where some good debug regions
are located — like printk data and its metadata, or even ftrace
and its content — we could retrieve dmesg and ftrace even for
non-kernel crashes or hung states. This could be more helpful for
production devices where existing mechanisms for various reasons
are not feasible.

> 
> I am also concerned that you're not accounting for memory lifecycle or things
> like memory hotplug - you seem to just store PAs/VAs with assumption that the
> ranges remain eternally mapped at the same ranges for both.
> 
> This is a concern because you also track dynamic ranges, and drivers might
> register stuff they allocate this way, and it all seems like an easy way to get
> UAF's.

I agree, it may not be considering memory hotplug scenario.

> 
> I may have missed something here and happy to be corrected, though.
> 
> In general the series is far from being in upstreamable shape - you send a giant
> 1st patch which lumps together a whole bunch of stuff, then you send dozens of
> 2-5 line patches, and finally include some qualcomm driver specific stuff for
> good measure.
> 
> The commit messages are generally awful and give little to no information, the
> cover letter is deeply uncompelling and doesn't make the case for the feature at
> all.

I am very sorry for this. I can really improve the commit
messages and the cover letter. It should discuss the problem
first, why the existing solution does not address it, and why
this approach was chosen, but until now nobody has complained
about it. This series has a very long history from
minidump->kmemdump->meminspect and it may have lost the core
detail along the way, but we can really improve this.

> 
> You make zero comments about key concerns with regards to stability, robustness,
> security. There's no testing logic anywhere, and you even include a plea for
> testing in the cover letter.

We did not see the driver getting PA/VA as a concern, but I see
your point.

The plea for testing was only for the debug_kinfo driver, which
we don't usually own in its downstream. Eugene, in discussion
with others, found there could be another potential users of
meminspect, and hence he converted it to use meminspect and
hence, the plea for testing only the debug_kinfo driver but
Qualcomm minidump driver tested with meminspect.


> This is very much RFC stuff and I continue to not understand why you've taken
> the RFC label off here.

You are right to question it given the volume of your open
concerns; removing the RFC label was premature. Eugene has even
presented this to the MM maintainer at some meeting, which I did
not attend, where he got a nod from David that this should be
taken out of RFC.

> 
> And it all very much smacks of trying to solve an internal problem you've
> encountered downstream by changing the core of the kernel, rather than you
> sending a generally useful feature.

It may look like a downstream problem, but it is a problem to
debug an end user's phone, and it may need more but minimal data
for debugging an end user phone crash. Hence, we needed something
in the core which could be used by others as well.

> 
> You need to address all of this and re-RFC the series. It instinctively feels
> like trying to solve the problem in the wrong place, but in any case it would be
> better to start with a SMALLER version of this first then look to extend it only
> if the community supports it.

Surely, it should be better to start with smaller but useful
information which could be capturing dmesg in any kind of crash,
and for that I need at least the PA/VA for printk data and its
metadata, if it is allowed. Hope this gives an idea of what we
are solving.


-Mukesh
> 
> Thanks, Lorenzo
> 
> On Wed, Jul 08, 2026 at 08:11:52AM +0100, Lorenzo Stoakes wrote:
> > +cc Jason as maybe he has thoughts on this...
> >
> > Overall - for this to be sensibly mainlined, we need to see a. a COMPELLING case
> > made for this feature, b. some buy-in from others, and c. have confidence this
> > will be properly maintained.
> >
> > I don't feel you've demonstrated any of these.
> >
> > And looking through the history of this (you've made it really hard with your
> > changelog):
> >
> >     v2 - https://lore.kernel.org/lkml/20260311-minidump-v2-v2-0-f91cedc6f99e@oss.qualcomm.com/
> >     v1 - https://lore.kernel.org/lkml/20251119154427.1033475-1-eugen.hristev@linaro.org/
> > RFC v3 - (I literally can't find it...?)
> > RFC v2 - https://lore.kernel.org/all/20250724135512.518487-1-eugen.hristev@linaro.org/
> > RFC v1 - https://lore.kernel.org/lkml/20250422113156.575971-1-eugen.hristev@linaro.org/
> >
> > I'm struggling to understand why on earth it came out of RFC?
> >
> > You really shouldn't drop the RFC tag unless you've got CLEAR signal that the
> > community wants the feature and that there's buy-in.
> >
> > Instead you've got some specific technical feedback, some trivia, etc. which
> > warrants RFC respins, but nothing to suggest buy-in.
> >
> > So please attach the RFC tag to any future respins. And I suggest you make the
> > case for this a LOT clearer and seek to engage with others to confirm that there
> > is anybody else who wants this.
> >
> > On Wed, Jul 08, 2026 at 11:01:39AM +0530, Mukesh Ojha wrote:
> > > First of all, I want to thank Eugene for his excellent work on this
> > > series. What began as the Qualcomm Minidump driver from me has now
> > > evolved into meminspect. He also presented meminspect at Linux
> > > Plumbers 2025.
> > >
> > > Video of the recording is available here for anyone interested:
> > > https://www.youtube.com/watch?v=aDZv4-kOLSc
> >
> > It's iffy putting links like this in a commit message that'll end up as a commit
> > (in mm we put the cover letter in). Links can die. Companies can change their
> > minds about videos being available.
> >
> > Maybe better as something explicitly after the commit message.
> >
> > >
> > > Introduction: Memory inspection mechanism
> > >
> > > meminspect is a mechanism which allows the kernel to mark specific
> > > memory areas for memory dumping or specific inspection, statistics,
> > > usage.  Once regions are marked, meminspect keeps an internal list with
> > > the regions in a dedicated table.  Further, these regions can be
> > > accessed using specific API by any interested driver.  Regions being
> > > marked beforehand, when the system is up and running, there is no need
> > > nor dependency on a panic handler, or a working kernel that can dump the
> > > debug information.  meminspect can be primarily used for debugging. The
> > > approach is feasible to work when pstore, kdump, or another mechanism do
> > > not. Pstore relies on persistent storage, a dedicated RAM area or
> > > flash, which has the disadvantage of having the memory reserved all the
> > > time, or another specific non volatile memory. Some devices cannot keep
> > > the RAM contents on reboot so ramoops does not work. Some devices do not
> > > allow kexec to run another kernel to debug the crashed one.  For such
> > > devices, that have another mechanism to help debugging, like firmware,
> > > meminspect is a viable solution.
> >
> > Please use paragraphs, this is an unreadable wall of text and it just seems
> > to be noise.
> >
> > Why would we want to mark specific areas a special way? What are the
> > trade-offs, what does that actually do? How do you interact with it? Why
> > can't other approaches be used?
> >
> > You should make it CLEAR what exactly the benefits are and why this is
> > better than alternatives.
> >
> > >
> > > meminspect can create a core image, similar with /proc/vmcore, with only
> > > the registered regions included. This can be loaded into crash tool/gdb
> > > and analyzed. This happens if CRASH_DUMP=y.  To have this working,
> >
> > What is CRASH_DUMP? Where is it defined? You mean CONFIG_CRASH_DUMP?
> >
> > > specific information from the kernel is registered, and this is done at
> > > meminspect init time, no need for the meminspect users to do anything.
> >
> > Again this just doesn't really mean anything to me?
> >
> > >
> > > This version of the meminspect patch series includes two drivers that
> > > make use of it: one is the Qualcomm Minidump, and the other one is the
> > > Debug Kinfo backend for Android devices, reworked from this source here:
> > > https://android.googlesource.com/kernel/common/+/refs/heads/android-mainline/drivers/android/debug_kinfo.c
> > > written originally by Jone Chou <jonechou@google.com>
> >
> > This feels rather like you've taken a specific use case you have, and
> > worked backwards from it to changes to core, honestly.
> >
> > >
> > > Tested on Qualcomm SA8775P (Lemans EVK) on next-20260707 with the
> > > minidump backend: kernel crash dump regions correctly captured
> > > via firmware.
> >
> > What is a minidump backend? There's no detail about the testing here
> > either. Does anybody outside of Qualcomm care about this?
> >
> > >
> > > This series introduces a new cross-subsystem framework and, to
> > > avoid merge ordering issues, I suggest the entire series be taken
> > > via the mm tree. Subsystem maintainers for touched files have
> > > been CC'd; I request an Acked-by from them if the respective
> > > patches look fine from their side.
> >
> > Don't put stuff about mechanics of merge in the middle of a cover letter
> > that will go into the git log, put this and the stuff about the video in a
> > block of text below the main text, you can tag it 'REVIEWERS NOTES' or
> > similar.
> >
> > Not only A-b for touched files, but as this is ostensibly an mm feature
> > you'll need tags from mm maintainers and acceptance of the feature overall
> > for it to be accepted.
> >
> > >
> > > Alternatively, the qcom backend patches (22-24) can be deferred
> > > to Bjorn's qcom tree in a follow-on series once the core
> > > meminspect framework lands.
> >
> > I think that would be better yes, you shouldn't be adding new driver
> > changes in a core series like this, only touching stuff you have to touch
> > as a result of the core change.
> >
> > Anything else should be saved for later series. You can express ordering
> > requirements in the cover letter...
> >
> > >
> > > *** How to use meminspect with minidump backend on Qualcomm platform guide ***
> >
> > Odd to put a specific qualcomm TODO in a cover letter for a mainline
> > feature...
> >
> > Again this makes it feels like this is something you want for your driver,
> > and the core changes are just a means of getting there, which is not an
> > acceptable justification for core changes.
> >
> > You have to rework this entire cover letter to sell it as a GENERAL
> > feature.
> >
> > I'm really not convinced we want to give drivers (which are great at doing
> > exactly the wrong thing with mm APIs) the ability to do invasive things in
> > mm.
> >
> > >
> > > Prerequisites:
> > > Crash tool compiled with target=ARM64.
> > >
> > > Target kernel must be built with: CONFIG_DEBUG_INFO_REDUCED=n;
> > > this will have vmlinux include all the debugging information
> > > needed for the crash tool and CONFIG_MEMINSPECT,
> > > CONFIG_CRASH_DUMP, and the driver CONFIG_QCOM_MINIDUMP.
> > > Kernel arguments: Kernel firmware must be set to mode 'mini' by kernel
> > > module parameter like this : qcom_scm.download_mode=mini
> > >
> > > After the kernel boots and the minidump module is loaded,
> > > everything is ready for a possible crash. Upon triggering a
> > > forced kernel crash, the target board will wait in download mode,
> > > where QDL (https://github.com/linux-msm/qdl) running on the host
> > > connected to the target (here, Lemans EVK) can be used to collect
> > > minidump.elf from the target device onto the host.
> > >
> > > Currently, --minimal mode is being used to get dmesg log from
> > > crashed device.
> > >
> > > Without --minimal mode, the crash tool needs to be patched to
> > > not crash on missing symbols and needs to be tuned, which I am
> > > currently working on in parallel.
> > >
> > > crash> log
> > > [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x514f0014]
> > > [    0.000000] Linux version 7.0.0-rc3-next-20260309-00028-g528b3c656121 (@21e3bca4168f) (aarch64-linux-gnu-gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #5 SMP PREEMPT Tue Mar 10 18:18:41 UTC 2026
> > >
> > > *** Debug Kinfo backend driver ***
> > > I need help with the testing of this driver, Anyone who actually wants
> >
> > Err you're putting forward a non-RFC series to mainline and also saying
> > essentially it's untested at least in one respect?
> >
> > This is signal that this should _remain_ RFC.
> >
> > > to test this, feel free to reply to the patch. we have also written a
> > > simple DT binding for the driver.
> > >
> > > Thanks in advance for the review, and apologies if I missed addressing any comment.
> > >
> > > -Mukesh
> > >
> > > Changes in v3: https://lore.kernel.org/lkml/20260311-minidump-v2-v2-0-f91cedc6f99e@oss.qualcomm.com/
> >
> > And again, ->v2 but you label it v3...!
> >
> > > - Addressed most of doc. comments and binding and 0-day kernel
> > >   test robot warning.
> > > - Add timekeeping: Register tk_data into meminspect
> > > - fixed some of the bugs identified during testing.
> > > - Fix missing return before dev_err_probe() in qcom_md_probe(); all
> > >   three error paths (SMEM lookup, table validation, table init) now
> > >   correctly abort probe on failure
> > > - Fix meminspect_traverse() kernel-doc: @priv description corrected
> > > - Fix meminspect.rst: replace stale MEMINSPECT_ITERATOR_CB type name
> > >   with the actual meminspect_iter_cb_t typedef
> > > - Add kernel-doc for meminspect_iter_cb_t typedef
> > > - Lot of code formating and style change as per coding standard.
> > >
> > > Changes in v2: https://lore.kernel.org/lkml/20251119154427.1033475-1-eugen.hristev@linaro.org/
> >
> > The link is to v1... what a mess!
> >
> > >  - Fixed doc warnings
> > >  - Fixed kernel-test robot warnings.
> > >  - Took Mike suggestion to remove mark inspect flag for dynamic memory.
> > >  - Added R-b for printk patch.
> > >  - Modified some commit messages for clarity.
> > >  - corrected binding change for debug-kinfo as per Rob suggestion.
> > >
> > > Changelog for meminspect v1:
> >
> > You don't include a link to RFC v3 at all?
> >
> > > - rename to meminspect
> > > - start on top of v2 actually, with the section and all.
> > > - remove the backend thing, change the API to access the table
> > > - move everything to kernel/
> > > - add dependency to CRASH_DUMP instead of a separate knob
> > > - move the minidump driver to soc/qcom
> > > - integrate the meminspect better into memblock by using a new memblock flag
> > > - minor fixes : use dev_err_probe everywhere, rearrange variable declarations,
> > > remove some useless code, etc.
> > >
> > > Changelog for RFC v3:
> > > - V2 available here : https://lore.kernel.org/all/20250724135512.518487-1-eugen.hristev@linaro.org/
> >
> > Same comment as below. Put links for changelogs with the version you're changing
> > it's a total nightmare trying to follow this.
> >
> > And I literally cannot find RFC v3 on list, did you mislabel it?
> >
> > > - Removed the .section as requested by David Hildenbrand.
> > > - Moved all kmemdump registration(when possible) to vmcoreinfo.
> > > - Because of this, some of the variables that I was registering had to be non-static
> > > so I had to modify this as per David Hildenbrand suggestion.
> > > - Fixed minor things in the Kinfo driver: one field was broken, fixed some
> > > compiler warnings, fixed the copyright and remove some useless includes.
> > > - Moved the whole kmemdump from drivers/debug into mm/ and Kconfigs into mm/Kconfig.debug
> > > and it's now available in kernel hacking, as per Randy Dunlap review
> > > - Reworked some of the Documentation as per review from Jon Corbet
> > >
> > > Changelog for RFC v2:
> > > - V1 available here: https://lore.kernel.org/lkml/20250422113156.575971-1-eugen.hristev@linaro.org/
> >
> > Why are you linking the previous version here, it's strange.
> >
> > Just put RFC v1: with the link below, same goes for other cases.
> >
> > > - Reworked the whole minidump implementation based on suggestions from Thomas Gleixner.
> > > This means new API, macros, new way to store the regions inside kmemdump
> > > (ditched the IDR, moved to static allocation, have a static default backend, etc)
> > > - Reworked qcom_minidump driver based on review from Bjorn Andersson
> > > - Reworked printk log buffer registration based on review from Petr Mladek.
> > >
> > > ---
> > > Eugen Hristev (21):
> > >       kernel: Introduce meminspect
> > >       init/version: Annotate static information into meminspect
> > >       mm/percpu: Annotate static information into meminspect
> > >       cpu: Annotate static information into meminspect
> > >       genirq/irqdesc: Annotate static information into meminspect
> > >       timers: Annotate static information into meminspect
> > >       kernel/fork: Annotate static information into meminspect
> > >       mm/page_alloc: Annotate static information into meminspect
> > >       mm/show_mem: Annotate static information into meminspect
> > >       mm/swapfile: Annotate static information into meminspect
> > >       kernel/vmcore_info: Register dynamic information into meminspect
> > >       kernel/configs: Register dynamic information into meminspect
> > >       mm/init-mm: Annotate static information into meminspect
> > >       panic: Annotate static information into meminspect
> > >       kallsyms: Annotate static information into meminspect
> > >       mm/mm_init: Annotate static information into meminspect
> > >       sched/core: Annotate runqueues into meminspect
> > >       remoteproc: qcom: Move minidump data structures into its own header
> > >       soc: qcom: Add minidump backend driver
> > >       soc: qcom: smem: Add minidump platform device
> > >       meminspect: Add debug kinfo compatible driver
> > >
> > > Mukesh Ojha (5):
> > >       timekeeping: Register tk_data into meminspect
> > >       mm/numa: Register node data information into meminspect
> > >       mm/sparse: Register information into meminspect
> > >       printk: Register information into meminspect
> > >       dt-bindings: reserved-memory: Add Google Kinfo Pixel reserved memory
> > >
> > >  Documentation/dev-tools/index.rst                  |   1 +
> > >  Documentation/dev-tools/meminspect.rst             | 144 +++++++
> > >  .../reserved-memory/google,debug-kinfo.yaml        |  48 +++
> > >  MAINTAINERS                                        |  16 +
> > >  drivers/of/platform.c                              |   1 +
> > >  drivers/remoteproc/qcom_common.c                   |  55 +--
> > >  drivers/soc/qcom/Kconfig                           |  13 +
> > >  drivers/soc/qcom/Makefile                          |   1 +
> > >  drivers/soc/qcom/minidump.c                        | 271 ++++++++++++
> > >  drivers/soc/qcom/smem.c                            |  10 +
> >
> > Yeah I hate that you're adding a wholy unrelated driver feature as part of this.
> >
> > Let's not.
> >
> > >  include/asm-generic/vmlinux.lds.h                  |  13 +
> > >  include/linux/meminspect.h                         | 271 ++++++++++++
> > >  include/linux/soc/qcom/minidump.h                  |  70 +++
> > >  init/Kconfig                                       |   1 +
> > >  init/version-timestamp.c                           |   3 +
> > >  init/version.c                                     |   3 +
> > >  kernel/Makefile                                    |   1 +
> > >  kernel/configs.c                                   |   6 +
> > >  kernel/cpu.c                                       |   5 +
> > >  kernel/fork.c                                      |   3 +
> > >  kernel/irq/irqdesc.c                               |   2 +
> > >  kernel/kallsyms.c                                  |   9 +
> > >  kernel/meminspect/Kconfig                          |  29 ++
> > >  kernel/meminspect/Makefile                         |   4 +
> > >  kernel/meminspect/kinfo.c                          | 257 +++++++++++
> > >  kernel/meminspect/meminspect.c                     | 474 +++++++++++++++++++++
> > >  kernel/panic.c                                     |   4 +
> > >  kernel/printk/printk.c                             |  12 +
> > >  kernel/sched/core.c                                |   2 +
> > >  kernel/time/timekeeping.c                          |   2 +
> > >  kernel/time/timer.c                                |   2 +
> > >  kernel/vmcore_info.c                               |   4 +
> > >  mm/init-mm.c                                       |  12 +
> > >  mm/mm_init.c                                       |   2 +
> > >  mm/numa.c                                          |   2 +
> > >  mm/page_alloc.c                                    |   2 +
> > >  mm/percpu.c                                        |   5 +
> > >  mm/show_mem.c                                      |   2 +
> > >  mm/sparse.c                                        |   3 +
> > >  mm/swapfile.c                                      |   2 +
> > >  40 files changed, 1713 insertions(+), 54 deletions(-)
> > > ---
> > > base-commit: 5c73cd9f0819c1c44e373e3dabb68318b1de1a12
> > > change-id: 20260708-meminspect-v3-76dd8166c4f1
> > >
> > > Best regards,
> > > --
> > > -Mukesh Ojha
> > >
> >
> > Thanks, Lorenzo

-- 
-Mukesh Ojha

^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 00/26] Introduce meminspect
  2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
                   ` (26 preceding siblings ...)
  2026-07-08  7:11 ` [PATCH v3 00/26] Introduce meminspect Lorenzo Stoakes
@ 2026-07-10  1:51 ` Liam R. Howlett
  27 siblings, 0 replies; 46+ messages in thread
From: Liam R. Howlett @ 2026-07-10  1:51 UTC (permalink / raw)
  To: Mukesh Ojha
  Cc: Jonathan Corbet, Shuah Khan, Eugen Hristev, Arnd Bergmann,
	Dennis Zhou, Tejun Heo, Christoph Lameter, Andrew Morton,
	Thomas Gleixner, Peter Zijlstra, Anna-Maria Behnsen,
	Frederic Weisbecker, John Stultz, Stephen Boyd, Kees Cook,
	Ingo Molnar, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
	Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider,
	K Prateek Nayak, David Hildenbrand, Lorenzo Stoakes,
	Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
	Brendan Jackman, Johannes Weiner, Zi Yan, Chris Li, Kairui Song,
	Kemeng Shi, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
	Petr Mladek, John Ogness, Sergey Senozhatsky, Bjorn Andersson,
	Mathieu Poirier, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Saravana Kannan, workflows, linux-doc, linux-kernel,
	linux-arch, linux-mm, linux-arm-msm, linux-remoteproc, devicetree

On 26/07/08 11:01AM, Mukesh Ojha wrote:
> First of all, I want to thank Eugene for his excellent work on this
> series. What began as the Qualcomm Minidump driver from me has now
> evolved into meminspect. He also presented meminspect at Linux
> Plumbers 2025.
> 
> Video of the recording is available here for anyone interested:
> https://www.youtube.com/watch?v=aDZv4-kOLSc
> 
> Introduction: Memory inspection mechanism
> 
> meminspect is a mechanism which allows the kernel to mark specific
> memory areas for memory dumping or specific inspection, statistics,
> usage.  Once regions are marked, meminspect keeps an internal list with
> the regions in a dedicated table.  Further, these regions can be
> accessed using specific API by any interested driver.  Regions being
> marked beforehand, when the system is up and running, there is no need
> nor dependency on a panic handler, or a working kernel that can dump the
> debug information.  meminspect can be primarily used for debugging. The
> approach is feasible to work when pstore, kdump, or another mechanism do
> not. Pstore relies on persistent storage, a dedicated RAM area or
> flash, which has the disadvantage of having the memory reserved all the
> time, or another specific non volatile memory. Some devices cannot keep
> the RAM contents on reboot so ramoops does not work. Some devices do not
> allow kexec to run another kernel to debug the crashed one.  For such
> devices, that have another mechanism to help debugging, like firmware,
> meminspect is a viable solution.
> 
> meminspect can create a core image, similar with /proc/vmcore, with only
> the registered regions included. This can be loaded into crash tool/gdb
> and analyzed. This happens if CRASH_DUMP=y.  To have this working,
> specific information from the kernel is registered, and this is done at
> meminspect init time, no need for the meminspect users to do anything.
> 
> This version of the meminspect patch series includes two drivers that
> make use of it: one is the Qualcomm Minidump, and the other one is the
> Debug Kinfo backend for Android devices, reworked from this source here:
> https://android.googlesource.com/kernel/common/+/refs/heads/android-mainline/drivers/android/debug_kinfo.c
> written originally by Jone Chou <jonechou@google.com>
> 
> Tested on Qualcomm SA8775P (Lemans EVK) on next-20260707 with the
> minidump backend: kernel crash dump regions correctly captured
> via firmware.
> 
> This series introduces a new cross-subsystem framework and, to
> avoid merge ordering issues, I suggest the entire series be taken
> via the mm tree. Subsystem maintainers for touched files have
> been CC'd; I request an Acked-by from them if the respective
> patches look fine from their side.


You are adding a cross-subsystem framework without tests?  How did this
get to v3 without tests?  Surely there were bugs during development and
you added new tests to make sure there wasn't regressions?  Where are
those?

It's a firmware debug framework for qualcomm devices?  Why would we want
to allow such an invasive change in core kernel infrastructure to help
keep firmware blobs big?  It really sounds like the wrong direction all
together.


> 
> Alternatively, the qcom backend patches (22-24) can be deferred
> to Bjorn's qcom tree in a follow-on series once the core
> meminspect framework lands.
> 
> *** How to use meminspect with minidump backend on Qualcomm platform guide ***
> 
> Prerequisites:
> Crash tool compiled with target=ARM64.

What other targets are supported?

> 
> Target kernel must be built with: CONFIG_DEBUG_INFO_REDUCED=n;
> this will have vmlinux include all the debugging information
> needed for the crash tool and CONFIG_MEMINSPECT,
> CONFIG_CRASH_DUMP, and the driver CONFIG_QCOM_MINIDUMP.
> Kernel arguments: Kernel firmware must be set to mode 'mini' by kernel
> module parameter like this : qcom_scm.download_mode=mini
> 
> After the kernel boots and the minidump module is loaded,
> everything is ready for a possible crash. Upon triggering a
> forced kernel crash, the target board will wait in download mode,
> where QDL (https://github.com/linux-msm/qdl) running on the host
> connected to the target (here, Lemans EVK) can be used to collect
> minidump.elf from the target device onto the host.
> 
> Currently, --minimal mode is being used to get dmesg log from
> crashed device.
> 
> Without --minimal mode, the crash tool needs to be patched to
> not crash on missing symbols and needs to be tuned, which I am
> currently working on in parallel.

It sounds like your debug tool needs more development to avoid crashing?

> 
> crash> log
> [    0.000000] Booting Linux on physical CPU 0x0000000000 [0x514f0014]
> [    0.000000] Linux version 7.0.0-rc3-next-20260309-00028-g528b3c656121 (@21e3bca4168f) (aarch64-linux-gnu-gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #5 SMP PREEMPT Tue Mar 10 18:18:41 UTC 2026
> 
> *** Debug Kinfo backend driver ***
> I need help with the testing of this driver, Anyone who actually wants
> to test this, feel free to reply to the patch. we have also written a
> simple DT binding for the driver.
> 
> Thanks in advance for the review, and apologies if I missed addressing any comment.
> 
> -Mukesh
> 
> Changes in v3: https://lore.kernel.org/lkml/20260311-minidump-v2-v2-0-f91cedc6f99e@oss.qualcomm.com/
> - Addressed most of doc. comments and binding and 0-day kernel
>   test robot warning.
> - Add timekeeping: Register tk_data into meminspect
> - fixed some of the bugs identified during testing.
> - Fix missing return before dev_err_probe() in qcom_md_probe(); all
>   three error paths (SMEM lookup, table validation, table init) now
>   correctly abort probe on failure
> - Fix meminspect_traverse() kernel-doc: @priv description corrected
> - Fix meminspect.rst: replace stale MEMINSPECT_ITERATOR_CB type name
>   with the actual meminspect_iter_cb_t typedef
> - Add kernel-doc for meminspect_iter_cb_t typedef
> - Lot of code formating and style change as per coding standard.
> 
> Changes in v2: https://lore.kernel.org/lkml/20251119154427.1033475-1-eugen.hristev@linaro.org/
>  - Fixed doc warnings
>  - Fixed kernel-test robot warnings.
>  - Took Mike suggestion to remove mark inspect flag for dynamic memory.
>  - Added R-b for printk patch.
>  - Modified some commit messages for clarity.
>  - corrected binding change for debug-kinfo as per Rob suggestion.
> 
> Changelog for meminspect v1:
> - rename to meminspect
> - start on top of v2 actually, with the section and all.
> - remove the backend thing, change the API to access the table
> - move everything to kernel/
> - add dependency to CRASH_DUMP instead of a separate knob
> - move the minidump driver to soc/qcom
> - integrate the meminspect better into memblock by using a new memblock flag
> - minor fixes : use dev_err_probe everywhere, rearrange variable declarations,
> remove some useless code, etc.
> 
> Changelog for RFC v3:
> - V2 available here : https://lore.kernel.org/all/20250724135512.518487-1-eugen.hristev@linaro.org/
> - Removed the .section as requested by David Hildenbrand.
> - Moved all kmemdump registration(when possible) to vmcoreinfo.
> - Because of this, some of the variables that I was registering had to be non-static
> so I had to modify this as per David Hildenbrand suggestion.
> - Fixed minor things in the Kinfo driver: one field was broken, fixed some
> compiler warnings, fixed the copyright and remove some useless includes.
> - Moved the whole kmemdump from drivers/debug into mm/ and Kconfigs into mm/Kconfig.debug
> and it's now available in kernel hacking, as per Randy Dunlap review
> - Reworked some of the Documentation as per review from Jon Corbet
> 
> Changelog for RFC v2:
> - V1 available here: https://lore.kernel.org/lkml/20250422113156.575971-1-eugen.hristev@linaro.org/
> - Reworked the whole minidump implementation based on suggestions from Thomas Gleixner.
> This means new API, macros, new way to store the regions inside kmemdump
> (ditched the IDR, moved to static allocation, have a static default backend, etc)
> - Reworked qcom_minidump driver based on review from Bjorn Andersson
> - Reworked printk log buffer registration based on review from Petr Mladek.
> 
> ---
> Eugen Hristev (21):
>       kernel: Introduce meminspect
>       init/version: Annotate static information into meminspect
>       mm/percpu: Annotate static information into meminspect
>       cpu: Annotate static information into meminspect
>       genirq/irqdesc: Annotate static information into meminspect
>       timers: Annotate static information into meminspect
>       kernel/fork: Annotate static information into meminspect
>       mm/page_alloc: Annotate static information into meminspect
>       mm/show_mem: Annotate static information into meminspect
>       mm/swapfile: Annotate static information into meminspect
>       kernel/vmcore_info: Register dynamic information into meminspect
>       kernel/configs: Register dynamic information into meminspect
>       mm/init-mm: Annotate static information into meminspect
>       panic: Annotate static information into meminspect
>       kallsyms: Annotate static information into meminspect
>       mm/mm_init: Annotate static information into meminspect
>       sched/core: Annotate runqueues into meminspect
>       remoteproc: qcom: Move minidump data structures into its own header
>       soc: qcom: Add minidump backend driver
>       soc: qcom: smem: Add minidump platform device
>       meminspect: Add debug kinfo compatible driver
> 
> Mukesh Ojha (5):
>       timekeeping: Register tk_data into meminspect
>       mm/numa: Register node data information into meminspect
>       mm/sparse: Register information into meminspect
>       printk: Register information into meminspect
>       dt-bindings: reserved-memory: Add Google Kinfo Pixel reserved memory
> 
>  Documentation/dev-tools/index.rst                  |   1 +
>  Documentation/dev-tools/meminspect.rst             | 144 +++++++
>  .../reserved-memory/google,debug-kinfo.yaml        |  48 +++

Probably shouldn't be here?

>  MAINTAINERS                                        |  16 +
...

I really think you need to step back and think about how your firmware
and driver can gain information without requiring so many tentacles
across the kernel but also without having an entire dump of ram.  Maybe
your firmware is doing some of what the driver should be doing?

It really seems like you are trying to upstream QA for firmware or
device issues and I don't see an argument against that in any of your
responses to any other emails.

Your problem statement seems to be: a phone freezes and we need our
firmware have global access to all memory to tell us why.  To reduce the
dump size from all of the memory to some subset (up to and including all
of the memory), we want to give our driver access to all of the memory.
Is that correct?

What is even more concerning is that you aren't limiting this to debug,
but also to statistics and usage.  Leaving the door open to larger abuse
of the access this cross-subsystem framework - with no testing - will
allow.

Thanks,
Liam


^ permalink raw reply	[flat|nested] 46+ messages in thread

* Re: [PATCH v3 11/26] mm/swapfile: Annotate static information into meminspect
  2026-07-09 14:53       ` Lorenzo Stoakes
@ 2026-07-10  4:09         ` Christoph Hellwig
  0 siblings, 0 replies; 46+ messages in thread
From: Christoph Hellwig @ 2026-07-10  4:09 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: Mukesh Ojha, Jonathan Corbet, Shuah Khan, Eugen Hristev,
	Arnd Bergmann, Dennis Zhou, Tejun Heo, Christoph Lameter,
	Andrew Morton, Thomas Gleixner, Peter Zijlstra,
	Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
	Stephen Boyd, Kees Cook, Ingo Molnar, Juri Lelli, Vincent Guittot,
	Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
	Valentin Schneider, K Prateek Nayak, David Hildenbrand,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
	Johannes Weiner, Zi Yan, Chris Li, Kairui Song, Kemeng Shi,
	Nhat Pham, Baoquan He, Barry Song, Youngjun Park, Petr Mladek,
	John Ogness, Sergey Senozhatsky, Bjorn Andersson, Mathieu Poirier,
	Konrad Dybcio, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Saravana Kannan, workflows, linux-doc, linux-kernel, linux-arch,
	linux-mm, linux-arm-msm, linux-remoteproc, devicetree

On Thu, Jul 09, 2026 at 03:53:44PM +0100, Lorenzo Stoakes wrote:
> > The whole reason we had to tag most of the MM symbols is that
> > the crash tool looks for this information while launching itself.
> 
> You're missing the point.
> 
> EXPORT_SYMBOL_GPL() != EXPORT_SYMBOL().
> 
> We cannot and will not allow symbols that are GPL-only to be exported by the
> back door to non-GPL modules.
> 
> Meminspect seems to ignore all of this and just exports symbols another way
> overriding kernel mechanisms which is just not acceptable...
> 
> I also don't really understand what you're saying here either, what has what
> crash looks up on startup got to do with anything?

Yeah, random backdoor exports for a totally opaque facility without
good use cases that comes from a known malicious actor like qualcomm is
a no-go.  I don't think anyone should even waste time on this.


^ permalink raw reply	[flat|nested] 46+ messages in thread

end of thread, other threads:[~2026-07-10  4:09 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-08  5:31 [PATCH v3 00/26] Introduce meminspect Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 01/26] kernel: " Mukesh Ojha
2026-07-08  7:38   ` Lorenzo Stoakes
2026-07-08 13:33     ` Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 02/26] init/version: Annotate static information into meminspect Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 03/26] mm/percpu: " Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 04/26] cpu: " Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 05/26] genirq/irqdesc: " Mukesh Ojha
2026-07-08  7:46   ` Lorenzo Stoakes
2026-07-08  5:31 ` [PATCH v3 06/26] timers: " Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 07/26] timekeeping: Register tk_data " Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 08/26] kernel/fork: Annotate static information " Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 09/26] mm/page_alloc: " Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 10/26] mm/show_mem: " Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 11/26] mm/swapfile: " Mukesh Ojha
2026-07-08  7:47   ` Lorenzo Stoakes
2026-07-08 19:05     ` Mukesh Ojha
2026-07-09 14:53       ` Lorenzo Stoakes
2026-07-10  4:09         ` Christoph Hellwig
2026-07-08  5:31 ` [PATCH v3 12/26] kernel/vmcore_info: Register dynamic " Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 13/26] kernel/configs: " Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 14/26] mm/init-mm: Annotate static " Mukesh Ojha
2026-07-08  7:52   ` Lorenzo Stoakes
2026-07-08  5:31 ` [PATCH v3 15/26] panic: " Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 16/26] kallsyms: " Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 17/26] mm/mm_init: " Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 18/26] sched/core: Annotate runqueues " Mukesh Ojha
2026-07-08  5:31 ` [PATCH v3 19/26] mm/numa: Register node data information " Mukesh Ojha
2026-07-08  7:55   ` Lorenzo Stoakes
2026-07-08  5:31 ` [PATCH v3 20/26] mm/sparse: Register " Mukesh Ojha
2026-07-08  5:32 ` [PATCH v3 21/26] printk: " Mukesh Ojha
2026-07-08  7:59   ` Lorenzo Stoakes
2026-07-08 18:53     ` Mukesh Ojha
2026-07-09  8:16     ` Petr Mladek
2026-07-08  5:32 ` [PATCH v3 22/26] remoteproc: qcom: Move minidump data structures into its own header Mukesh Ojha
2026-07-08  5:32 ` [PATCH v3 23/26] soc: qcom: Add minidump backend driver Mukesh Ojha
2026-07-08  5:32 ` [PATCH v3 24/26] soc: qcom: smem: Add minidump platform device Mukesh Ojha
2026-07-08  5:32 ` [PATCH v3 25/26] dt-bindings: reserved-memory: Add Google Kinfo Pixel reserved memory Mukesh Ojha
2026-07-08  7:08 ` [PATCH v3 26/26] meminspect: Add debug kinfo compatible driver Mukesh Ojha
2026-07-08  8:06   ` Lorenzo Stoakes
2026-07-08 18:46     ` Mukesh Ojha
2026-07-09 13:24   ` Petr Pavlu
2026-07-08  7:11 ` [PATCH v3 00/26] Introduce meminspect Lorenzo Stoakes
2026-07-08  8:18   ` Lorenzo Stoakes
2026-07-09 20:42     ` Mukesh Ojha
2026-07-10  1:51 ` Liam R. Howlett

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox