| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/28 01:26 | flow | patch-triage |
2mArgs:null Results: {
"EnableConfigs": [
"ZONE_DEVICE",
"PCI_P2PDMA",
"DAX",
"DEV_DAX",
"FS_DAX",
"MEMORY_HOTPLUG",
"SPARSEMEM_VMEMMAP"
],
"FocusSymbols": [
"memmap_init_zone_device",
"memmap_init_compound",
"zone_device_page_init_from_template",
"zone_device_page_init_slow"
],
"Reasoning": "The patch optimizes the initialization of ZONE_DEVICE pages by using a template and non-temporal memcpy. This is core memory management logic that is reachable when probing devices like PMEM, DAX, or PCI P2PDMA.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/28 01:26 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 1fa30007abaa187f488237d709151800c72ff262\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Tue Jul 28 01:26:42 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h\nindex 4635616863f53d..bc6a9f34b346af 100644\n--- a/arch/x86/include/asm/string_64.h\n+++ b/arch/x86/include/asm/string_64.h\n@@ -82,7 +82,35 @@ int strcmp(const char *cs, const char *ct);\n #ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE\n #define __HAVE_ARCH_MEMCPY_FLUSHCACHE 1\n void __memcpy_flushcache(void *dst, const void *src, size_t cnt);\n-static __always_inline void memcpy_flushcache(void *dst, const void *src, size_t cnt)\n+\n+static __always_inline void movnti_8(void *dst, const void *src)\n+{\n+\tasm volatile(\"movntiq %1, %0\"\n+\t\t : \"=m\"(*(u64 *)dst)\n+\t\t : \"r\"(*(const u64 *)src)\n+\t\t : \"memory\");\n+}\n+\n+static __always_inline void movnti_16(void *dst, const void *src)\n+{\n+\tmovnti_8(dst, src);\n+\tmovnti_8(dst + 8, src + 8);\n+}\n+\n+static __always_inline void movnti_32(void *dst, const void *src)\n+{\n+\tmovnti_16(dst, src);\n+\tmovnti_16(dst + 16, src + 16);\n+}\n+\n+static __always_inline void movnti_64(void *dst, const void *src)\n+{\n+\tmovnti_32(dst, src);\n+\tmovnti_32(dst + 32, src + 32);\n+}\n+\n+static __always_inline void memcpy_flushcache(void *dst, const void *src,\n+\t\t\t\t\t size_t cnt)\n {\n \tif (__builtin_constant_p(cnt)) {\n \t\tswitch (cnt) {\n@@ -96,10 +124,48 @@ static __always_inline void memcpy_flushcache(void *dst, const void *src, size_t\n \t\t\t\tasm (\"movntiq %1, %0\" : \"=m\"(*(u64 *)dst) : \"r\"(*(u64 *)src));\n \t\t\t\tasm (\"movntiq %1, %0\" : \"=m\"(*(u64 *)(dst + 8)) : \"r\"(*(u64 *)(src + 8)));\n \t\t\t\treturn;\n+\t\t\t/*\n+\t\t\t * The relevant fixed-size copies here are the\n+\t\t\t * x86_64 struct page sizes: 64, 80, and 96 bytes.\n+\t\t\t * Keep 32-byte and 48-byte copies inline as well\n+\t\t\t * instead of sending those nearby fixed-size\n+\t\t\t * cases back to __memcpy_flushcache().\n+\t\t\t */\n+\t\t\tcase 32:\n+\t\t\t\tmovnti_32(dst, src);\n+\t\t\t\treturn;\n+\t\t\tcase 48:\n+\t\t\t\tmovnti_32(dst, src);\n+\t\t\t\tmovnti_16(dst + 32, src + 32);\n+\t\t\t\treturn;\n+\t\t\tcase 64:\n+\t\t\t\tmovnti_64(dst, src);\n+\t\t\t\treturn;\n+\t\t\tcase 80:\n+\t\t\t\tmovnti_64(dst, src);\n+\t\t\t\tmovnti_16(dst + 64, src + 64);\n+\t\t\t\treturn;\n+\t\t\tcase 96:\n+\t\t\t\tmovnti_64(dst, src);\n+\t\t\t\tmovnti_32(dst + 64, src + 64);\n+\t\t\t\treturn;\n \t\t}\n \t}\n+\n \t__memcpy_flushcache(dst, src, cnt);\n }\n+\n+#define memcpy_nontemporal memcpy_nontemporal\n+/*\n+ * Reuse the existing x86 flushcache backend as the non-temporal copy\n+ * primitive.\n+ */\n+static __always_inline void memcpy_nontemporal(void *dst, const void *src,\n+\t\tsize_t cnt)\n+{\n+\tmemcpy_flushcache(dst, src, cnt);\n+}\n+\n #endif\n \n #endif /* __KERNEL__ */\ndiff --git a/include/linux/mm.h b/include/linux/mm.h\nindex 485df9c2dbddb3..43343bfce4936e 100644\n--- a/include/linux/mm.h\n+++ b/include/linux/mm.h\n@@ -2541,11 +2541,22 @@ static inline void set_page_section(struct page *page, unsigned long section)\n \tpage-\u003eflags.f |= (section \u0026 SECTIONS_MASK) \u003c\u003c SECTIONS_PGSHIFT;\n }\n \n+static inline void set_page_section_from_pfn(struct page *page,\n+\t\tunsigned long pfn)\n+{\n+\tset_page_section(page, pfn_to_section_nr(pfn));\n+}\n+\n static inline unsigned long memdesc_section(memdesc_flags_t mdf)\n {\n \treturn (mdf.f \u003e\u003e SECTIONS_PGSHIFT) \u0026 SECTIONS_MASK;\n }\n #else /* !SECTION_IN_PAGE_FLAGS */\n+static inline void set_page_section_from_pfn(struct page *page,\n+\t\tunsigned long pfn)\n+{\n+}\n+\n static inline unsigned long memdesc_section(memdesc_flags_t mdf)\n {\n \treturn 0;\n@@ -2768,9 +2779,7 @@ static inline void set_page_links(struct page *page, enum zone_type zone,\n {\n \tset_page_zone(page, zone);\n \tset_page_node(page, node);\n-#ifdef SECTION_IN_PAGE_FLAGS\n-\tset_page_section(page, pfn_to_section_nr(pfn));\n-#endif\n+\tset_page_section_from_pfn(page, pfn);\n }\n \n /**\ndiff --git a/include/linux/string.h b/include/linux/string.h\nindex 5702daca4326b7..6cb5cdd01158b2 100644\n--- a/include/linux/string.h\n+++ b/include/linux/string.h\n@@ -278,6 +278,19 @@ static inline void memcpy_flushcache(void *dst, const void *src, size_t cnt)\n }\n #endif\n \n+#ifndef memcpy_nontemporal\n+/*\n+ * memcpy_nontemporal() requests a non-temporal copy when the\n+ * architecture has a suitable backend. Architectures without a\n+ * specialized backend fall back to memcpy(). Keep this as a\n+ * function-like macro so the compiler can still see the original\n+ * memcpy() call site and preserve the usual FORTIFY coverage when\n+ * object sizes remain visible there, while keeping the API void.\n+ */\n+#define memcpy_nontemporal(dst, src, len) \\\n+\t((void)memcpy(dst, src, len))\n+#endif\n+\n void *memchr_inv(const void *s, int c, size_t n);\n char *strreplace(char *str, char old, char new);\n \ndiff --git a/mm/mm_init.c b/mm/mm_init.c\nindex 0f64909e8d20e2..ae42a1311e1d18 100644\n--- a/mm/mm_init.c\n+++ b/mm/mm_init.c\n@@ -1005,11 +1005,37 @@ static void __init memmap_init(void)\n }\n \n #ifdef CONFIG_ZONE_DEVICE\n-static void __ref __init_zone_device_page(struct page *page, unsigned long pfn,\n+/*\n+ * Return true when memmap_init_zone_device() must initialize the page\n+ * refcount to 0. MEMORY_DEVICE_GENERIC pages regain a refcount of 1 in\n+ * the free path, while the remaining ZONE_DEVICE types start from 0 here\n+ * and raise the count again when the allocator or driver hands the page\n+ * out.\n+ */\n+static inline bool pagemap_requires_refcount_reset(const struct dev_pagemap *pgmap)\n+{\n+\t/*\n+\t * MEMORY_DEVICE_GENERIC pages regain a refcount of 1 in the free\n+\t * path. The remaining ZONE_DEVICE types start from 0 here and raise\n+\t * the count again when the allocator or driver hands the page out.\n+\t */\n+\tswitch (pgmap-\u003etype) {\n+\tcase MEMORY_DEVICE_FS_DAX:\n+\tcase MEMORY_DEVICE_PRIVATE:\n+\tcase MEMORY_DEVICE_COHERENT:\n+\tcase MEMORY_DEVICE_PCI_P2PDMA:\n+\t\treturn true;\n+\tcase MEMORY_DEVICE_GENERIC:\n+\t\treturn false;\n+\t}\n+\n+\treturn false;\n+}\n+\n+static void __ref __zone_device_page_init(struct page *page, unsigned long pfn,\n \t\t\t\t\t unsigned long zone_idx, int nid,\n \t\t\t\t\t struct dev_pagemap *pgmap)\n {\n-\n \t__init_single_page(page, pfn, zone_idx, nid);\n \n \t/*\n@@ -1028,27 +1054,54 @@ static void __ref __init_zone_device_page(struct page *page, unsigned long pfn,\n \t */\n \tpage_folio(page)-\u003epgmap = pgmap;\n \tpage-\u003ezone_device_data = NULL;\n+}\n \n-\t/*\n-\t * ZONE_DEVICE pages other than MEMORY_TYPE_GENERIC are released\n-\t * directly to the driver page allocator which will set the page count\n-\t * to 1 when allocating the page.\n-\t *\n-\t * MEMORY_TYPE_GENERIC and MEMORY_TYPE_FS_DAX pages automatically have\n-\t * their refcount reset to one whenever they are freed (ie. after\n-\t * their refcount drops to 0).\n-\t */\n-\tswitch (pgmap-\u003etype) {\n-\tcase MEMORY_DEVICE_FS_DAX:\n-\tcase MEMORY_DEVICE_PRIVATE:\n-\tcase MEMORY_DEVICE_COHERENT:\n-\tcase MEMORY_DEVICE_PCI_P2PDMA:\n+static void __ref zone_device_page_init_slow(struct page *page,\n+\t\tunsigned long pfn, unsigned long zone_idx, int nid,\n+\t\tstruct dev_pagemap *pgmap)\n+{\n+\t__zone_device_page_init(page, pfn, zone_idx, nid, pgmap);\n+\tif (pagemap_requires_refcount_reset(pgmap))\n \t\tset_page_count(page, 0);\n-\t\tbreak;\n+}\n \n-\tcase MEMORY_DEVICE_GENERIC:\n-\t\tbreak;\n-\t}\n+static inline void zone_device_tail_page_init(struct page *page,\n+\t\tunsigned long pfn, unsigned long zone_idx, int nid,\n+\t\tstruct dev_pagemap *pgmap, const struct page *head,\n+\t\tunsigned int order)\n+{\n+\tzone_device_page_init_slow(page, pfn, zone_idx, nid, pgmap);\n+\tprep_compound_tail(page, head, order);\n+\tset_page_count(page, 0);\n+}\n+\n+/*\n+ * 'template' is a reusable page prototype rather than a strictly immutable\n+ * object. Most ZONE_DEVICE fields stay constant across the pages covered by\n+ * the current template, but section bits and page-\u003evirtual may still depend\n+ * on the PFN. Refresh those PFN-dependent fields in the template before\n+ * copying it into @page.\n+ */\n+static inline void zone_device_page_update_template(struct page *template,\n+\t\tunsigned long pfn)\n+{\n+\tset_page_section_from_pfn(template, pfn);\n+#ifdef WANT_PAGE_VIRTUAL\n+\tif (!is_highmem_idx(ZONE_DEVICE))\n+\t\tset_page_address(template, __va(pfn \u003c\u003c PAGE_SHIFT));\n+#endif\n+}\n+\n+static void zone_device_page_init_from_template(struct page *page,\n+\t\tunsigned long pfn, struct page *template)\n+{\n+\t/*\n+\t * 'template' carries the invariant portion of a ZONE_DEVICE struct\n+\t * page. Update the PFN-dependent fields in place before copying it\n+\t * to the destination page.\n+\t */\n+\tzone_device_page_update_template(template, pfn);\n+\tmemcpy_nontemporal(page, template, sizeof(*page));\n }\n \n /*\n@@ -1083,6 +1136,7 @@ static void __ref memmap_init_compound(struct page *head,\n {\n \tunsigned long pfn, end_pfn = head_pfn + nr_pages;\n \tunsigned int order = pgmap-\u003evmemmap_shift;\n+\tstruct page template;\n \n \t/*\n \t * We have to initialize the pages, including setting up page links.\n@@ -1091,12 +1145,26 @@ static void __ref memmap_init_compound(struct page *head,\n \t * the pages in the same go.\n \t */\n \t__SetPageHead(head);\n+\n \tfor (pfn = head_pfn + 1; pfn \u003c end_pfn; pfn++) {\n \t\tstruct page *page = pfn_to_page(pfn);\n \n-\t\t__init_zone_device_page(page, pfn, zone_idx, nid, pgmap);\n-\t\tprep_compound_tail(page, head, order);\n-\t\tset_page_count(page, 0);\n+\t\tif (pfn == head_pfn + 1) {\n+\t\t\t/*\n+\t\t\t * All tails of the same compound page share the\n+\t\t\t * state established by prep_compound_tail(). Reuse\n+\t\t\t * one tail template for the whole range and\n+\t\t\t * refresh only the PFN-dependent fields in that\n+\t\t\t * template before each copy.\n+\t\t\t */\n+\t\t\tzone_device_tail_page_init(page, pfn, zone_idx, nid,\n+\t\t\t\t\t\t pgmap, head, order);\n+\t\t\t/* init template page */\n+\t\t\tmemcpy(\u0026template, page, sizeof(*page));\n+\t\t} else {\n+\t\t\tzone_device_page_init_from_template(page, pfn,\n+\t\t\t\t\t\t\t \u0026template);\n+\t\t}\n \t}\n \tprep_compound_head(head, order);\n }\n@@ -1113,6 +1181,7 @@ void __ref memmap_init_zone_device(struct zone *zone,\n \tunsigned long zone_idx = zone_idx(zone);\n \tunsigned long start = jiffies;\n \tint nid = pgdat-\u003enode_id;\n+\tstruct page template;\n \n \tif (WARN_ON_ONCE(!pgmap || zone_idx != ZONE_DEVICE))\n \t\treturn;\n@@ -1130,7 +1199,21 @@ void __ref memmap_init_zone_device(struct zone *zone,\n \tfor (pfn = start_pfn; pfn \u003c end_pfn; pfn += pfns_per_compound) {\n \t\tstruct page *page = pfn_to_page(pfn);\n \n-\t\t__init_zone_device_page(page, pfn, zone_idx, nid, pgmap);\n+\t\tif (pfn == start_pfn) {\n+\t\t\t/*\n+\t\t\t * Seed the reusable head-page template from the\n+\t\t\t * first real struct page, because the existing\n+\t\t\t * page-init and pageblock helpers expect a real\n+\t\t\t * memmap entry rather than a stack object.\n+\t\t\t */\n+\t\t\tzone_device_page_init_slow(page, pfn, zone_idx,\n+\t\t\t\t\t\t nid, pgmap);\n+\t\t\t/* init template page */\n+\t\t\tmemcpy(\u0026template, page, sizeof(*page));\n+\t\t} else {\n+\t\t\tzone_device_page_init_from_template(page, pfn,\n+\t\t\t\t\t\t\t \u0026template);\n+\t\t}\n \n \t\tif (IS_ALIGNED(pfn, PAGES_PER_SECTION))\n \t\t\tcond_resched();\n"
} |
| 2/1 | 2026/07/28 01:26 | agent | patch-evaluator |
2mModel:best-expensive Args: null Results: {
"EnableConfigs": [
"ZONE_DEVICE",
"PCI_P2PDMA",
"DAX",
"DEV_DAX",
"FS_DAX",
"MEMORY_HOTPLUG",
"SPARSEMEM_VMEMMAP"
],
"FocusSymbols": [
"memmap_init_zone_device",
"memmap_init_compound",
"zone_device_page_init_from_template",
"zone_device_page_init_slow"
],
"Reasoning": "The patch optimizes the initialization of ZONE_DEVICE pages by using a template and non-temporal memcpy. This is core memory management logic that is reachable when probing devices like PMEM, DAX, or PCI P2PDMA.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). - Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU. - Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove) that are executed only during PCI hot-unplug or sysfs driver unbind operations. If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. Prefer non-static, non-inlined API entrypoint functions over internal static helper functions (which are inlined by the compiler and do not have distinct symbol addresses). 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 1fa30007abaa187f488237d709151800c72ff262
Author: syz-cluster <triage@syzkaller.com>
Date: Tue Jul 28 01:26:42 2026 +0000
syz-cluster: applied patch under review
diff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h
index 4635616863f53d..bc6a9f34b346af 100644
--- a/arch/x86/include/asm/string_64.h
+++ b/arch/x86/include/asm/string_64.h
@@ -82,7 +82,35 @@ int strcmp(const char *cs, const char *ct);
#ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE
#define __HAVE_ARCH_MEMCPY_FLUSHCACHE 1
void __memcpy_flushcache(void *dst, const void *src, size_t cnt);
-static __always_inline void memcpy_flushcache(void *dst, const void *src, size_t cnt)
+
+static __always_inline void movnti_8(void *dst, const void *src)
+{
+ asm volatile("movntiq %1, %0"
+ : "=m"(*(u64 *)dst)
+ : "r"(*(const u64 *)src)
+ : "memory");
+}
+
+static __always_inline void movnti_16(void *dst, const void *src)
+{
+ movnti_8(dst, src);
+ movnti_8(dst + 8, src + 8);
+}
+
+static __always_inline void movnti_32(void *dst, const void *src)
+{
+ movnti_16(dst, src);
+ movnti_16(dst + 16, src + 16);
+}
+
+static __always_inline void movnti_64(void *dst, const void *src)
+{
+ movnti_32(dst, src);
+ movnti_32(dst + 32, src + 32);
+}
+
+static __always_inline void memcpy_flushcache(void *dst, const void *src,
+ size_t cnt)
{
if (__builtin_constant_p(cnt)) {
switch (cnt) {
@@ -96,10 +124,48 @@ static __always_inline void memcpy_flushcache(void *dst, const void *src, size_t
asm ("movntiq %1, %0" : "=m"(*(u64 *)dst) : "r"(*(u64 *)src));
asm ("movntiq %1, %0" : "=m"(*(u64 *)(dst + 8)) : "r"(*(u64 *)(src + 8)));
return;
+ /*
+ * The relevant fixed-size copies here are the
+ * x86_64 struct page sizes: 64, 80, and 96 bytes.
+ * Keep 32-byte and 48-byte copies inline as well
+ * instead of sending those nearby fixed-size
+ * cases back to __memcpy_flushcache().
+ */
+ case 32:
+ movnti_32(dst, src);
+ return;
+ case 48:
+ movnti_32(dst, src);
+ movnti_16(dst + 32, src + 32);
+ return;
+ case 64:
+ movnti_64(dst, src);
+ return;
+ case 80:
+ movnti_64(dst, src);
+ movnti_16(dst + 64, src + 64);
+ return;
+ case 96:
+ movnti_64(dst, src);
+ movnti_32(dst + 64, src + 64);
+ return;
}
}
+
__memcpy_flushcache(dst, src, cnt);
}
+
+#define memcpy_nontemporal memcpy_nontemporal
+/*
+ * Reuse the existing x86 flushcache backend as the non-temporal copy
+ * primitive.
+ */
+static __always_inline void memcpy_nontemporal(void *dst, const void *src,
+ size_t cnt)
+{
+ memcpy_flushcache(dst, src, cnt);
+}
+
#endif
#endif /* __KERNEL__ */
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 485df9c2dbddb3..43343bfce4936e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2541,11 +2541,22 @@ static inline void set_page_section(struct page *page, unsigned long section)
page->flags.f |= (section & SECTIONS_MASK) << SECTIONS_PGSHIFT;
}
+static inline void set_page_section_from_pfn(struct page *page,
+ unsigned long pfn)
+{
+ set_page_section(page, pfn_to_section_nr(pfn));
+}
+
static inline unsigned long memdesc_section(memdesc_flags_t mdf)
{
return (mdf.f >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
}
#else /* !SECTION_IN_PAGE_FLAGS */
+static inline void set_page_section_from_pfn(struct page *page,
+ unsigned long pfn)
+{
+}
+
static inline unsigned long memdesc_section(memdesc_flags_t mdf)
{
return 0;
@@ -2768,9 +2779,7 @@ static inline void set_page_links(struct page *page, enum zone_type zone,
{
set_page_zone(page, zone);
set_page_node(page, node);
-#ifdef SECTION_IN_PAGE_FLAGS
- set_page_section(page, pfn_to_section_nr(pfn));
-#endif
+ set_page_section_from_pfn(page, pfn);
}
/**
diff --git a/include/linux/string.h b/include/linux/string.h
index 5702daca4326b7..6cb5cdd01158b2 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -278,6 +278,19 @@ static inline void memcpy_flushcache(void *dst, const void *src, size_t cnt)
}
#endif
+#ifndef memcpy_nontemporal
+/*
+ * memcpy_nontemporal() requests a non-temporal copy when the
+ * architecture has a suitable backend. Architectures without a
+ * specialized backend fall back to memcpy(). Keep this as a
+ * function-like macro so the compiler can still see the original
+ * memcpy() call site and preserve the usual FORTIFY coverage when
+ * object sizes remain visible there, while keeping the API void.
+ */
+#define memcpy_nontemporal(dst, src, len) \
+ ((void)memcpy(dst, src, len))
+#endif
+
void *memchr_inv(const void *s, int c, size_t n);
char *strreplace(char *str, char old, char new);
diff --git a/mm/mm_init.c b/mm/mm_init.c
index 0f64909e8d20e2..ae42a1311e1d18 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -1005,11 +1005,37 @@ static void __init memmap_init(void)
}
#ifdef CONFIG_ZONE_DEVICE
-static void __ref __init_zone_device_page(struct page *page, unsigned long pfn,
+/*
+ * Return true when memmap_init_zone_device() must initialize the page
+ * refcount to 0. MEMORY_DEVICE_GENERIC pages regain a refcount of 1 in
+ * the free path, while the remaining ZONE_DEVICE types start from 0 here
+ * and raise the count again when the allocator or driver hands the page
+ * out.
+ */
+static inline bool pagemap_requires_refcount_reset(const struct dev_pagemap *pgmap)
+{
+ /*
+ * MEMORY_DEVICE_GENERIC pages regain a refcount of 1 in the free
+ * path. The remaining ZONE_DEVICE types start from 0 here and raise
+ * the count again when the allocator or driver hands the page out.
+ */
+ switch (pgmap->type) {
+ case MEMORY_DEVICE_FS_DAX:
+ case MEMORY_DEVICE_PRIVATE:
+ case MEMORY_DEVICE_COHERENT:
+ case MEMORY_DEVICE_PCI_P2PDMA:
+ return true;
+ case MEMORY_DEVICE_GENERIC:
+ return false;
+ }
+
+ return false;
+}
+
+static void __ref __zone_device_page_init(struct page *page, unsigned long pfn,
unsigned long zone_idx, int nid,
struct dev_pagemap *pgmap)
{
-
__init_single_page(page, pfn, zone_idx, nid);
/*
@@ -1028,27 +1054,54 @@ static void __ref __init_zone_device_page(struct page *page, unsigned long pfn,
*/
page_folio(page)->pgmap = pgmap;
page->zone_device_data = NULL;
+}
- /*
- * ZONE_DEVICE pages other than MEMORY_TYPE_GENERIC are released
- * directly to the driver page allocator which will set the page count
- * to 1 when allocating the page.
- *
- * MEMORY_TYPE_GENERIC and MEMORY_TYPE_FS_DAX pages automatically have
- * their refcount reset to one whenever they are freed (ie. after
- * their refcount drops to 0).
- */
- switch (pgmap->type) {
- case MEMORY_DEVICE_FS_DAX:
- case MEMORY_DEVICE_PRIVATE:
- case MEMORY_DEVICE_COHERENT:
- case MEMORY_DEVICE_PCI_P2PDMA:
+static void __ref zone_device_page_init_slow(struct page *page,
+ unsigned long pfn, unsigned long zone_idx, int nid,
+ struct dev_pagemap *pgmap)
+{
+ __zone_device_page_init(page, pfn, zone_idx, nid, pgmap);
+ if (pagemap_requires_refcount_reset(pgmap))
set_page_count(page, 0);
- break;
+}
- case MEMORY_DEVICE_GENERIC:
- break;
- }
+static inline void zone_device_tail_page_init(struct page *page,
+ unsigned long pfn, unsigned long zone_idx, int nid,
+ struct dev_pagemap *pgmap, const struct page *head,
+ unsigned int order)
+{
+ zone_device_page_init_slow(page, pfn, zone_idx, nid, pgmap);
+ prep_compound_tail(page, head, order);
+ set_page_count(page, 0);
+}
+
+/*
+ * 'template' is a reusable page prototype rather than a strictly immutable
+ * object. Most ZONE_DEVICE fields stay constant across the pages covered by
+ * the current template, but section bits and page->virtual may still depend
+ * on the PFN. Refresh those PFN-dependent fields in the template before
+ * copying it into @page.
+ */
+static inline void zone_device_page_update_template(struct page *template,
+ unsigned long pfn)
+{
+ set_page_section_from_pfn(template, pfn);
+#ifdef WANT_PAGE_VIRTUAL
+ if (!is_highmem_idx(ZONE_DEVICE))
+ set_page_address(template, __va(pfn << PAGE_SHIFT));
+#endif
+}
+
+static void zone_device_page_init_from_template(struct page *page,
+ unsigned long pfn, struct page *template)
+{
+ /*
+ * 'template' carries the invariant portion of a ZONE_DEVICE struct
+ * page. Update the PFN-dependent fields in place before copying it
+ * to the destination page.
+ */
+ zone_device_page_update_template(template, pfn);
+ memcpy_nontemporal(page, template, sizeof(*page));
}
/*
@@ -1083,6 +1136,7 @@ static void __ref memmap_init_compound(struct page *head,
{
unsigned long pfn, end_pfn = head_pfn + nr_pages;
unsigned int order = pgmap->vmemmap_shift;
+ struct page template;
/*
* We have to initialize the pages, including setting up page links.
@@ -1091,12 +1145,26 @@ static void __ref memmap_init_compound(struct page *head,
* the pages in the same go.
*/
__SetPageHead(head);
+
for (pfn = head_pfn + 1; pfn < end_pfn; pfn++) {
struct page *page = pfn_to_page(pfn);
- __init_zone_device_page(page, pfn, zone_idx, nid, pgmap);
- prep_compound_tail(page, head, order);
- set_page_count(page, 0);
+ if (pfn == head_pfn + 1) {
+ /*
+ * All tails of the same compound page share the
+ * state established by prep_compound_tail(). Reuse
+ * one tail template for the whole range and
+ * refresh only the PFN-dependent fields in that
+ * template before each copy.
+ */
+ zone_device_tail_page_init(page, pfn, zone_idx, nid,
+ pgmap, head, order);
+ /* init template page */
+ memcpy(&template, page, sizeof(*page));
+ } else {
+ zone_device_page_init_from_template(page, pfn,
+ &template);
+ }
}
prep_compound_head(head, order);
}
@@ -1113,6 +1181,7 @@ void __ref memmap_init_zone_device(struct zone *zone,
unsigned long zone_idx = zone_idx(zone);
unsigned long start = jiffies;
int nid = pgdat->node_id;
+ struct page template;
if (WARN_ON_ONCE(!pgmap || zone_idx != ZONE_DEVICE))
return;
@@ -1130,7 +1199,21 @@ void __ref memmap_init_zone_device(struct zone *zone,
for (pfn = start_pfn; pfn < end_pfn; pfn += pfns_per_compound) {
struct page *page = pfn_to_page(pfn);
- __init_zone_device_page(page, pfn, zone_idx, nid, pgmap);
+ if (pfn == start_pfn) {
+ /*
+ * Seed the reusable head-page template from the
+ * first real struct page, because the existing
+ * page-init and pageblock helpers expect a real
+ * memmap entry rather than a stack object.
+ */
+ zone_device_page_init_slow(page, pfn, zone_idx,
+ nid, pgmap);
+ /* init template page */
+ memcpy(&template, page, sizeof(*page));
+ } else {
+ zone_device_page_init_from_template(page, pfn,
+ &template);
+ }
if (IS_ALIGNED(pfn, PAGES_PER_SECTION))
cond_resched();
|
| 3/2 | 2026/07/28 01:26 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 5925 output: 30 thoughts: 456 Thoughts: **Analyzing a Kernel Optimization Patch** Okay, so I'm looking at this patch that optimizes the initialization of `struct page` for `ZONE_DEVICE` memory. It's using `memcpy_nontemporal` to copy a pre-defined template instead of painstakingly initializing each page individually, which is a clever approach. This optimization targets `memmap_init_zone_device` and `memmap_init_compound`, both of which are critical in memory management. It also looks like there's an x86-specific implementation of `memcpy_nontemporal` using `movnti` instructions, a nice low-level optimization. My immediate thought is, is this reachable and, more importantly, worth fuzzing? `memmap_init_zone_device` is triggered when `ZONE_DEVICE` memory is hotplugged. That's typically for DAX, PMEM, and the like. Now, can this be reached in a common setup like QEMU? Absolutely! We can emulate PMEM/NVDIMM devices in QEMU, we can use the `memmap=` kernel parameter or even utilize `mmap` with DAX. Hmm, wait a minute, I remember `memmap_init_zone_device` is called from `devm_memremap_pages`. Let's dig deeper and see what calls that function. *checks code* Okay, it's called from `drivers/dax/super.c`, `drivers/nvdimm/pmem.c`, and `drivers/pci/p2pdma.c`. Interesting! The big question now is, can syzkaller trigger `devm_memremap_pages` through, perhaps, some loop device, a pmem device, or even p2pdma? Actually, wait, `memmap_init_zone_device` is a core MM function, so it's a definite "yes" to core kernel logic. Now, let's refocus. This is an optimization, yes, but it changes how pages are initialized, meaning it touches core MM logic. Absolutely worth fuzzing. The key symbols to focus on here are definitely `memmap_init_zone_device` and `memmap_init_compound`. Finally, I need to check if `ZONE_DEVICE` is even enabled in typical configs. I need to make sure `CONFIG_ZONE_DEVICE` is set. Let me just check `mm/mm_init.c` to confirm where `memmap_init_zone_device` is used. |
| 4/2 | 2026/07/28 01:26 | tool | grepper |
0mArgs:{
"Expression": "memmap_init_zone_device",
"PathPrefix": "mm/"
}Results: {
"Output": "mm/memremap.c=144=static int pagemap_range(struct dev_pagemap *pgmap, struct mhp_params *params,\n--\nmm/memremap.c-241-\t */\nmm/memremap.c:242:\tmemmap_init_zone_device(\u0026NODE_DATA(nid)-\u003enode_zones[ZONE_DEVICE],\nmm/memremap.c-243-\t\t\t\tPHYS_PFN(range-\u003estart),\n--\nmm/mm_init.c=968=static void __init memmap_init(void)\n--\nmm/mm_init.c-1008-/*\nmm/mm_init.c:1009: * Return true when memmap_init_zone_device() must initialize the page\nmm/mm_init.c-1010- * refcount to 0. MEMORY_DEVICE_GENERIC pages regain a refcount of 1 in\n--\nmm/mm_init.c=1131=static void __ref memmap_init_compound(struct page *head,\n--\nmm/mm_init.c-1171-\nmm/mm_init.c:1172:void __ref memmap_init_zone_device(struct zone *zone,\nmm/mm_init.c-1173-\t\t\t\t unsigned long start_pfn,\n"
} |
| 5/2 | 2026/07/28 01:26 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 7290 output: 28 thoughts: 52 Thoughts: Here's my summary, as though I'm thinking through this process: **Diving into `memmap_init_zone_device` and its Usage** Okay, so I'm looking at the `memmap_init_zone_device` function. My initial hunch tells me this is where some critical initialization or setup for memory mapping is handled within a specific zone or device context. I'm keen to understand *how* it's being used. The call graph is what I will look at. Now, I need to trace the control flow. Let's see...`devm_memremap_pages` is a likely starting point because that's what seems to relate to the 'device managed memory remapping'. That calls `pagemap_range`. And *aha!* `pagemap_range` calls `memmap_init_zone_device`. So the dependency is clear. I need to understand what `devm_memremap_pages` does at the top, since it is the starting point. This will give me a better understanding of the context in which `memmap_init_zone_device` is being invoked. |
| 6/2 | 2026/07/28 01:26 | tool | grepper |
0mArgs:{
"Expression": "devm_memremap_pages",
"PathPrefix": ""
}Results: {
"Output": "Documentation/mm/hmm.rst=274=These can be allocated and freed with::\n--\nDocumentation/mm/hmm.rst-290-\nDocumentation/mm/hmm.rst:291:There are also devm_request_free_mem_region(), devm_memremap_pages(),\nDocumentation/mm/hmm.rst-292-devm_memunmap_pages(), and devm_release_mem_region() when the resources can\n--\nDocumentation/mm/memory-model.rst=141=to keep the memory pinned for active use. `ZONE_DEVICE`, via\nDocumentation/mm/memory-model.rst:142::c:func:`devm_memremap_pages`, performs just enough memory hotplug to\nDocumentation/mm/memory-model.rst-143-turn on :c:func:`pfn_to_page`, :c:func:`page_to_pfn`, and\n--\nDocumentation/mm/memory-model.rst=157=memory hotplug. Sub-section support allows for 2MB as the cross-arch\nDocumentation/mm/memory-model.rst:158:common alignment granularity for :c:func:`devm_memremap_pages`.\nDocumentation/mm/memory-model.rst-159-\n--\nDocumentation/translations/zh_CN/mm/hmm.rst=220=migrate_vma_finalize() 函数旨在使驱动程序更易于编写并集中跨驱动程序的通用代码。\n--\nDocumentation/translations/zh_CN/mm/hmm.rst-241-\nDocumentation/translations/zh_CN/mm/hmm.rst:242:还有devm_request_free_mem_region(), devm_memremap_pages(),\nDocumentation/translations/zh_CN/mm/hmm.rst-243-devm_memunmap_pages() 和 devm_release_mem_region() 当资源可以绑定到 ``struct device``.\n--\nDocumentation/translations/zh_CN/mm/memory-model.rst=107=ZONE_DEVICE\n--\nDocumentation/translations/zh_CN/mm/memory-model.rst-111-事实有关:这些地址范围的页面对象从未被在线标记过,而且必须对设备进行引用,而不仅仅\nDocumentation/translations/zh_CN/mm/memory-model.rst:112:是页面,以保持内存被“锁定”以便使用。 `ZONE_DEVICE` ,通过 :c:func:`devm_memremap_pages` ,\nDocumentation/translations/zh_CN/mm/memory-model.rst-113-为给定的pfns范围执行足够的内存热插拔来开启 :c:func:`pfn_to_page`,\n--\nDocumentation/translations/zh_CN/mm/memory-model.rst-122-:c:func:`arch_add_memory` ,即内存热插拔的上半部分。子段支持允许2MB作为\nDocumentation/translations/zh_CN/mm/memory-model.rst:123::c:func:`devm_memremap_pages` 的跨架构通用对齐颗粒度。\nDocumentation/translations/zh_CN/mm/memory-model.rst-124-\n--\ndrivers/dax/device.c=380=static int dev_dax_probe(struct dev_dax *dev_dax)\n--\ndrivers/dax/device.c-434-\t\t\torder_base_2(dev_dax-\u003ealign \u003e\u003e PAGE_SHIFT);\ndrivers/dax/device.c:435:\taddr = devm_memremap_pages(dev, pgmap);\ndrivers/dax/device.c-436-\tif (IS_ERR(addr))\n--\ndrivers/dax/fsdev.c=207=static int fsdev_dax_probe(struct dev_dax *dev_dax)\n--\ndrivers/dax/fsdev.c-273-\ndrivers/dax/fsdev.c:274:\taddr = devm_memremap_pages(dev, pgmap);\ndrivers/dax/fsdev.c-275-\tif (IS_ERR(addr))\n--\ndrivers/gpu/drm/amd/amdkfd/kfd_migrate.c=1026=int kgd2kfd_init_zone_device(struct amdgpu_device *adev)\n--\ndrivers/gpu/drm/amd/amdkfd/kfd_migrate.c-1067-\t */\ndrivers/gpu/drm/amd/amdkfd/kfd_migrate.c:1068:\tr = devm_memremap_pages(adev-\u003edev, pgmap);\ndrivers/gpu/drm/amd/amdkfd/kfd_migrate.c-1069-\tif (IS_ERR(r)) {\n--\ndrivers/gpu/drm/xe/xe_svm.c=1760=static struct xe_pagemap *xe_pagemap_create(struct xe_device *xe, struct xe_vram_region *vr)\n--\ndrivers/gpu/drm/xe/xe_svm.c-1801-\tpagemap-\u003eops = drm_pagemap_pagemap_ops_get();\ndrivers/gpu/drm/xe/xe_svm.c:1802:\taddr = devm_memremap_pages(dev, pagemap);\ndrivers/gpu/drm/xe/xe_svm.c-1803-\tif (IS_ERR(addr)) {\n--\ndrivers/hv/mshv_vtl_main.c=381=static int mshv_vtl_ioctl_add_vtl0_mem(struct mshv_vtl *vtl, void __user *arg)\n--\ndrivers/hv/mshv_vtl_main.c-419-\ndrivers/hv/mshv_vtl_main.c:420:\taddr = devm_memremap_pages(mem_dev, pgmap);\ndrivers/hv/mshv_vtl_main.c-421-\tif (IS_ERR(addr)) {\ndrivers/hv/mshv_vtl_main.c:422:\t\tdev_err(vtl-\u003emodule_dev, \"devm_memremap_pages error: %ld\\n\", PTR_ERR(addr));\ndrivers/hv/mshv_vtl_main.c-423-\t\tkfree(pgmap);\n--\ndrivers/nvdimm/Kconfig=143=config NVDIMM_TEST_BUILD\n--\ndrivers/nvdimm/Kconfig-151-\t otherwise helps catch build errors induced by changes to the\ndrivers/nvdimm/Kconfig:152:\t core devm_memremap_pages() implementation and other\ndrivers/nvdimm/Kconfig-153-\t infrastructure.\n--\ndrivers/nvdimm/pmem.c=448=static int pmem_attach_disk(struct device *dev,\n--\ndrivers/nvdimm/pmem.c-517-\t\tpmem-\u003epgmap.ops = \u0026fsdax_pagemap_ops;\ndrivers/nvdimm/pmem.c:518:\t\taddr = devm_memremap_pages(dev, \u0026pmem-\u003epgmap);\ndrivers/nvdimm/pmem.c-519-\t\tpfn_sb = nd_pfn-\u003epfn_sb;\n--\ndrivers/nvdimm/pmem.c-530-\t\tpmem-\u003epgmap.ops = \u0026fsdax_pagemap_ops;\ndrivers/nvdimm/pmem.c:531:\t\taddr = devm_memremap_pages(dev, \u0026pmem-\u003epgmap);\ndrivers/nvdimm/pmem.c-532-\t\tbb_range = pmem-\u003epgmap.range;\n--\ndrivers/pci/p2pdma.c=387=int pci_p2pdma_add_resource(struct pci_dev *pdev, int bar, size_t size,\n--\ndrivers/pci/p2pdma.c-436-\ndrivers/pci/p2pdma.c:437:\taddr = devm_memremap_pages(\u0026pdev-\u003edev, pgmap);\ndrivers/pci/p2pdma.c-438-\tif (IS_ERR(addr)) {\n--\ndrivers/s390/block/dcssblk.c=553=dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)\n--\ndrivers/s390/block/dcssblk.c-696-\t\tdev_info-\u003epgmap.nr_range\t= 1;\ndrivers/s390/block/dcssblk.c:697:\t\taddr = devm_memremap_pages(\u0026dev_info-\u003edev, \u0026dev_info-\u003epgmap);\ndrivers/s390/block/dcssblk.c-698-\t\tif (IS_ERR(addr)) {\n--\nfs/fuse/virtio_fs.c=1076=static int virtio_fs_setup_dax(struct virtio_device *vdev, struct virtio_fs *fs)\n--\nfs/fuse/virtio_fs.c-1116-\t/* Ideally we would directly use the PCI BAR resource but\nfs/fuse/virtio_fs.c:1117:\t * devm_memremap_pages() wants its own copy in pgmap. So\nfs/fuse/virtio_fs.c-1118-\t * initialize a struct resource from scratch (only the start\n--\nfs/fuse/virtio_fs.c-1126-\nfs/fuse/virtio_fs.c:1127:\tfs-\u003ewindow_kaddr = devm_memremap_pages(\u0026vdev-\u003edev, pgmap);\nfs/fuse/virtio_fs.c-1128-\tif (IS_ERR(fs-\u003ewindow_kaddr))\n--\ninclude/linux/memremap.h=77=struct dev_pagemap_ops {\n--\ninclude/linux/memremap.h-115- * @altmap: pre-allocated/reserved memory for vmemmap allocations\ninclude/linux/memremap.h:116: * @ref: reference count that pins the devm_memremap_pages() mapping\ninclude/linux/memremap.h-117- * @done: completion for @ref\n--\ninclude/linux/memremap.h=230=void memunmap_pages(struct dev_pagemap *pgmap);\ninclude/linux/memremap.h:231:void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap);\ninclude/linux/memremap.h-232-void devm_memunmap_pages(struct device *dev, struct dev_pagemap *pgmap);\n--\ninclude/linux/memremap.h=247=static inline void zone_device_private_split_cb(struct folio *original_folio,\n--\ninclude/linux/memremap.h-264-#else\ninclude/linux/memremap.h:265:static inline void *devm_memremap_pages(struct device *dev,\ninclude/linux/memremap.h-266-\t\tstruct dev_pagemap *pgmap)\n--\ninclude/linux/memremap.h-268-\t/*\ninclude/linux/memremap.h:269:\t * Fail attempts to call devm_memremap_pages() without\ninclude/linux/memremap.h-270-\t * ZONE_DEVICE support enabled, this requires callers to fall\n--\nmm/memremap.c=130=EXPORT_SYMBOL_GPL(memunmap_pages);\nmm/memremap.c-131-\nmm/memremap.c:132:static void devm_memremap_pages_release(void *data)\nmm/memremap.c-133-{\n--\nmm/memremap.c=144=static int pagemap_range(struct dev_pagemap *pgmap, struct mhp_params *params,\n--\nmm/memremap.c-261-/*\nmm/memremap.c:262: * Not device managed version of devm_memremap_pages, undone by\nmm/memremap.c:263: * memunmap_pages(). Please use devm_memremap_pages if you have a struct\nmm/memremap.c-264- * device available.\n--\nmm/memremap.c=352=EXPORT_SYMBOL_GPL(memremap_pages);\n--\nmm/memremap.c-354-/**\nmm/memremap.c:355: * devm_memremap_pages - remap and provide memmap backing for the given resource\nmm/memremap.c-356- * @dev: hosting device for @res\n--\nmm/memremap.c-367- * 'live' on entry and will be killed and reaped at\nmm/memremap.c:368: * devm_memremap_pages_release() time, or if this routine fails.\nmm/memremap.c-369- *\n--\nmm/memremap.c-373- */\nmm/memremap.c:374:void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)\nmm/memremap.c-375-{\n--\nmm/memremap.c-382-\nmm/memremap.c:383:\terror = devm_add_action_or_reset(dev, devm_memremap_pages_release,\nmm/memremap.c-384-\t\t\tpgmap);\n--\nmm/memremap.c-388-}\nmm/memremap.c:389:EXPORT_SYMBOL_GPL(devm_memremap_pages);\nmm/memremap.c-390-\nmm/memremap.c=391=void devm_memunmap_pages(struct device *dev, struct dev_pagemap *pgmap)\nmm/memremap.c-392-{\nmm/memremap.c:393:\tdevm_release_action(dev, devm_memremap_pages_release, pgmap);\nmm/memremap.c-394-}\n--\ntools/testing/nvdimm/Kbuild=13=ldflags-y += --wrap=__release_region\ntools/testing/nvdimm/Kbuild:14:ldflags-y += --wrap=devm_memremap_pages\ntools/testing/nvdimm/Kbuild-15-ldflags-y += --wrap=insert_resource\n--\ntools/testing/nvdimm/test/iomap.c=108=static void dev_pagemap_percpu_release(struct percpu_ref *ref)\n--\ntools/testing/nvdimm/test/iomap.c-114-\ntools/testing/nvdimm/test/iomap.c:115:void *__wrap_devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)\ntools/testing/nvdimm/test/iomap.c-116-{\n--\ntools/testing/nvdimm/test/iomap.c-121-\tif (!nfit_res)\ntools/testing/nvdimm/test/iomap.c:122:\t\treturn devm_memremap_pages(dev, pgmap);\ntools/testing/nvdimm/test/iomap.c-123-\n--\ntools/testing/nvdimm/test/iomap.c-134-}\ntools/testing/nvdimm/test/iomap.c:135:EXPORT_SYMBOL_GPL(__wrap_devm_memremap_pages);\ntools/testing/nvdimm/test/iomap.c-136-\n--\ntools/testing/nvdimm/test/nfit_test.h=212=void *__wrap_devm_memremap(struct device *dev, resource_size_t offset,\ntools/testing/nvdimm/test/nfit_test.h-213-\t\tsize_t size, unsigned long flags);\ntools/testing/nvdimm/test/nfit_test.h:214:void *__wrap_devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap);\ntools/testing/nvdimm/test/nfit_test.h-215-void *__wrap_memremap(resource_size_t offset, size_t size,\n"
} |
| 7/2 | 2026/07/28 01:27 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 11729 output: 28 thoughts: 235 Thoughts: **Analyzing the Reachability of `devm_memremap_pages` and Related Functions** Okay, let's break this down. My initial thought is to identify the call sites of `devm_memremap_pages`. I see that `drivers/pci/p2pdma.c`, `drivers/dax/device.c`, `drivers/nvdimm/pmem.c`, `fs/fuse/virtio_fs.c`, and `drivers/s390/block/dcssblk.c` all use this function. Now, a key question for me is whether syzkaller can realistically trigger `devm_memremap_pages`. The answer seems to be yes – creating a loop device, playing with pmem/dax if enabled, virtio_fs, or p2pdma are potential avenues. Now, this patch modifies `memmap_init_compound`, which is called within `memmap_init_zone_device`. That's interesting, and I need to explore this relationship further. I realize that `memmap_init_compound` is only actually reached from `memmap_init_zone_device` if `pgmap->vmemmap_shift` is set. So, this sets up a conditional path. Therefore, the next question is, is `memmap_init_compound` reachable? It seems the crucial factor here is the `vmemmap_shift` variable. If it's set, then, yes, it is. So, I need to check the callers of `memmap_init_zone_device` to determine the conditions under which the `vmemmap_shift` is set. |
| 8/2 | 2026/07/28 01:27 | tool | grepper |
0mArgs:{
"Expression": "memmap_init_compound",
"PathPrefix": "mm/"
}Results: {
"Output": "mm/mm_init.c=1115=static inline unsigned long compound_nr_pages(unsigned long pfn,\n--\nmm/mm_init.c-1130-\nmm/mm_init.c:1131:static void __ref memmap_init_compound(struct page *head,\nmm/mm_init.c-1132-\t\t\t\t unsigned long head_pfn,\n--\nmm/mm_init.c=1172=void __ref memmap_init_zone_device(struct zone *zone,\n--\nmm/mm_init.c-1223-\nmm/mm_init.c:1224:\t\tmemmap_init_compound(page, pfn, zone_idx, nid, pgmap,\nmm/mm_init.c-1225-\t\t\t\t compound_nr_pages(pfn, altmap, pgmap));\n"
} |
| 9/2 | 2026/07/28 01:27 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 12579 output: 24 thoughts: 198 Thoughts: **Fuzzing Kernel Memory Initialization** Okay, so this patch introduces `memcpy_nontemporal` and integrates it into `zone_device_page_init_from_template`. Essentially, it's an optimization for initializing `struct page` specifically for ZONE_DEVICE memory. It’s definitely core kernel functionality, which immediately makes me think, "Worth fuzzing?" Absolutely, it's part of the kernel's functional core. Let’s zero in on some key symbols. I'm thinking `memmap_init_zone_device` and `memmap_init_compound`. Now, these are called during device probe – think Persistent Memory, Direct Access (DAX), and potentially peer-to-peer DMA. Are they *hot* paths, meaning heavily used during normal operation? No, they're initialization functions, so they are not hot. But, are they *reachable*? Yes, definitely. Every time a device utilizing these memory types is probed, or memory is hotplugged, these functions come into play. To actually get to this code, the configuration dependency is `CONFIG_ZONE_DEVICE`. Time to check the dependencies of `CONFIG_ZONE_DEVICE`. |
| 10/2 | 2026/07/28 01:27 | tool | grepper |
0mArgs:{
"Expression": "config ZONE_DEVICE",
"PathPrefix": ""
}Results: {
"Output": "mm/Kconfig=1231=config ZONE_DMA32\n--\nmm/Kconfig-1235-\nmm/Kconfig:1236:config ZONE_DEVICE\nmm/Kconfig-1237-\tbool \"Device memory (pmem, HMM, etc...) hotplug support\"\n"
} |
| 11/2 | 2026/07/28 01:27 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 13138 output: 33 thoughts: 16 Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person: **Investigating ZONE_DEVICE in mm/Kconfig** Right, let's dive straight in. I need to get a clear picture of how `ZONE_DEVICE` is configured. My initial instinct is to go directly to `mm/Kconfig`. It's the central place for memory management options within the kernel's Kconfig system, and that's where I'd expect to find the definition and any accompanying dependencies or default values for a memory zone related configuration option. That's the logical starting point for understanding its role and potential impact on system behavior. Time to crack open that file and get to it. |
| 12/2 | 2026/07/28 01:27 | tool | read-file |
0mArgs:{
"File": "mm/Kconfig",
"FirstLine": 1236,
"LineCount": 20
}Results: {
"Contents": "1236:\tconfig ZONE_DEVICE\n1237:\t\tbool \"Device memory (pmem, HMM, etc...) hotplug support\"\n1238:\t\tdepends on MEMORY_HOTPLUG\n1239:\t\tdepends on MEMORY_HOTREMOVE\n1240:\t\tdepends on SPARSEMEM_VMEMMAP\n1241:\t\tselect XARRAY_MULTI\n1242:\t\n1243:\t\thelp\n1244:\t\t Device memory hotplug support allows for establishing pmem,\n1245:\t\t or other device driver discovered memory regions, in the\n1246:\t\t memmap. This allows pfn_to_page() lookups of otherwise\n1247:\t\t \"device-physical\" addresses which is needed for DAX, PCI_P2PDMA, and\n1248:\t\t DEVICE_PRIVATE features among others.\n1249:\t\n1250:\t\t Enabling this option will reduce the entropy of x86 KASLR memory\n1251:\t\t regions. For example - on a 46 bit system, the entropy goes down\n1252:\t\t from 16 bits to 15 bits. The actual reduction in entropy depends\n1253:\t\t on the physical address bits, on processor features, kernel config\n1254:\t\t (5 level page table) and physical memory present on the system.\n1255:\t\n"
} |
| 13/2 | 2026/07/28 01:27 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 13698 output: 27 thoughts: 126 Thoughts: **My Current Analysis of ZONE_DEVICE Dependencies** Okay, so I'm digging into `ZONE_DEVICE` and what it needs to function correctly. It looks like `ZONE_DEVICE` has a pretty clear dependency tree – it's fundamentally linked to `MEMORY_HOTPLUG`, `MEMORY_HOTREMOVE`, and `SPARSEMEM_VMEMMAP`. Makes sense, considering it's dealing with memory regions that are added and removed dynamically. Therefore, I need to make sure `ZONE_DEVICE` is definitely enabled in my configuration. Now, the trick is figuring out *how* to actually trigger this functionality. It seems like we'll need a device driver that's specifically written to utilize `devm_memremap_pages`. That's a key piece of the puzzle. Beyond the driver, I'm thinking about the wider ecosystem that would support this. The way to do that looks to be through: `CONFIG_PCI_P2PDMA` or `CONFIG_DAX` or `CONFIG_NVDIMM_DAX` or `CONFIG_DEV_DAX` or `CONFIG_FS_DAX`. I will need to understand what each of these options does, in order to get the full picture. I think a good starting point is probably `CONFIG_PCI_P2PDMA`. I will start by looking into that one first, to see where it leads. |
| 14/2 | 2026/07/28 01:27 | tool | grepper |
0mArgs:{
"Expression": "config PCI_P2PDMA",
"PathPrefix": ""
}Results: {
"Output": "drivers/pci/Kconfig=197=config PCIE_TPH\n--\ndrivers/pci/Kconfig-205-\ndrivers/pci/Kconfig:206:config PCI_P2PDMA\ndrivers/pci/Kconfig-207-\tbool \"PCI peer-to-peer transfer support\"\n"
} |
| 15/2 | 2026/07/28 01:27 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 14240 output: 35 thoughts: 22 Thoughts: Here's a summary of my thought process, as requested: **PCI_P2PDMA Configuration Inspection** Okay, so I need to figure out the configuration options related to PCI Peer-to-Peer DMA support. The kernel configuration system is a beast, but the usual starting point for PCI-related options is the `drivers/pci/Kconfig` file. I'm going to head over there to see what's defined for `PCI_P2PDMA`. Hopefully, the description in `Kconfig` is clear enough to understand the implications of enabling or disabling it. I expect it will reference some underlying DMA controller options or perhaps specific hardware requirements. Then I'll correlate it with the code to get an understanding of the impact to the kernel. |
| 16/2 | 2026/07/28 01:27 | tool | read-file |
0mArgs:{
"File": "drivers/pci/Kconfig",
"FirstLine": 206,
"LineCount": 10
}Results: {
"Contents": " 206:\tconfig PCI_P2PDMA\n 207:\t\tbool \"PCI peer-to-peer transfer support\"\n 208:\t\tdepends on ZONE_DEVICE\n 209:\t\t#\n 210:\t\t# The need for the scatterlist DMA bus address flag means PCI P2PDMA\n 211:\t\t# requires 64bit\n 212:\t\t#\n 213:\t\tdepends on 64BIT\n 214:\t\tselect GENERIC_ALLOCATOR\n 215:\t\tselect NEED_SG_DMA_FLAGS\n"
} |
| 17/2 | 2026/07/28 01:27 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 14608 output: 23 thoughts: 31 Thoughts: Okay, here's my interpretation of those thoughts, presented as a personal thought process, as requested: **Considering Dependencies for PCI_P2PDMA** Alright, let's break this down. I'm looking at `PCI_P2PDMA`, and immediately, my mind jumps to its dependencies. I know it leans heavily on `ZONE_DEVICE` – that makes perfect sense for direct access. And, naturally, `64BIT` is essential; we're dealing with potentially large address spaces here. But... what about the broader context? Is it fully compatible with everything within `CONFIG_DAX`? Is it just a dependency or is there any interaction? Are there any specific considerations that arise at the interaction between those two features? I need to dig into the details a bit more to be sure I'm not missing any critical conflicts or performance implications. Perhaps there are some interaction scenarios, like what happen when DMA happens against DAX-enabled storage. |
| 18/2 | 2026/07/28 01:27 | tool | grepper |
0mArgs:{
"Expression": "config DAX",
"PathPrefix": ""
}Results: {
"Output": "drivers/dax/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/dax/Kconfig:2:menuconfig DAX\ndrivers/dax/Kconfig-3-\ttristate \"DAX: direct access to differentiated memory\"\n"
} |
| 19/2 | 2026/07/28 01:27 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 14941 output: 33 thoughts: 13 Thoughts: Here's my thought process, summarized as you requested: **Kconfig Dive for DAX Driver Configuration** Okay, so I need to figure out the configuration options for the DAX driver. The first logical step, as always, is to head directly to the `Kconfig` file. That's the central hub for defining and documenting these things. Specifically, I'm going to look at `drivers/dax/Kconfig`. This is where I'd expect to find the dependencies, default settings, and descriptions that govern how the DAX driver behaves and is configured at compile time. I need to understand what knobs I have available to tweak this driver. Let's see what's in there. |
| 20/2 | 2026/07/28 01:27 | tool | read-file |
0mArgs:{
"File": "drivers/dax/Kconfig",
"FirstLine": 2,
"LineCount": 20
}Results: {
"Contents": " 2:\tmenuconfig DAX\n 3:\t\ttristate \"DAX: direct access to differentiated memory\"\n 4:\t\tdefault m if NVDIMM_DAX\n 5:\t\n 6:\tif DAX\n 7:\t\n 8:\tconfig DEV_DAX\n 9:\t\ttristate \"Device DAX: direct access mapping device\"\n 10:\t\tdepends on TRANSPARENT_HUGEPAGE\n 11:\t\thelp\n 12:\t\t Support raw access to differentiated (persistence, bandwidth,\n 13:\t\t latency...) memory via an mmap(2) capable character\n 14:\t\t device. Platform firmware or a device driver may identify a\n 15:\t\t platform memory resource that is differentiated from the\n 16:\t\t baseline memory pool. Mappings of a /dev/daxX.Y device impose\n 17:\t\t restrictions that make the mapping behavior deterministic.\n 18:\t\n 19:\tconfig DEV_DAX_PMEM\n 20:\t\ttristate \"PMEM DAX: direct access to persistent memory\"\n 21:\t\tdepends on LIBNVDIMM \u0026\u0026 NVDIMM_DAX \u0026\u0026 DEV_DAX\n"
} |
| 21/2 | 2026/07/28 01:27 | llm | patch-evaluator |
1mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 15433 output: 25 thoughts: 21 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience like yourself: **DAX Considerations** Alright, so I'm thinking about Direct Access (DAX). `DEV_DAX`, definitely a solid approach, proven and well-understood. It's usually the first thing that comes to mind when you're optimizing for direct block-device access. But...and here's where my mind starts to wander...what about `CONFIG_FS_DAX`? That option really makes you consider the filesystem-level DAX implementation. This gives more fine grained control. I'm evaluating which gives me the best trade-off between implementation complexity, performance, and flexibility depending on the specific application scenario. It's a key consideration. |
| 22/2 | 2026/07/28 01:28 | tool | grepper |
0mArgs:{
"Expression": "config FS_DAX",
"PathPrefix": ""
}Results: {
"Output": "fs/Kconfig=56=endif # BLOCK\nfs/Kconfig-57-\nfs/Kconfig:58:config FS_DAX\nfs/Kconfig-59-\tbool \"File system based Direct Access (DAX) support\"\n--\nfs/Kconfig-89-\nfs/Kconfig:90:config FS_DAX_PMD\nfs/Kconfig-91-\tbool\n"
} |
| 23/2 | 2026/07/28 01:28 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 15749 output: 31 thoughts: 17 Thoughts: Here's my thought process, as if I were considering this myself: **Investigating the `FS_DAX` Kconfig Option** Okay, so I need to understand how the system is configured for Direct Access (DAX) file systems. My first instinct, as always, is to dive right into the heart of the matter: `fs/Kconfig`. This is where all the file system-related configuration options are defined. I want to check for the presence and details of `FS_DAX`. I'm expecting to find its definition there. I know from experience that this file will contain the necessary settings controlling how DAX support is enabled or disabled and any accompanying dependencies or default values. Let's see what we've got. |
| 24/2 | 2026/07/28 01:28 | tool | read-file |
0mArgs:{
"File": "fs/Kconfig",
"FirstLine": 58,
"LineCount": 10
}Results: {
"Contents": " 58:\tconfig FS_DAX\n 59:\t\tbool \"File system based Direct Access (DAX) support\"\n 60:\t\tdepends on MMU\n 61:\t\tdepends on ZONE_DEVICE\n 62:\t\tselect FS_IOMAP\n 63:\t\tselect DAX\n 64:\t\thelp\n 65:\t\t Direct Access (DAX) can be used on memory-backed block devices.\n 66:\t\t If the block device supports DAX and the filesystem supports DAX,\n 67:\t\t then you can avoid using the pagecache to buffer I/Os. Turning\n"
} |
| 25/2 | 2026/07/28 01:28 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 16113 output: 31 thoughts: 138 Thoughts: **My Configuration Review** Okay, so I'm digging into this configuration and it's pretty straightforward at first glance. It looks like `FS_DAX` is built on top of `ZONE_DEVICE`, which makes perfect sense. To enable everything correctly, I need to include `ZONE_DEVICE`, `PCI_P2PDMA`, `DAX`, `DEV_DAX`, and `FS_DAX` in the `EnableConfigs`. That covers the dependencies nicely. But then there's this change to `arch/x86/include/asm/string_64.h`. Ah, `memcpy_nontemporal` using `movnti` instructions. This is x86-specific, which means I need to be careful. I know I need to look for any existing config options around `memcpy_nontemporal`, to ensure this is handled correctly. Let's see... it's guarded by `#ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE`. Okay, so that's the key. I need to make sure I take the architecture-specific constraint into consideration. I need to review and ensure that this specific configuration is appropriately handled to prevent any issues. |
| 26/2 | 2026/07/28 01:28 | tool | grepper |
0mArgs:{
"Expression": "config ARCH_HAS_UACCESS_FLUSHCACHE",
"PathPrefix": ""
}Results: {
"Output": "lib/Kconfig=542=config UACCESS_MEMCPY\n--\nlib/Kconfig-544-\nlib/Kconfig:545:config ARCH_HAS_UACCESS_FLUSHCACHE\nlib/Kconfig-546-\tbool\n"
} |
| 27/2 | 2026/07/28 01:28 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 16610 output: 32 thoughts: 23 Thoughts: Okay, let's dive into this. Here's how I'd approach this task, as if these were my internal thoughts: **Investigating `ARCH_HAS_UACCESS_FLUSHCACHE` in the Kconfig** Right, let's get down to brass tacks. First things first, I need to check the `lib/Kconfig` file. Specifically, I'm looking for the definition, or at least the presence, of `ARCH_HAS_UACCESS_FLUSHCACHE`. This is the key piece I need to understand. I'm assuming, given the naming, that it's related to cache coherency and data access, particularly in the context of user-space interactions. I need to understand if this is something being defined at the architecture level. This is a crucial first step for figuring out the dependencies and possible configurations relating to this feature. I'll need to see how it's defined, under what conditions it's enabled, and which architectures or boards are affected. Let's see what the Kconfig has to say. |
| 28/2 | 2026/07/28 01:28 | tool | read-file |
0mArgs:{
"File": "lib/Kconfig",
"FirstLine": 545,
"LineCount": 10
}Results: {
"Contents": " 545:\tconfig ARCH_HAS_UACCESS_FLUSHCACHE\n 546:\t\tbool\n 547:\t\n 548:\t# arch has a concept of a recoverable synchronous exception due to a\n 549:\t# memory-read error like x86 machine-check or ARM data-abort, and\n 550:\t# implements copy_mc_to_{user,kernel} to abort and report\n 551:\t# 'bytes-transferred' if that exception fires when accessing the source\n 552:\t# buffer.\n 553:\tconfig ARCH_HAS_COPY_MC\n 554:\t\tbool\n"
} |
| 29/2 | 2026/07/28 01:28 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 17060 output: 31 thoughts: 15 Thoughts: Here's my thought process, as if I were considering this myself: **Architecture Selection Analysis** Okay, so something has been selected, and the key driver seems to be "architectures." My immediate thought is to delve into the selection process. Who exactly made this choice? What architects or architectural teams were involved? I need to understand the decision-makers. My analysis will begin by identifying the specific architectures or architectural styles that influenced this selection. Are we talking about software architectures, system architectures, network architectures, or something else entirely? Understanding the domain is crucial. From there, I'll try to find out who the key players in those architectural contexts are. This information will inform my investigation into the rationale behind the decision and any potential implications that the architecture selection might have. |
| 30/2 | 2026/07/28 01:28 | tool | grepper |
0mArgs:{
"Expression": "select ARCH_HAS_UACCESS_FLUSHCACHE",
"PathPrefix": ""
}Results: {
"Output": "arch/arm64/Kconfig=1922=config ARM64_PMEM\n--\narch/arm64/Kconfig-1924-\tselect ARCH_HAS_PMEM_API\narch/arm64/Kconfig:1925:\tselect ARCH_HAS_UACCESS_FLUSHCACHE\narch/arm64/Kconfig-1926-\thelp\n--\narch/powerpc/Kconfig=118=config PPC\n--\narch/powerpc/Kconfig-158-\tselect ARCH_HAS_TICK_BROADCAST\t\tif GENERIC_CLOCKEVENTS_BROADCAST\narch/powerpc/Kconfig:159:\tselect ARCH_HAS_UACCESS_FLUSHCACHE\narch/powerpc/Kconfig-160-\tselect ARCH_HAS_UBSAN\n--\narch/x86/Kconfig=58=config X86\n--\narch/x86/Kconfig-102-\tselect ARCH_HAS_NONLEAF_PMD_YOUNG\tif PGTABLE_LEVELS \u003e 2\narch/x86/Kconfig:103:\tselect ARCH_HAS_UACCESS_FLUSHCACHE\tif X86_64\narch/x86/Kconfig-104-\tselect ARCH_HAS_COPY_MC\t\t\tif X86_64\n"
} |
| 31/2 | 2026/07/28 01:28 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 17601 output: 36 thoughts: 120 Thoughts: **Fuzzing Strategy Assessment** Okay, so this code is being targeted specifically for `X86_64` architecture, which makes sense given the potential performance implications we're likely dealing with. The fact that it's selected like that indicates a real, live scenario. The initial assessment is that this patch is definitely functional and ripe for fuzzing. We have a set of interesting focus symbols identified: `memmap_init_zone_device`, `memmap_init_compound`, `zone_device_page_init_from_template`, `zone_device_tail_page_init`, and `zone_device_page_init_slow`. These seem like good entry points to expose memory management issues. However, hang on... `zone_device_page_init_from_template` is marked as `static inline`? That means it's probably expanded at the call site, which has implications for how the fuzzer will behave and for control flow tracking. Gotta check `mm/mm_init.c` to see how it's being used. |
| 32/2 | 2026/07/28 01:29 | tool | read-file |
0mArgs:{
"File": "mm/mm_init.c",
"FirstLine": 1088,
"LineCount": 20
}Results: {
"Contents": "1088:\t\tset_page_section_from_pfn(template, pfn);\n1089:\t#ifdef WANT_PAGE_VIRTUAL\n1090:\t\tif (!is_highmem_idx(ZONE_DEVICE))\n1091:\t\t\tset_page_address(template, __va(pfn \u003c\u003c PAGE_SHIFT));\n1092:\t#endif\n1093:\t}\n1094:\t\n1095:\tstatic void zone_device_page_init_from_template(struct page *page,\n1096:\t\t\tunsigned long pfn, struct page *template)\n1097:\t{\n1098:\t\t/*\n1099:\t\t * 'template' carries the invariant portion of a ZONE_DEVICE struct\n1100:\t\t * page. Update the PFN-dependent fields in place before copying it\n1101:\t\t * to the destination page.\n1102:\t\t */\n1103:\t\tzone_device_page_update_template(template, pfn);\n1104:\t\tmemcpy_nontemporal(page, template, sizeof(*page));\n1105:\t}\n1106:\t\n1107:\t/*\n"
} |
| 33/2 | 2026/07/28 01:29 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 18294 output: 174 thoughts: 425 Thoughts: **Analyzing the Symbol Landscape** Okay, let's break down this code. I'm seeing a pattern here with memory management and device integration. First, looking at the initialization functions, `zone_device_page_init_from_template` is declared static, but *not* inline, which is interesting. On the other hand, `zone_device_tail_page_init` is static inline, and `zone_device_page_init_slow` is simply static. I need to keep that in mind when tracing calls and symbol visibility. My initial focus needs to be on: * `memmap_init_zone_device` * `memmap_init_compound` * `zone_device_page_init_from_template` * `zone_device_page_init_slow` Wait, hang on. This patch also modifies `arch/x86/include/asm/string_64.h`. It's adding a bunch of new inline functions - `movnti_8`, `movnti_16`, `movnti_32`, `movnti_64`, `memcpy_flushcache`, and `memcpy_nontemporal`. These are *all* `static __always_inline`, so they won't have their own exported symbols. That reinforces my original list as the key symbols to track. Now, I need to confirm the reachability of `memmap_init_zone_device`. Let's see... Yes, it's called from `pagemap_range` in `mm/memremap.c`. And `pagemap_range` is called from `devm_memremap_pages`. Excellent. `devm_memremap_pages` is exported, and it's used by various drivers. Good, this is a reasonable starting point. Finally, regarding configuration, it looks like this patch is related to these options: `ZONE_DEVICE`, `PCI_P2PDMA`, `DAX`, `DEV_DAX`, and `FS_DAX`. I need to ensure the system is properly configured. Let's make sure `ZONE_DEVICE` doesn't have any dependencies I need to address. Hmmm, yes, it depends on `MEMORY_HOTPLUG`, and `MEMORY_HOTREMOVE` and `SPARSEMEM_VMEMMAP`. So, to be safe, I'll add `MEMORY_HOTPLUG` and `SPARSEMEM_VMEMMAP` to the config, just in case. |
| 34/2 | 2026/07/28 01:29 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"ZONE_DEVICE",
"PCI_P2PDMA",
"DAX",
"DEV_DAX",
"FS_DAX",
"MEMORY_HOTPLUG",
"SPARSEMEM_VMEMMAP"
],
"FocusSymbols": [
"memmap_init_zone_device",
"memmap_init_compound",
"zone_device_page_init_from_template",
"zone_device_page_init_slow"
],
"Reasoning": "The patch optimizes the initialization of ZONE_DEVICE pages by using a template and non-temporal memcpy. This is core memory management logic that is reachable when probing devices like PMEM, DAX, or PCI P2PDMA.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"ZONE_DEVICE",
"PCI_P2PDMA",
"DAX",
"DEV_DAX",
"FS_DAX",
"MEMORY_HOTPLUG",
"SPARSEMEM_VMEMMAP"
],
"FocusSymbols": [
"memmap_init_zone_device",
"memmap_init_compound",
"zone_device_page_init_from_template",
"zone_device_page_init_slow"
],
"Reasoning": "The patch optimizes the initialization of ZONE_DEVICE pages by using a template and non-temporal memcpy. This is core memory management logic that is reachable when probing devices like PMEM, DAX, or PCI P2PDMA.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|