| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/23 01:16 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"BPF_SYSCALL"
],
"FocusSymbols": [
"array_map_mmap_fault",
"bpf_map_mmap_fault",
"array_map_mmap"
],
"Reasoning": "The patch introduces lazy page faulting for BPF array maps mapped to user space. It modifies `array_map_mmap` to not eagerly map the memory and adds `array_map_mmap_fault` and `bpf_map_mmap_fault` to handle page faults on demand. This is a functional change in the core BPF subsystem and is reachable from user space by creating and mmap-ing a BPF array map.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/23 01:16 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 44a8b6fdfecd7f3112675f76f8e8520ef9b69048\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Thu Jul 23 01:16:44 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/include/linux/bpf.h b/include/linux/bpf.h\nindex e066f44a9c0580..b536f3c9e1036b 100644\n--- a/include/linux/bpf.h\n+++ b/include/linux/bpf.h\n@@ -145,6 +145,7 @@ struct bpf_map_ops {\n \tint (*map_direct_value_meta)(const struct bpf_map *map,\n \t\t\t\t u64 imm, u32 *off);\n \tint (*map_mmap)(struct bpf_map *map, struct vm_area_struct *vma);\n+\tvm_fault_t (*map_mmap_fault)(struct bpf_map *map, struct vm_fault *vmf);\n \t__poll_t (*map_poll)(struct bpf_map *map, struct file *filp,\n \t\t\t struct poll_table_struct *pts);\n \tunsigned long (*map_get_unmapped_area)(struct file *filep, unsigned long addr,\ndiff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c\nindex 248b4818178cd1..1711be582907dc 100644\n--- a/kernel/bpf/arraymap.c\n+++ b/kernel/bpf/arraymap.c\n@@ -576,7 +576,6 @@ static int array_map_check_btf(struct bpf_map *map,\n static int array_map_mmap(struct bpf_map *map, struct vm_area_struct *vma)\n {\n \tstruct bpf_array *array = container_of(map, struct bpf_array, map);\n-\tpgoff_t pgoff = PAGE_ALIGN(sizeof(*array)) \u003e\u003e PAGE_SHIFT;\n \n \tif (!(map-\u003emap_flags \u0026 BPF_F_MMAPABLE))\n \t\treturn -EINVAL;\n@@ -585,8 +584,42 @@ static int array_map_mmap(struct bpf_map *map, struct vm_area_struct *vma)\n \t PAGE_ALIGN((u64)array-\u003emap.max_entries * array-\u003eelem_size))\n \t\treturn -EINVAL;\n \n-\treturn remap_vmalloc_range(vma, array_map_vmalloc_addr(array),\n-\t\t\t\t vma-\u003evm_pgoff + pgoff);\n+\t/*\n+\t * The backing memory is vmalloc'ed up front, so instead of wiring up\n+\t * every PTE here we let array_map_mmap_fault() insert pages on demand.\n+\t * remap_vmalloc_range_partial() used to set these flags for us; keep\n+\t * them to preserve behavior (no VMA expansion, excluded from coredump).\n+\t */\n+\tvm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);\n+\n+\treturn 0;\n+}\n+\n+static vm_fault_t array_map_mmap_fault(struct bpf_map *map,\n+\t\t\t\t struct vm_fault *vmf)\n+{\n+\tstruct bpf_array *array = container_of(map, struct bpf_array, map);\n+\tpgoff_t pgoff = PAGE_ALIGN(sizeof(*array)) \u003e\u003e PAGE_SHIFT;\n+\tstruct page *page;\n+\tvoid *kaddr;\n+\n+\t/*\n+\t * vmf-\u003epgoff is the page offset within the mapping (vma-\u003evm_pgoff plus\n+\t * the offset of the faulting address). The data pages start after the\n+\t * bpf_array header, hence the extra pgoff. This mirrors the offset that\n+\t * remap_vmalloc_range(vma, ..., vma-\u003evm_pgoff + pgoff) used to apply.\n+\t */\n+\tkaddr = array_map_vmalloc_addr(array) +\n+\t\t((u64)(vmf-\u003epgoff + pgoff) \u003c\u003c PAGE_SHIFT);\n+\n+\tpage = vmalloc_to_page(kaddr);\n+\tif (!page)\n+\t\treturn VM_FAULT_SIGBUS;\n+\n+\tget_page(page);\n+\tvmf-\u003epage = page;\n+\n+\treturn 0;\n }\n \n static bool array_map_meta_equal(const struct bpf_map *meta0,\n@@ -812,6 +845,7 @@ const struct bpf_map_ops array_map_ops = {\n \t.map_direct_value_addr = array_map_direct_value_addr,\n \t.map_direct_value_meta = array_map_direct_value_meta,\n \t.map_mmap = array_map_mmap,\n+\t.map_mmap_fault = array_map_mmap_fault,\n \t.map_seq_show_elem = array_map_seq_show_elem,\n \t.map_check_btf = array_map_check_btf,\n \t.map_lookup_batch = generic_map_lookup_batch,\ndiff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c\nindex 0ff9e3aa293d57..fb0e1f55c4873d 100644\n--- a/kernel/bpf/syscall.c\n+++ b/kernel/bpf/syscall.c\n@@ -1077,9 +1077,26 @@ static void bpf_map_mmap_close(struct vm_area_struct *vma)\n \t\tbpf_map_write_active_dec(map);\n }\n \n+/*\n+ * Called for maps that populate their memory-mapped region lazily, i.e. that\n+ * return without wiring up any PTEs from their -\u003emap_mmap callback. Maps that\n+ * populate the whole VMA eagerly (e.g. via remap_vmalloc_range()) never reach\n+ * here.\n+ */\n+static vm_fault_t bpf_map_mmap_fault(struct vm_fault *vmf)\n+{\n+\tstruct bpf_map *map = vmf-\u003evma-\u003evm_private_data;\n+\n+\tif (!map-\u003eops-\u003emap_mmap_fault)\n+\t\treturn VM_FAULT_SIGBUS;\n+\n+\treturn map-\u003eops-\u003emap_mmap_fault(map, vmf);\n+}\n+\n static const struct vm_operations_struct bpf_map_default_vmops = {\n \t.open\t\t= bpf_map_mmap_open,\n \t.close\t\t= bpf_map_mmap_close,\n+\t.fault\t\t= bpf_map_mmap_fault,\n };\n \n static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)\ndiff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile\nindex 55d394438705a6..b6593fb1135b29 100644\n--- a/tools/testing/selftests/bpf/Makefile\n+++ b/tools/testing/selftests/bpf/Makefile\n@@ -1003,6 +1003,7 @@ $(OUTPUT)/bench: $(OUTPUT)/bench.o \\\n \t\t $(OUTPUT)/bench_bpf_timing.o \\\n \t\t $(OUTPUT)/bench_bpf_nop.o \\\n \t\t $(OUTPUT)/bench_xdp_lb.o \\\n+\t\t $(OUTPUT)/bench_arraymap_mmap.o \\\n \t\t $(OUTPUT)/usdt_1.o \\\n \t\t $(OUTPUT)/usdt_2.o \\\n \t\t #\ndiff --git a/tools/testing/selftests/bpf/bench.c b/tools/testing/selftests/bpf/bench.c\nindex 3d9d2cd7764bd3..192d5fcb7a748f 100644\n--- a/tools/testing/selftests/bpf/bench.c\n+++ b/tools/testing/selftests/bpf/bench.c\n@@ -287,6 +287,7 @@ extern struct argp bench_crypto_argp;\n extern struct argp bench_sockmap_argp;\n extern struct argp bench_lpm_trie_map_argp;\n extern struct argp bench_xdp_lb_argp;\n+extern struct argp bench_arraymap_mmap_argp;\n \n static const struct argp_child bench_parsers[] = {\n \t{ \u0026bench_ringbufs_argp, 0, \"Ring buffers benchmark\", 0 },\n@@ -304,6 +305,7 @@ static const struct argp_child bench_parsers[] = {\n \t{ \u0026bench_sockmap_argp, 0, \"bpf sockmap benchmark\", 0 },\n \t{ \u0026bench_lpm_trie_map_argp, 0, \"LPM trie map benchmark\", 0 },\n \t{ \u0026bench_xdp_lb_argp, 0, \"XDP load-balancer benchmark\", 0 },\n+\t{ \u0026bench_arraymap_mmap_argp, 0, \"arraymap-mmap benchmark\", 0 },\n \t{},\n };\n \n@@ -582,6 +584,7 @@ extern const struct bench bench_lpm_trie_delete;\n extern const struct bench bench_lpm_trie_free;\n extern const struct bench bench_bpf_nop;\n extern const struct bench bench_xdp_lb;\n+extern const struct bench bench_arraymap_mmap;\n \n static const struct bench *benchs[] = {\n \t\u0026bench_count_global,\n@@ -665,6 +668,7 @@ static const struct bench *benchs[] = {\n \t\u0026bench_lpm_trie_free,\n \t\u0026bench_bpf_nop,\n \t\u0026bench_xdp_lb,\n+\t\u0026bench_arraymap_mmap,\n };\n \n static void find_benchmark(void)\ndiff --git a/tools/testing/selftests/bpf/benchs/bench_arraymap_mmap.c b/tools/testing/selftests/bpf/benchs/bench_arraymap_mmap.c\nnew file mode 100644\nindex 00000000000000..356d80a85cf01e\n--- /dev/null\n+++ b/tools/testing/selftests/bpf/benchs/bench_arraymap_mmap.c\n@@ -0,0 +1,146 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/* Copyright (c) 2026 Meta Platforms, Inc. */\n+#include \u003cargp.h\u003e\n+#include \u003csys/mman.h\u003e\n+#include \"bench.h\"\n+\n+/* Benchmark mmap()/munmap() of an mmap-able BPF array map from N threads. */\n+\n+static struct ctx {\n+\tint map_fd;\n+\tsize_t mmap_sz;\n+} ctx;\n+\n+static struct {\n+\t__u32 nr_threads;\n+\t__u64 map_size;\n+} args = {\n+\t.nr_threads = 16,\n+\t.map_size = 8 * 1024 * 1024, /* 8 MiB */\n+};\n+\n+enum {\n+\tARG_NR_THREADS = 5000,\n+\tARG_MAP_SIZE = 5001,\n+};\n+\n+static const struct argp_option opts[] = {\n+\t{ \"nr-threads\", ARG_NR_THREADS, \"NR_THREADS\", 0,\n+\t\t\"Number of threads that mmap/munmap the map (default 16)\" },\n+\t{ \"map-size\", ARG_MAP_SIZE, \"BYTES\", 0,\n+\t\t\"Size of the BPF array map in bytes (default 8388608)\" },\n+\t{},\n+};\n+\n+static error_t parse_arg(int key, char *arg, struct argp_state *state)\n+{\n+\tswitch (key) {\n+\tcase ARG_NR_THREADS:\n+\t\targs.nr_threads = strtoul(arg, NULL, 0);\n+\t\tif (args.nr_threads == 0) {\n+\t\t\tfprintf(stderr, \"Invalid nr-threads: %s\\n\", arg);\n+\t\t\targp_usage(state);\n+\t\t}\n+\t\tbreak;\n+\tcase ARG_MAP_SIZE:\n+\t\targs.map_size = strtoull(arg, NULL, 0);\n+\t\tif (args.map_size == 0) {\n+\t\t\tfprintf(stderr, \"Invalid map-size: %s\\n\", arg);\n+\t\t\targp_usage(state);\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\treturn ARGP_ERR_UNKNOWN;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/* exported into benchmark runner */\n+const struct argp bench_arraymap_mmap_argp = {\n+\t.options = opts,\n+\t.parser = parse_arg,\n+};\n+\n+static void validate(void)\n+{\n+\tif (env.consumer_cnt != 0) {\n+\t\tfprintf(stderr, \"benchmark doesn't support consumer!\\n\");\n+\t\texit(1);\n+\t}\n+\n+\t/*\n+\t * The number of worker threads is controlled by --nr-threads and\n+\t * drives the framework's producer machinery, so per-producer stats\n+\t * are reported correctly.\n+\t */\n+\tenv.producer_cnt = args.nr_threads;\n+}\n+\n+static long hits;\n+\n+static void *producer(void *input)\n+{\n+\twhile (true) {\n+\t\tvoid *addr;\n+\n+\t\taddr = mmap(NULL, ctx.mmap_sz, PROT_READ | PROT_WRITE,\n+\t\t\t MAP_SHARED, ctx.map_fd, 0);\n+\t\tif (addr == MAP_FAILED) {\n+\t\t\tfprintf(stderr, \"mmap failed: %d\\n\", -errno);\n+\t\t\texit(1);\n+\t\t}\n+\t\tif (munmap(addr, ctx.mmap_sz)) {\n+\t\t\tfprintf(stderr, \"munmap failed: %d\\n\", -errno);\n+\t\t\texit(1);\n+\t\t}\n+\t\tatomic_inc(\u0026hits);\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+static void measure(struct bench_res *res)\n+{\n+\tres-\u003ehits = atomic_swap(\u0026hits, 0);\n+}\n+\n+static void setup(void)\n+{\n+\tLIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_MMAPABLE);\n+\tlong page_sz = sysconf(_SC_PAGESIZE);\n+\t__u32 value_size = sizeof(__u64);\n+\t__u32 max_entries;\n+\n+\tsetup_libbpf();\n+\n+\t/*\n+\t * mmap-able array maps round the value size up to 8 bytes and expose\n+\t * PAGE_ALIGN(max_entries * elem_size) bytes to user space.\n+\t */\n+\tmax_entries = (args.map_size + value_size - 1) / value_size;\n+\tctx.mmap_sz = ((__u64)max_entries * value_size + page_sz - 1) \u0026\n+\t\t ~(page_sz - 1);\n+\n+\tctx.map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, \"mmap_array\",\n+\t\t\t\t sizeof(__u32), value_size, max_entries,\n+\t\t\t\t \u0026opts);\n+\tif (ctx.map_fd \u003c 0) {\n+\t\tfprintf(stderr, \"failed to create map: %d\\n\", -errno);\n+\t\texit(1);\n+\t}\n+\n+\tprintf(\"array map: %u entries, mmap size %zu bytes, %u threads\\n\",\n+\t max_entries, ctx.mmap_sz, args.nr_threads);\n+}\n+\n+const struct bench bench_arraymap_mmap = {\n+\t.name = \"arraymap-mmap\",\n+\t.argp = \u0026bench_arraymap_mmap_argp,\n+\t.validate = validate,\n+\t.setup = setup,\n+\t.producer_thread = producer,\n+\t.measure = measure,\n+\t.report_progress = ops_report_progress,\n+\t.report_final = ops_report_final,\n+};\ndiff --git a/tools/testing/selftests/bpf/benchs/run_bench_arraymap_mmap.sh b/tools/testing/selftests/bpf/benchs/run_bench_arraymap_mmap.sh\nnew file mode 100755\nindex 00000000000000..3efd441cd653a2\n--- /dev/null\n+++ b/tools/testing/selftests/bpf/benchs/run_bench_arraymap_mmap.sh\n@@ -0,0 +1,15 @@\n+#!/bin/bash\n+# SPDX-License-Identifier: GPL-2.0\n+\n+source ./benchs/run_common.sh\n+\n+set -eufo pipefail\n+\n+for t in 1 4 8 16; do\n+for s in 1048576 8388608 67108864; do\n+subtitle \"nr_threads: $t, map_size: $s\"\n+\tsummarize_ops \"arraymap-mmap: \" \\\n+\t \"$($RUN_BENCH --nr-threads $t --map-size $s arraymap-mmap)\"\n+\tprintf \"\\n\"\n+done\n+done\n"
} |
| 2/1 | 2026/07/23 01:16 | agent | patch-evaluator |
0mModel:best-expensive Args: null Results: {
"EnableConfigs": [
"BPF_SYSCALL"
],
"FocusSymbols": [
"array_map_mmap_fault",
"bpf_map_mmap_fault",
"array_map_mmap"
],
"Reasoning": "The patch introduces lazy page faulting for BPF array maps mapped to user space. It modifies `array_map_mmap` to not eagerly map the memory and adds `array_map_mmap_fault` and `bpf_map_mmap_fault` to handle page faults on demand. This is a functional change in the core BPF subsystem and is reachable from user space by creating and mmap-ing a BPF array map.",
"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). 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. 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. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. 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 44a8b6fdfecd7f3112675f76f8e8520ef9b69048
Author: syz-cluster <triage@syzkaller.com>
Date: Thu Jul 23 01:16:44 2026 +0000
syz-cluster: applied patch under review
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index e066f44a9c0580..b536f3c9e1036b 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -145,6 +145,7 @@ struct bpf_map_ops {
int (*map_direct_value_meta)(const struct bpf_map *map,
u64 imm, u32 *off);
int (*map_mmap)(struct bpf_map *map, struct vm_area_struct *vma);
+ vm_fault_t (*map_mmap_fault)(struct bpf_map *map, struct vm_fault *vmf);
__poll_t (*map_poll)(struct bpf_map *map, struct file *filp,
struct poll_table_struct *pts);
unsigned long (*map_get_unmapped_area)(struct file *filep, unsigned long addr,
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index 248b4818178cd1..1711be582907dc 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -576,7 +576,6 @@ static int array_map_check_btf(struct bpf_map *map,
static int array_map_mmap(struct bpf_map *map, struct vm_area_struct *vma)
{
struct bpf_array *array = container_of(map, struct bpf_array, map);
- pgoff_t pgoff = PAGE_ALIGN(sizeof(*array)) >> PAGE_SHIFT;
if (!(map->map_flags & BPF_F_MMAPABLE))
return -EINVAL;
@@ -585,8 +584,42 @@ static int array_map_mmap(struct bpf_map *map, struct vm_area_struct *vma)
PAGE_ALIGN((u64)array->map.max_entries * array->elem_size))
return -EINVAL;
- return remap_vmalloc_range(vma, array_map_vmalloc_addr(array),
- vma->vm_pgoff + pgoff);
+ /*
+ * The backing memory is vmalloc'ed up front, so instead of wiring up
+ * every PTE here we let array_map_mmap_fault() insert pages on demand.
+ * remap_vmalloc_range_partial() used to set these flags for us; keep
+ * them to preserve behavior (no VMA expansion, excluded from coredump).
+ */
+ vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);
+
+ return 0;
+}
+
+static vm_fault_t array_map_mmap_fault(struct bpf_map *map,
+ struct vm_fault *vmf)
+{
+ struct bpf_array *array = container_of(map, struct bpf_array, map);
+ pgoff_t pgoff = PAGE_ALIGN(sizeof(*array)) >> PAGE_SHIFT;
+ struct page *page;
+ void *kaddr;
+
+ /*
+ * vmf->pgoff is the page offset within the mapping (vma->vm_pgoff plus
+ * the offset of the faulting address). The data pages start after the
+ * bpf_array header, hence the extra pgoff. This mirrors the offset that
+ * remap_vmalloc_range(vma, ..., vma->vm_pgoff + pgoff) used to apply.
+ */
+ kaddr = array_map_vmalloc_addr(array) +
+ ((u64)(vmf->pgoff + pgoff) << PAGE_SHIFT);
+
+ page = vmalloc_to_page(kaddr);
+ if (!page)
+ return VM_FAULT_SIGBUS;
+
+ get_page(page);
+ vmf->page = page;
+
+ return 0;
}
static bool array_map_meta_equal(const struct bpf_map *meta0,
@@ -812,6 +845,7 @@ const struct bpf_map_ops array_map_ops = {
.map_direct_value_addr = array_map_direct_value_addr,
.map_direct_value_meta = array_map_direct_value_meta,
.map_mmap = array_map_mmap,
+ .map_mmap_fault = array_map_mmap_fault,
.map_seq_show_elem = array_map_seq_show_elem,
.map_check_btf = array_map_check_btf,
.map_lookup_batch = generic_map_lookup_batch,
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 0ff9e3aa293d57..fb0e1f55c4873d 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1077,9 +1077,26 @@ static void bpf_map_mmap_close(struct vm_area_struct *vma)
bpf_map_write_active_dec(map);
}
+/*
+ * Called for maps that populate their memory-mapped region lazily, i.e. that
+ * return without wiring up any PTEs from their ->map_mmap callback. Maps that
+ * populate the whole VMA eagerly (e.g. via remap_vmalloc_range()) never reach
+ * here.
+ */
+static vm_fault_t bpf_map_mmap_fault(struct vm_fault *vmf)
+{
+ struct bpf_map *map = vmf->vma->vm_private_data;
+
+ if (!map->ops->map_mmap_fault)
+ return VM_FAULT_SIGBUS;
+
+ return map->ops->map_mmap_fault(map, vmf);
+}
+
static const struct vm_operations_struct bpf_map_default_vmops = {
.open = bpf_map_mmap_open,
.close = bpf_map_mmap_close,
+ .fault = bpf_map_mmap_fault,
};
static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 55d394438705a6..b6593fb1135b29 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -1003,6 +1003,7 @@ $(OUTPUT)/bench: $(OUTPUT)/bench.o \
$(OUTPUT)/bench_bpf_timing.o \
$(OUTPUT)/bench_bpf_nop.o \
$(OUTPUT)/bench_xdp_lb.o \
+ $(OUTPUT)/bench_arraymap_mmap.o \
$(OUTPUT)/usdt_1.o \
$(OUTPUT)/usdt_2.o \
#
diff --git a/tools/testing/selftests/bpf/bench.c b/tools/testing/selftests/bpf/bench.c
index 3d9d2cd7764bd3..192d5fcb7a748f 100644
--- a/tools/testing/selftests/bpf/bench.c
+++ b/tools/testing/selftests/bpf/bench.c
@@ -287,6 +287,7 @@ extern struct argp bench_crypto_argp;
extern struct argp bench_sockmap_argp;
extern struct argp bench_lpm_trie_map_argp;
extern struct argp bench_xdp_lb_argp;
+extern struct argp bench_arraymap_mmap_argp;
static const struct argp_child bench_parsers[] = {
{ &bench_ringbufs_argp, 0, "Ring buffers benchmark", 0 },
@@ -304,6 +305,7 @@ static const struct argp_child bench_parsers[] = {
{ &bench_sockmap_argp, 0, "bpf sockmap benchmark", 0 },
{ &bench_lpm_trie_map_argp, 0, "LPM trie map benchmark", 0 },
{ &bench_xdp_lb_argp, 0, "XDP load-balancer benchmark", 0 },
+ { &bench_arraymap_mmap_argp, 0, "arraymap-mmap benchmark", 0 },
{},
};
@@ -582,6 +584,7 @@ extern const struct bench bench_lpm_trie_delete;
extern const struct bench bench_lpm_trie_free;
extern const struct bench bench_bpf_nop;
extern const struct bench bench_xdp_lb;
+extern const struct bench bench_arraymap_mmap;
static const struct bench *benchs[] = {
&bench_count_global,
@@ -665,6 +668,7 @@ static const struct bench *benchs[] = {
&bench_lpm_trie_free,
&bench_bpf_nop,
&bench_xdp_lb,
+ &bench_arraymap_mmap,
};
static void find_benchmark(void)
diff --git a/tools/testing/selftests/bpf/benchs/bench_arraymap_mmap.c b/tools/testing/selftests/bpf/benchs/bench_arraymap_mmap.c
new file mode 100644
index 00000000000000..356d80a85cf01e
--- /dev/null
+++ b/tools/testing/selftests/bpf/benchs/bench_arraymap_mmap.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2026 Meta Platforms, Inc. */
+#include <argp.h>
+#include <sys/mman.h>
+#include "bench.h"
+
+/* Benchmark mmap()/munmap() of an mmap-able BPF array map from N threads. */
+
+static struct ctx {
+ int map_fd;
+ size_t mmap_sz;
+} ctx;
+
+static struct {
+ __u32 nr_threads;
+ __u64 map_size;
+} args = {
+ .nr_threads = 16,
+ .map_size = 8 * 1024 * 1024, /* 8 MiB */
+};
+
+enum {
+ ARG_NR_THREADS = 5000,
+ ARG_MAP_SIZE = 5001,
+};
+
+static const struct argp_option opts[] = {
+ { "nr-threads", ARG_NR_THREADS, "NR_THREADS", 0,
+ "Number of threads that mmap/munmap the map (default 16)" },
+ { "map-size", ARG_MAP_SIZE, "BYTES", 0,
+ "Size of the BPF array map in bytes (default 8388608)" },
+ {},
+};
+
+static error_t parse_arg(int key, char *arg, struct argp_state *state)
+{
+ switch (key) {
+ case ARG_NR_THREADS:
+ args.nr_threads = strtoul(arg, NULL, 0);
+ if (args.nr_threads == 0) {
+ fprintf(stderr, "Invalid nr-threads: %s\n", arg);
+ argp_usage(state);
+ }
+ break;
+ case ARG_MAP_SIZE:
+ args.map_size = strtoull(arg, NULL, 0);
+ if (args.map_size == 0) {
+ fprintf(stderr, "Invalid map-size: %s\n", arg);
+ argp_usage(state);
+ }
+ break;
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+
+ return 0;
+}
+
+/* exported into benchmark runner */
+const struct argp bench_arraymap_mmap_argp = {
+ .options = opts,
+ .parser = parse_arg,
+};
+
+static void validate(void)
+{
+ if (env.consumer_cnt != 0) {
+ fprintf(stderr, "benchmark doesn't support consumer!\n");
+ exit(1);
+ }
+
+ /*
+ * The number of worker threads is controlled by --nr-threads and
+ * drives the framework's producer machinery, so per-producer stats
+ * are reported correctly.
+ */
+ env.producer_cnt = args.nr_threads;
+}
+
+static long hits;
+
+static void *producer(void *input)
+{
+ while (true) {
+ void *addr;
+
+ addr = mmap(NULL, ctx.mmap_sz, PROT_READ | PROT_WRITE,
+ MAP_SHARED, ctx.map_fd, 0);
+ if (addr == MAP_FAILED) {
+ fprintf(stderr, "mmap failed: %d\n", -errno);
+ exit(1);
+ }
+ if (munmap(addr, ctx.mmap_sz)) {
+ fprintf(stderr, "munmap failed: %d\n", -errno);
+ exit(1);
+ }
+ atomic_inc(&hits);
+ }
+
+ return NULL;
+}
+
+static void measure(struct bench_res *res)
+{
+ res->hits = atomic_swap(&hits, 0);
+}
+
+static void setup(void)
+{
+ LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_MMAPABLE);
+ long page_sz = sysconf(_SC_PAGESIZE);
+ __u32 value_size = sizeof(__u64);
+ __u32 max_entries;
+
+ setup_libbpf();
+
+ /*
+ * mmap-able array maps round the value size up to 8 bytes and expose
+ * PAGE_ALIGN(max_entries * elem_size) bytes to user space.
+ */
+ max_entries = (args.map_size + value_size - 1) / value_size;
+ ctx.mmap_sz = ((__u64)max_entries * value_size + page_sz - 1) &
+ ~(page_sz - 1);
+
+ ctx.map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "mmap_array",
+ sizeof(__u32), value_size, max_entries,
+ &opts);
+ if (ctx.map_fd < 0) {
+ fprintf(stderr, "failed to create map: %d\n", -errno);
+ exit(1);
+ }
+
+ printf("array map: %u entries, mmap size %zu bytes, %u threads\n",
+ max_entries, ctx.mmap_sz, args.nr_threads);
+}
+
+const struct bench bench_arraymap_mmap = {
+ .name = "arraymap-mmap",
+ .argp = &bench_arraymap_mmap_argp,
+ .validate = validate,
+ .setup = setup,
+ .producer_thread = producer,
+ .measure = measure,
+ .report_progress = ops_report_progress,
+ .report_final = ops_report_final,
+};
diff --git a/tools/testing/selftests/bpf/benchs/run_bench_arraymap_mmap.sh b/tools/testing/selftests/bpf/benchs/run_bench_arraymap_mmap.sh
new file mode 100755
index 00000000000000..3efd441cd653a2
--- /dev/null
+++ b/tools/testing/selftests/bpf/benchs/run_bench_arraymap_mmap.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+source ./benchs/run_common.sh
+
+set -eufo pipefail
+
+for t in 1 4 8 16; do
+for s in 1048576 8388608 67108864; do
+subtitle "nr_threads: $t, map_size: $s"
+ summarize_ops "arraymap-mmap: " \
+ "$($RUN_BENCH --nr-threads $t --map-size $s arraymap-mmap)"
+ printf "\n"
+done
+done
|
| 3/2 | 2026/07/23 01:16 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 6131 output: 23 thoughts: 269 Thoughts: **My Initial Assessment of the BPF Array Map mmap Patch** Okay, so I'm looking at this patch and immediately, I see that this is a potentially significant change to BPF array map memory management. The core idea is shifting from eagerly mapping the memory with `remap_vmalloc_range` in `array_map_mmap` to a lazy, demand-paged approach. The use of `VM_DONTEXPAND | VM_DONTDUMP` flags is a clear indicator of this, along with the introduction of this `map_mmap_fault` callback which will now handle the page faults. This is a fundamental shift, and I need to understand it in detail. I know this will affect performance and resource usage. Essentially, they're making BPF array maps behave more like typical memory regions, where pages are only allocated and mapped when they're actually accessed. This could have performance implications, both positive and negative. I need to think through the scenarios: What's the impact of the initial access overhead? How does this influence overall memory consumption? Is it going to be a win in terms of reduced memory footprint for large arrays, or will the added fault handling cost outweigh the benefits in certain workloads? This needs some careful consideration. The fact that they've modified `bpf_map_mmap` in `kernel/bpf/syscall.c` to hook up the fault handler in `bpf_map_default_vmops` is the key. It means they're integrating the lazy mapping within the BPF system call interface, which makes perfect sense. They've updated the `map->ops->map_mmap_fault` call. Right, so to get a handle on this, I need to focus on these functions: `array_map_mmap`, `array_map_mmap_fault`, and `bpf_map_mmap_fault`. I'm going to do a quick `grep` for `bpf_map_mmap_fault` and `array_map_mmap_fault` to figure out where these are being called from and to see what interactions exist. I need to see how these map faults are triggered, handled, and how memory is allocated on demand. This is going to give me a solid start to analyzing the changes. |
| 4/2 | 2026/07/23 01:16 | tool | grepper |
0mArgs:{
"Expression": "bpf_map_mmap_fault"
}Results: {
"Output": "kernel/bpf/syscall.c=1072=static void bpf_map_mmap_close(struct vm_area_struct *vma)\n--\nkernel/bpf/syscall.c-1085- */\nkernel/bpf/syscall.c:1086:static vm_fault_t bpf_map_mmap_fault(struct vm_fault *vmf)\nkernel/bpf/syscall.c-1087-{\n--\nkernel/bpf/syscall.c=1096=static const struct vm_operations_struct bpf_map_default_vmops = {\n--\nkernel/bpf/syscall.c-1098-\t.close\t\t= bpf_map_mmap_close,\nkernel/bpf/syscall.c:1099:\t.fault\t\t= bpf_map_mmap_fault,\nkernel/bpf/syscall.c-1100-};\n"
} |
| 5/2 | 2026/07/23 01:16 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 7147 output: 22 thoughts: 15 Thoughts: Here's my thought process, summarized as you requested: **Debugging Initiative: The `array_map_mmap_fault` Investigation** Okay, time to get to the heart of this problem. My initial instinct is to dig directly into the source code and logs, and the best tool for that, given the context, is `grep`. I want to zero in on the specific issue or function call that's causing this `array_map_mmap_fault`. This likely points to a memory-related issue, probably with memory mapping and how an `array_map` function is interacting with it. I'll need to use `grep` to hunt down instances of that specific term, `array_map_mmap_fault`. This will give me a starting point – where this specific error or function is being called or referenced. From there, I can analyze the surrounding code to understand the context and root cause. I'm hoping this will lead me to the problematic logic quickly. Let's see what `grep` uncovers. |
| 6/2 | 2026/07/23 01:17 | tool | grepper |
0mArgs:{
"Expression": "array_map_mmap_fault"
}Results: {
"Output": "kernel/bpf/arraymap.c=576=static int array_map_mmap(struct bpf_map *map, struct vm_area_struct *vma)\n--\nkernel/bpf/arraymap.c-588-\t * The backing memory is vmalloc'ed up front, so instead of wiring up\nkernel/bpf/arraymap.c:589:\t * every PTE here we let array_map_mmap_fault() insert pages on demand.\nkernel/bpf/arraymap.c-590-\t * remap_vmalloc_range_partial() used to set these flags for us; keep\n--\nkernel/bpf/arraymap.c-597-\nkernel/bpf/arraymap.c:598:static vm_fault_t array_map_mmap_fault(struct bpf_map *map,\nkernel/bpf/arraymap.c-599-\t\t\t\t struct vm_fault *vmf)\n--\nkernel/bpf/arraymap.c=834=const struct bpf_map_ops array_map_ops = {\n--\nkernel/bpf/arraymap.c-847-\t.map_mmap = array_map_mmap,\nkernel/bpf/arraymap.c:848:\t.map_mmap_fault = array_map_mmap_fault,\nkernel/bpf/arraymap.c-849-\t.map_seq_show_elem = array_map_seq_show_elem,\n"
} |
| 7/2 | 2026/07/23 01:17 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 7774 output: 21 thoughts: 88 Thoughts: Okay, here's my assessment of the situation: **Functional Patch Analysis** Alright, so the patch itself seems solid – it's functional and I can confirm that the code path it modifies is reachable, which is a good starting point. My focus needs to be laser-sharp on `array_map_mmap_fault` and `bpf_map_mmap_fault`, those are the key functions to dig into. It looks like `array_map_mmap` itself has also seen some modifications, so that's worth keeping an eye on as well. Now, before I dive too deep into the code, let's nail down the configuration requirements. We already know that `CONFIG_BPF_SYSCALL` is essential, that's a given. But I need to double-check, ensure there aren't any other, more obscure configurations that this patch depends on. Understanding the build environment dependencies is key to confirming this change works as expected in various setups. I need to make sure this is going to play nice with all our deployment options. |
| 8/2 | 2026/07/23 01:17 | tool | grepper |
0mArgs:{
"Expression": "config BPF_SYSCALL"
}Results: {
"Output": "kernel/bpf/Kconfig=25=menu \"BPF subsystem\"\nkernel/bpf/Kconfig-26-\nkernel/bpf/Kconfig:27:config BPF_SYSCALL\nkernel/bpf/Kconfig-28-\tbool \"Enable bpf() system call\"\n"
} |
| 9/2 | 2026/07/23 01:17 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8192 output: 18 thoughts: 15 Thoughts: Okay, let's see. My first thought is: **Checking Conditional Compilation of `arraymap.c`** Alright, before I dive too deep, I need to confirm something. I'm going to quickly check if `arraymap.c` is compiled based on a particular condition. This could be a macro, a feature flag, or something else entirely. It's critical to understand the build process and which parts of the code are actually included in different configurations. Understanding the conditions around compilation of this file is foundational before continuing. I need to know why and how it's included, or excluded. |
| 10/2 | 2026/07/23 01:17 | tool | grepper |
0mArgs:{
"Expression": "arraymap.o"
}Results: {
"Output": "kernel/bpf/Makefile=10=obj-$(CONFIG_BPF_SYSCALL) += bpf_iter.o map_iter.o task_iter.o prog_iter.o link_iter.o\nkernel/bpf/Makefile:11:obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o bloom_filter.o\nkernel/bpf/Makefile-12-obj-$(CONFIG_BPF_SYSCALL) += local_storage.o queue_stack_maps.o ringbuf.o bpf_insn_array.o\n--\ntools/testing/selftests/bpf/prog_tests/for_each.c=79=static void test_array_map(void)\n--\ntools/testing/selftests/bpf/prog_tests/for_each.c-130-\ntools/testing/selftests/bpf/prog_tests/for_each.c:131:\tASSERT_EQ(skel-\u003ebss-\u003earraymap_output, expected_total, \"array_output\");\ntools/testing/selftests/bpf/prog_tests/for_each.c-132-\tASSERT_EQ(skel-\u003ebss-\u003ecpu + 1, skel-\u003ebss-\u003epercpu_val, \"percpu_val\");\n--\ntools/testing/selftests/bpf/progs/for_each_array_map_elem.c=50=check_percpu_elem(struct bpf_map *map, __u32 *key, __u64 *val,\n--\ntools/testing/selftests/bpf/progs/for_each_array_map_elem.c-57-\ntools/testing/selftests/bpf/progs/for_each_array_map_elem.c:58:u32 arraymap_output = 0;\ntools/testing/selftests/bpf/progs/for_each_array_map_elem.c-59-\n--\ntools/testing/selftests/bpf/progs/for_each_array_map_elem.c=61=int test_pkt_access(struct __sk_buff *skb)\n--\ntools/testing/selftests/bpf/progs/for_each_array_map_elem.c-68-\t\tbpf_for_each_map_elem(\u0026arraymap, unused_subprog, \u0026data, 0);\ntools/testing/selftests/bpf/progs/for_each_array_map_elem.c:69:\tarraymap_output = data.output;\ntools/testing/selftests/bpf/progs/for_each_array_map_elem.c-70-\n"
} |
| 11/2 | 2026/07/23 01:17 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 9043 output: 17 thoughts: 38 Thoughts: Okay, here's my take on those thoughts, framed as my own mental process: **Diving into BPF Syscall Configuration** Alright, let's get down to brass tacks. It looks like `CONFIG_BPF_SYSCALL` is the critical configuration option here. That's the main entry point, the keystone. But, hold on a second... are there *any* other config knobs that might influence the BPF syscall behavior, even indirectly? I can't be sure, I should really check. Let's head over to the source code. The most logical place to start digging would be `kernel/bpf/syscall.c`. That file should give me a solid view of the syscall's implementation and how it might be affected by various other compilation options or kernel settings. Time to get my hands dirty. Let's see what we can uncover! |
| 12/2 | 2026/07/23 01:17 | tool | grepper |
0mArgs:{
"Expression": "syscall.o"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 818 lines.\nUse more precise expression if possible.\n\nDocumentation/filesystems/caching/cachefiles.rst=396=circumstances the caching code is running in the security context of whatever\nDocumentation/filesystems/caching/cachefiles.rst:397:process issued the original syscall on the netfs.\nDocumentation/filesystems/caching/cachefiles.rst-398-\n--\nDocumentation/trace/ftrace.rst=90=of ftrace. Here is a list of some of the key files:\n--\nDocumentation/trace/ftrace.rst-186-\tbefore a waiter is woken up. That is, if an application calls a\nDocumentation/trace/ftrace.rst:187:\tblocking read syscall on one of the per_cpu trace_pipe_raw files, it\nDocumentation/trace/ftrace.rst-188-\twill block until the given amount of data specified by buffer_percent\n--\nDocumentation/userspace-api/rseq.rst=216=operation.\nDocumentation/userspace-api/rseq.rst-217-\nDocumentation/userspace-api/rseq.rst:218:If the thread issues a syscall other than rseq_slice_yield(2) within the\nDocumentation/userspace-api/rseq.rst-219-granted timeslice extension, the grant is also revoked and the CPU is\n--\narch/arm64/include/asm/processor.h=305=static inline void start_thread_common(struct pt_regs *regs, unsigned long pc,\n--\narch/arm64/include/asm/processor.h-318-\t * To allow the syscalls:sys_exit_execve tracepoint we need to preserve\narch/arm64/include/asm/processor.h:319:\t * syscallno, but do not need orig_x0 or the original GPRs.\narch/arm64/include/asm/processor.h-320-\t */\n--\narch/arm64/include/asm/ptrace.h-88-/*\narch/arm64/include/asm/ptrace.h:89: * If pt_regs.syscallno == NO_SYSCALL, then the thread is not executing\narch/arm64/include/asm/ptrace.h-90- * a syscall -- i.e., its most recent entry into the kernel from\n--\narch/arm64/include/asm/ptrace.h=156=struct pt_regs {\n--\narch/arm64/include/asm/ptrace.h-166-\tu64 orig_x0;\narch/arm64/include/asm/ptrace.h:167:\ts32 syscallno;\narch/arm64/include/asm/ptrace.h-168-\tu32 pmr;\n--\narch/arm64/include/asm/ptrace.h=177=static inline bool in_syscall(struct pt_regs const *regs)\narch/arm64/include/asm/ptrace.h-178-{\narch/arm64/include/asm/ptrace.h:179:\treturn regs-\u003esyscallno != NO_SYSCALL;\narch/arm64/include/asm/ptrace.h-180-}\n--\narch/arm64/include/asm/ptrace.h=182=static inline void forget_syscall(struct pt_regs *regs)\narch/arm64/include/asm/ptrace.h-183-{\narch/arm64/include/asm/ptrace.h:184:\tregs-\u003esyscallno = NO_SYSCALL;\narch/arm64/include/asm/ptrace.h-185-}\n--\narch/arm64/include/asm/syscall.h=20=static inline int syscall_get_nr(struct task_struct *task,\n--\narch/arm64/include/asm/syscall.h-22-{\narch/arm64/include/asm/syscall.h:23:\treturn regs-\u003esyscallno;\narch/arm64/include/asm/syscall.h-24-}\n--\narch/arm64/include/asm/syscall.h=64=static inline void syscall_set_nr(struct task_struct *task,\n--\narch/arm64/include/asm/syscall.h-67-{\narch/arm64/include/asm/syscall.h:68:\tregs-\u003esyscallno = nr;\narch/arm64/include/asm/syscall.h-69-\tif (nr == -1) {\n--\narch/arm64/kernel/Makefile=10=CFLAGS_REMOVE_return_address.o = $(CC_FLAGS_FTRACE)\n--\narch/arm64/kernel/Makefile-13-# checks due to randomize_kstack_offset.\narch/arm64/kernel/Makefile:14:CFLAGS_REMOVE_syscall.o\t = -fstack-protector -fstack-protector-strong\narch/arm64/kernel/Makefile:15:CFLAGS_syscall.o\t+= -fno-stack-protector\narch/arm64/kernel/Makefile-16-\n--\narch/arm64/kernel/Makefile=29=obj-y\t\t\t:= debug-monitors.o entry.o irq.o fpsimd.o\t\t\\\n--\narch/arm64/kernel/Makefile-35-\t\t\t smp.o smp_spin_table.o topology.o smccc-call.o\t\\\narch/arm64/kernel/Makefile:36:\t\t\t syscall.o proton-pack.o idle.o patching.o pi/\t\\\narch/arm64/kernel/Makefile-37-\t\t\t rsi.o jump_label.o\n--\narch/arm64/kernel/asm-offsets.c=27=int main(void)\n--\narch/arm64/kernel/asm-offsets.c-75- DEFINE(S_PSTATE,\t\toffsetof(struct pt_regs, pstate));\narch/arm64/kernel/asm-offsets.c:76: DEFINE(S_SYSCALLNO,\t\toffsetof(struct pt_regs, syscallno));\narch/arm64/kernel/asm-offsets.c-77- DEFINE(S_SDEI_TTBR1,\t\toffsetof(struct pt_regs, sdei_ttbr1));\n--\narch/arm64/kernel/ptrace.c=736=static int system_call_get(struct task_struct *target,\n--\narch/arm64/kernel/ptrace.c-739-{\narch/arm64/kernel/ptrace.c:740:\treturn membuf_store(\u0026to, task_pt_regs(target)-\u003esyscallno);\narch/arm64/kernel/ptrace.c-741-}\n--\narch/arm64/kernel/ptrace.c=743=static int system_call_set(struct task_struct *target,\n--\narch/arm64/kernel/ptrace.c-747-{\narch/arm64/kernel/ptrace.c:748:\tint syscallno = task_pt_regs(target)-\u003esyscallno;\narch/arm64/kernel/ptrace.c-749-\tint ret;\narch/arm64/kernel/ptrace.c-750-\narch/arm64/kernel/ptrace.c:751:\tret = user_regset_copyin(\u0026pos, \u0026count, \u0026kbuf, \u0026ubuf, \u0026syscallno, 0, -1);\narch/arm64/kernel/ptrace.c-752-\tif (ret)\n--\narch/arm64/kernel/ptrace.c-754-\narch/arm64/kernel/ptrace.c:755:\ttask_pt_regs(target)-\u003esyscallno = syscallno;\narch/arm64/kernel/ptrace.c-756-\treturn ret;\n--\narch/arm64/kernel/ptrace.c=2235=long compat_arch_ptrace(struct task_struct *child, compat_long_t request,\n--\narch/arm64/kernel/ptrace.c-2273-\t\tcase COMPAT_PTRACE_SET_SYSCALL:\narch/arm64/kernel/ptrace.c:2274:\t\t\ttask_pt_regs(child)-\u003esyscallno = data;\narch/arm64/kernel/ptrace.c-2275-\t\t\tret = 0;\n--\narch/arm64/kernel/ptrace.c=2411=int syscall_trace_enter(struct pt_regs *regs)\n--\narch/arm64/kernel/ptrace.c-2426-\tif (test_thread_flag(TIF_SYSCALL_TRACEPOINT))\narch/arm64/kernel/ptrace.c:2427:\t\ttrace_sys_enter(regs, regs-\u003esyscallno);\narch/arm64/kernel/ptrace.c-2428-\narch/arm64/kernel/ptrace.c:2429:\taudit_syscall_entry(regs-\u003esyscallno, regs-\u003eorig_x0, regs-\u003eregs[1],\narch/arm64/kernel/ptrace.c-2430-\t\t\t regs-\u003eregs[2], regs-\u003eregs[3]);\narch/arm64/kernel/ptrace.c-2431-\narch/arm64/kernel/ptrace.c:2432:\treturn regs-\u003esyscallno;\narch/arm64/kernel/ptrace.c-2433-}\n--\narch/arm64/kernel/syscall.c=62=static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,\n--\narch/arm64/kernel/syscall.c-67-\tregs-\u003eorig_x0 = regs-\u003eregs[0];\narch/arm64/kernel/syscall.c:68:\tregs-\u003esyscallno = scno;\narch/arm64/kernel/syscall.c-69-\n--\narch/csky/kernel/Makefile=4=obj-y += head.o entry.o atomic.o signal.o traps.o irq.o time.o vdso.o vdso/\narch/csky/kernel/Makefile:5:obj-y += power.o syscall.o syscall_table.o setup.o\narch/csky/kernel/Makefile-6-obj-y += process.o cpu-probe.o ptrace.o stacktrace.o\n--\narch/loongarch/kernel/Makefile=10=obj-y\t\t+= head.o cpu-probe.o cacheinfo.o env.o setup.o entry.o genex.o \\\narch/loongarch/kernel/Makefile-11-\t\t traps.o irq.o idle.o process.o dma.o mem.o reset.o switch.o \\\narch/loongarch/kernel/Makefile:12:\t\t elf.o syscall.o signal.o time.o topology.o inst.o ptrace.o vdso.o \\\narch/loongarch/kernel/Makefile-13-\t\t alternative.o kdebugfs.o unwind.o\n--\narch/loongarch/kernel/Makefile=24=CFLAGS_module.o\t\t+= $(call cc-disable-warning, override-init)\narch/loongarch/kernel/Makefile:25:CFLAGS_syscall.o\t+= $(call cc-disable-warning, override-init)\narch/loongarch/kernel/Makefile-26-CFLAGS_traps.o\t\t+= $(call cc-disable-warning, override-init)\n--\narch/mips/include/uapi/asm/inst.h=44=enum spec_op {\n--\narch/mips/include/uapi/asm/inst.h-47-\tjr_op, jalr_op, movz_op, movn_op,\narch/mips/include/uapi/asm/inst.h:48:\tsyscall_op, break_op, spim_op, sync_op,\narch/mips/include/uapi/asm/inst.h-49-\tmfhi_op, mthi_op, mflo_op, mtlo_op,\n--\narch/mips/include/uapi/asm/inst.h=442=enum mm_32axf_minor_op {\n--\narch/mips/include/uapi/asm/inst.h-458-\tmm_sync_op = 0x1ad,\narch/mips/include/uapi/asm/inst.h:459:\tmm_syscall_op = 0x22d,\narch/mips/include/uapi/asm/inst.h-460-\tmm_wait_op = 0x24d,\n--\narch/mips/kernel/Makefile=8=obj-y\t\t+= head.o branch.o cmpxchg.o elf.o entry.o genex.o idle.o irq.o \\\narch/mips/kernel/Makefile-9-\t\t process.o prom.o ptrace.o reset.o setup.o signal.o \\\narch/mips/kernel/Makefile:10:\t\t syscall.o time.o topology.o traps.o unaligned.o watch.o \\\narch/mips/kernel/Makefile-11-\t\t vdso.o cacheinfo.o\n--\narch/mips/kernel/scall32-o32.S=25=NESTED(handle_sys, PT_SIZE, sp)\n--\narch/mips/kernel/scall32-o32.S-31-\narch/mips/kernel/scall32-o32.S:32:\tlw\tt1, PT_EPC(sp)\t\t# skip syscall on return\narch/mips/kernel/scall32-o32.S-33-\n--\narch/mips/kernel/scall64-n32.S=26=NESTED(handle_sysn32, PT_SIZE, sp)\n--\narch/mips/kernel/scall64-n32.S-38-#ifndef CONFIG_MIPS32_O32\narch/mips/kernel/scall64-n32.S:39:\tld\tt1, PT_EPC(sp)\t\t# skip syscall on return\narch/mips/kernel/scall64-n32.S-40-\tdaddiu\tt1, 4\t\t\t# skip to next instruction\n--\narch/mips/kernel/scall64-n64.S=28=NESTED(handle_sys64, PT_SIZE, sp)\n--\narch/mips/kernel/scall64-n64.S-41-#if !defined(CONFIG_MIPS32_O32) \u0026\u0026 !defined(CONFIG_MIPS32_N32)\narch/mips/kernel/scall64-n64.S:42:\tld\tt1, PT_EPC(sp)\t\t# skip syscall on return\narch/mips/kernel/scall64-n64.S-43-\tdaddiu\tt1, 4\t\t\t# skip to next instruction\n--\narch/mips/kernel/scall64-o32.S=28=NESTED(handle_sys, PT_SIZE, sp)\n--\narch/mips/kernel/scall64-o32.S-33-\t.set\tat\narch/mips/kernel/scall64-o32.S:34:\tld\tt1, PT_EPC(sp)\t\t# skip syscall on return\narch/mips/kernel/scall64-o32.S-35-\n--\narch/mips/kernel/syscall.c-45-/*\narch/mips/kernel/syscall.c:46: * For historic reasons the pipe(2) syscall on MIPS has an unusual calling\narch/mips/kernel/syscall.c-47- * convention.\tIt returns results in registers $v0 / $v1 which means there\n--\narch/mips/mm/uasm-micromips.c=42=static const struct insn insn_table_MM[insn_invalid] = {\n--\narch/mips/mm/uasm-micromips.c-123-\t[insn_dinsm]\t= {0, 0},\narch/mips/mm/uasm-micromips.c:124:\t[insn_syscall]\t= {M(mm_pool32a_op, 0, 0, 0, mm_syscall_op, mm_pool32axf_op), SCIMM},\narch/mips/mm/uasm-micromips.c-125-\t[insn_bbit0]\t= {0, 0},\n--\narch/mips/mm/uasm-mips.c=50=static const struct insn insn_table[insn_invalid] = {\n--\narch/mips/mm/uasm-mips.c-195-\t[insn_sync]\t= {M(spec_op, 0, 0, 0, 0, sync_op), RE},\narch/mips/mm/uasm-mips.c:196:\t[insn_syscall]\t= {M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},\narch/mips/mm/uasm-mips.c-197-\t[insn_tlbp]\t= {M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0},\n--\narch/openrisc/include/asm/ptrace.h-32- * This struct describes how the registers are laid out on the kernel stack\narch/openrisc/include/asm/ptrace.h:33: * during a syscall or other kernel entry.\narch/openrisc/include/asm/ptrace.h-34- *\n--\narch/parisc/kernel/Makefile=8=obj-y\t\t:= head.o cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \\\narch/parisc/kernel/Makefile:9:\t\t syscall.o entry.o sys_parisc.o firmware.o \\\narch/parisc/kernel/Makefile-10-\t\t ptrace.o hardware.o inventory.o drivers.o alternative.o \\\n--\narch/parisc/kernel/signal.c=383=handle_signal(struct ksignal *ksig, struct pt_regs *regs, long in_syscall)\n--\narch/parisc/kernel/signal.c-405-\narch/parisc/kernel/signal.c:406:static void check_syscallno_in_delay_branch(struct pt_regs *regs)\narch/parisc/kernel/signal.c-407-{\n--\narch/parisc/kernel/signal.c=451=syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)\n--\narch/parisc/kernel/signal.c-476-\t\tDBG(1, \"%s: %ld\\n\", __func__, regs-\u003egr[28]);\narch/parisc/kernel/signal.c:477:\t\tcheck_syscallno_in_delay_branch(regs);\narch/parisc/kernel/signal.c-478-\t\tbreak;\n--\narch/parisc/kernel/signal.c=483=insert_restart_trampoline(struct pt_regs *regs)\n--\narch/parisc/kernel/signal.c-533-\t\tDBG(1, \"%s: Type %ld\\n\", __func__, regs-\u003egr[28]);\narch/parisc/kernel/signal.c:534:\t\tcheck_syscallno_in_delay_branch(regs);\narch/parisc/kernel/signal.c-535-\t\treturn;\n--\narch/parisc/kernel/syscall.S=131=linux_gateway_entry:\n--\narch/parisc/kernel/syscall.S-185-\t saved/restored). TASK_PT_PSW is zeroed so we can see whether\narch/parisc/kernel/syscall.S:186:\t a process is on a syscall or not. For an interrupt the real\narch/parisc/kernel/syscall.S-187-\t PSW value is stored. This is needed for gdb and sys_ptrace. */\n--\narch/parisc/kernel/syscall.S=348=tracesys_next:\narch/parisc/kernel/syscall.S:349:\t/* do_syscall_trace_enter either returned the syscallno, or -1L,\narch/parisc/kernel/syscall.S-350-\t * so we skip restoring the PT_GR20 below, since we pulled it from\n--\narch/parisc/kernel/vdso32/Makefile=10=KCSAN_SANITIZE := n\narch/parisc/kernel/vdso32/Makefile-11-\narch/parisc/kernel/vdso32/Makefile:12:obj-vdso32 = note.o sigtramp.o restart_syscall.o\narch/parisc/kernel/vdso32/Makefile-13-obj-cvdso32 = vdso32_generic.o\n--\narch/parisc/kernel/vdso64/Makefile=10=KCSAN_SANITIZE := n\narch/parisc/kernel/vdso64/Makefile-11-\narch/parisc/kernel/vdso64/Makefile:12:obj-vdso64 = note.o sigtramp.o restart_syscall.o\narch/parisc/kernel/vdso64/Makefile-13-obj-cvdso64 = vdso64_generic.o\n--\narch/powerpc/kernel/Makefile=58=KCSAN_SANITIZE_setup_64.o := n\n--\narch/powerpc/kernel/Makefile-62-# checks due to randomize_kstack_offset.\narch/powerpc/kernel/Makefile:63:CFLAGS_REMOVE_syscall.o = -fstack-protector -fstack-protector-strong\narch/powerpc/kernel/Makefile:64:CFLAGS_syscall.o += -fno-stack-protector\narch/powerpc/kernel/Makefile-65-#endif\n--\narch/powerpc/kernel/Makefile=67=obj-y\t\t\t\t:= cputable.o syscalls.o switch.o \\\n--\narch/powerpc/kernel/Makefile-74-\t\t\t\t hw_breakpoint_constraints.o interrupt.o \\\narch/powerpc/kernel/Makefile:75:\t\t\t\t kdebugfs.o stacktrace.o syscall.o\narch/powerpc/kernel/Makefile-76-obj-y\t\t\t\t+= ptrace/\n--\narch/powerpc/kernel/rtas.c=48=struct rtas_filter {\n--\narch/powerpc/kernel/rtas.c-67- * generally allowed, and @filter describes constraints on the\narch/powerpc/kernel/rtas.c:68: * arguments. See also @banned_for_syscall_on_le.\narch/powerpc/kernel/rtas.c:69: * @banned_for_syscall_on_le: Set when call via sys_rtas is generally allowed\narch/powerpc/kernel/rtas.c-70- * but specifically restricted on ppc64le. Such\n--\narch/powerpc/kernel/rtas.c=83=struct rtas_function {\narch/powerpc/kernel/rtas.c-84-\ts32 token;\narch/powerpc/kernel/rtas.c:85:\tconst bool banned_for_syscall_on_le:1;\narch/powerpc/kernel/rtas.c-86-\tconst char * const name;\n--\narch/powerpc/kernel/rtas.c=104=static struct rtas_function rtas_function_table[] __ro_after_init = {\n--\narch/powerpc/kernel/rtas.c-455-\t\t.name = \"ibm,suspend-me\",\narch/powerpc/kernel/rtas.c:456:\t\t.banned_for_syscall_on_le = true,\narch/powerpc/kernel/rtas.c-457-\t\t.filter = \u0026(const struct rtas_filter) {\n--\narch/powerpc/kernel/rtas.c-469-\t\t.name = \"ibm,update-nodes\",\narch/powerpc/kernel/rtas.c:470:\t\t.banned_for_syscall_on_le = true,\narch/powerpc/kernel/rtas.c-471-\t\t.filter = \u0026(const struct rtas_filter) {\n--\narch/powerpc/kernel/rtas.c-478-\t\t.name = \"ibm,update-properties\",\narch/powerpc/kernel/rtas.c:479:\t\t.banned_for_syscall_on_le = true,\narch/powerpc/kernel/rtas.c-480-\t\t.filter = \u0026(const struct rtas_filter) {\n--\narch/powerpc/kernel/rtas.c=1776=static bool block_rtas_call(const struct rtas_function *func, int nargs,\n--\narch/powerpc/kernel/rtas.c-1794-\t */\narch/powerpc/kernel/rtas.c:1795:\tif (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN) \u0026\u0026 func-\u003ebanned_for_syscall_on_le)\narch/powerpc/kernel/rtas.c-1796-\t\tgoto err;\n--\narch/riscv/kernel/signal.c=413=static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,\n--\narch/riscv/kernel/signal.c-447-\t * For the nommu case we don't have a VDSO. Instead we push two\narch/riscv/kernel/signal.c:448:\t * instructions to call the rt_sigreturn syscall onto the user stack.\narch/riscv/kernel/signal.c-449-\t */\n--\narch/s390/kernel/Makefile=39=obj-y\t:= head.o traps.o time.o process.o early.o setup.o idle.o vtime.o\narch/s390/kernel/Makefile:40:obj-y\t+= processor.o syscall.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o\narch/s390/kernel/Makefile-41-obj-y\t+= debug.o irq.o ipl.o dis.o vdso.o cpufeature.o\n--\narch/sh/kernel/vsyscall/Makefile-1-# SPDX-License-Identifier: GPL-2.0\narch/sh/kernel/vsyscall/Makefile:2:obj-y += vsyscall.o vsyscall-syscall.o vsyscall-syms.o\narch/sh/kernel/vsyscall/Makefile-3-\narch/sh/kernel/vsyscall/Makefile:4:$(obj)/vsyscall-syscall.o: $(obj)/vsyscall-trapa.so\narch/sh/kernel/vsyscall/Makefile-5-\n--\narch/sh/kernel/vsyscall/vsyscall.c=34=static const struct ctl_table vdso_table[] = {\n--\narch/sh/kernel/vsyscall/vsyscall.c-46-/*\narch/sh/kernel/vsyscall/vsyscall.c:47: * These symbols are defined by vsyscall.o to mark the bounds\narch/sh/kernel/vsyscall/vsyscall.c-48- * of the ELF DSO images included therein.\n--\narch/um/kernel/skas/Makefile-5-\narch/um/kernel/skas/Makefile:6:obj-y := stub.o mmu.o process.o syscall.o uaccess.o \\\narch/um/kernel/skas/Makefile-7-\t stub_exe_embed.o\n--\narch/x86/include/asm/syscall_wrapper.h=12=extern long __ia32_sys_ni_syscall(const struct pt_regs *regs);\n--\narch/x86/include/asm/syscall_wrapper.h-17- * __x64_sys_*() - 64-bit native syscall\narch/x86/include/asm/syscall_wrapper.h:18: * __ia32_sys_*() - 32-bit native syscall or common compat syscall\narch/x86/include/asm/syscall_wrapper.h-19- * __ia32_compat_sys_*() - 32-bit compat syscall\n--\narch/xtensa/kernel/Makefile=8=obj-y := head.o align.o coprocessor.o entry.o irq.o platform.o process.o \\\narch/xtensa/kernel/Makefile:9:\t ptrace.o setup.o signal.o stacktrace.o syscall.o time.o traps.o \\\narch/xtensa/kernel/Makefile-10-\t vectors.o\n--\ndrivers/gpu/drm/i915/gem/i915_gem_mman.c=29=__vma_matches(struct vm_area_struct *vma, struct file *filp,\n--\ndrivers/gpu/drm/i915/gem/i915_gem_mman.c-53- * to implement DRM mmap support is with an mmap offset ioctl (like\ndrivers/gpu/drm/i915/gem/i915_gem_mman.c:54: * i915_gem_mmap_gtt) and then using the mmap syscall on the DRM fd directly.\ndrivers/gpu/drm/i915/gem/i915_gem_mman.c-55- * That way debug tooling like valgrind will understand what's going on, hiding\n--\ndrivers/pci/Makefile=28=obj-$(CONFIG_X86_INTEL_MID)\t+= pci-mid.o\ndrivers/pci/Makefile:29:obj-$(CONFIG_PCI_SYSCALL)\t+= syscall.o\ndrivers/pci/Makefile-30-obj-$(CONFIG_PCI_STUB)\t\t+= pci-stub.o\n--\nfs/kernfs/dir.c=1003=unsigned int kernfs_root_flags(struct kernfs_node *kn)\n--\nfs/kernfs/dir.c-1009- * kernfs_create_root - create a new kernfs hierarchy\nfs/kernfs/dir.c:1010: * @scops: optional syscall operations for the hierarchy\nfs/kernfs/dir.c-1011- * @flags: KERNFS_ROOT_* flags\n--\nfs/kernfs/dir.c-1016- */\nfs/kernfs/dir.c:1017:struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,\nfs/kernfs/dir.c-1018-\t\t\t\t unsigned int flags, void *priv)\n--\nfs/kernfs/dir.c-1057-\nfs/kernfs/dir.c:1058:\troot-\u003esyscall_ops = scops;\nfs/kernfs/dir.c-1059-\troot-\u003eflags = flags;\n--\nfs/kernfs/dir.c=1291=static struct dentry *kernfs_iop_mkdir(struct mnt_idmap *idmap,\n--\nfs/kernfs/dir.c-1295-\tstruct kernfs_node *parent = dir-\u003ei_private;\nfs/kernfs/dir.c:1296:\tstruct kernfs_syscall_ops *scops = kernfs_root(parent)-\u003esyscall_ops;\nfs/kernfs/dir.c-1297-\tint ret;\n--\nfs/kernfs/dir.c=1311=static int kernfs_iop_rmdir(struct inode *dir, struct dentry *dentry)\n--\nfs/kernfs/dir.c-1313-\tstruct kernfs_node *kn = kernfs_dentry_node(dentry);\nfs/kernfs/dir.c:1314:\tstruct kernfs_syscall_ops *scops = kernfs_root(kn)-\u003esyscall_ops;\nfs/kernfs/dir.c-1315-\tint ret;\n--\nfs/kernfs/dir.c=1329=static int kernfs_iop_rename(struct mnt_idmap *idmap,\n--\nfs/kernfs/dir.c-1335-\tstruct kernfs_node *new_parent = new_dir-\u003ei_private;\nfs/kernfs/dir.c:1336:\tstruct kernfs_syscall_ops *scops = kernfs_root(kn)-\u003esyscall_ops;\nfs/kernfs/dir.c-1337-\tint ret;\n--\nfs/kernfs/kernfs-internal.h=33=struct kernfs_root {\n--\nfs/kernfs/kernfs-internal.h-42-\tu32\t\t\tid_highbits;\nfs/kernfs/kernfs-internal.h:43:\tstruct kernfs_syscall_ops *syscall_ops;\nfs/kernfs/kernfs-internal.h-44-\n--\nfs/kernfs/mount.c=28=static int kernfs_sop_show_options(struct seq_file *sf, struct dentry *dentry)\n--\nfs/kernfs/mount.c-30-\tstruct kernfs_root *root = kernfs_root(kernfs_dentry_node(dentry));\nfs/kernfs/mount.c:31:\tstruct kernfs_syscall_ops *scops = root-\u003esyscall_ops;\nfs/kernfs/mount.c-32-\n--\nfs/kernfs/mount.c=38=static int kernfs_sop_show_path(struct seq_file *sf, struct dentry *dentry)\n--\nfs/kernfs/mount.c-41-\tstruct kernfs_root *root = kernfs_root(node);\nfs/kernfs/mount.c:42:\tstruct kernfs_syscall_ops *scops = root-\u003esyscall_ops;\nfs/kernfs/mount.c-43-\n--\nfs/resctrl/rdtgroup.c=4260=static int rdtgroup_show_options(struct seq_file *seq, struct kernfs_root *kf)\n--\nfs/resctrl/rdtgroup.c-4276-\nfs/resctrl/rdtgroup.c:4277:static struct kernfs_syscall_ops rdtgroup_kf_syscall_ops = {\nfs/resctrl/rdtgroup.c-4278-\t.mkdir\t\t= rdtgroup_mkdir,\n--\nfs/resctrl/rdtgroup.c=4284=static int rdtgroup_setup_root(struct rdt_fs_context *ctx)\nfs/resctrl/rdtgroup.c-4285-{\nfs/resctrl/rdtgroup.c:4286:\trdt_root = kernfs_create_root(\u0026rdtgroup_kf_syscall_ops,\nfs/resctrl/rdtgroup.c-4287-\t\t\t\t KERNFS_ROOT_CREATE_DEACTIVATED |\n--\ninclude/linux/kernfs.h=199=struct kernfs_node {\n--\ninclude/linux/kernfs.h-239-/*\ninclude/linux/kernfs.h:240: * kernfs_syscall_ops may be specified on kernfs_create_root() to support\ninclude/linux/kernfs.h-241- * syscalls. These optional callbacks are invoked on the matching syscalls\n--\ninclude/linux/kernfs.h-245- */\ninclude/linux/kernfs.h:246:struct kernfs_syscall_ops {\ninclude/linux/kernfs.h-247-\tint (*show_options)(struct seq_file *sf, struct kernfs_root *root);\n--\ninclude/linux/kernfs.h=425=struct dentry *kernfs_node_dentry(struct kernfs_node *kn,\ninclude/linux/kernfs.h-426-\t\t\t\t struct super_block *sb);\ninclude/linux/kernfs.h:427:struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops,\ninclude/linux/kernfs.h-428-\t\t\t\t unsigned int flags, void *priv);\n--\ninclude/linux/kernfs.h=525=static inline struct kernfs_root *\ninclude/linux/kernfs.h:526:kernfs_create_root(struct kernfs_syscall_ops *scops, unsigned int flags,\ninclude/linux/kernfs.h-527-\t\t void *priv)\n--\ninclude/linux/rseq_entry.h=650=static __always_inline bool __rseq_exit_to_user_mode_restart(struct pt_regs *regs)\n--\ninclude/linux/rseq_entry.h-655-\t * If the task did not go through schedule or got the flag enforced\ninclude/linux/rseq_entry.h:656:\t * by the rseq syscall or execve, then nothing to do here.\ninclude/linux/rseq_entry.h-657-\t *\n--\ninclude/media/media-devnode.h=28=extern struct dentry *media_debugfs_root;\n--\ninclude/media/media-devnode.h-45- * @compat_ioctl: pointer to the function that will handle 32 bits userspace\ninclude/media/media-devnode.h:46: *\tcalls to the ioctl() syscall on a Kernel compiled with 64 bits.\ninclude/media/media-devnode.h-47- * @open: pointer to the function that implements open() syscall\n--\ninclude/trace/events/migrate.h-19-\tEM( MR_MEMORY_HOTPLUG,\t\"memory_hotplug\")\t\t\\\ninclude/trace/events/migrate.h:20:\tEM( MR_SYSCALL,\t\t\"syscall_or_cpuset\")\t\t\\\ninclude/trace/events/migrate.h-21-\tEM( MR_MEMPOLICY_MBIND,\t\"mempolicy_mbind\")\t\t\\\n--\ninclude/uapi/drm/vmwgfx_drm.h=373=struct drm_vmw_fence_rep {\n--\ninclude/uapi/drm/vmwgfx_drm.h-396- *\ninclude/uapi/drm/vmwgfx_drm.h:397: * Buffer objects are mapped using the mmap() syscall on the drm device.\ninclude/uapi/drm/vmwgfx_drm.h-398- */\n--\ninclude/xen/interface/xen.h=542=struct shared_info {\n--\ninclude/xen/interface/xen.h-580-\t * Wallclock time: updated only by control software. Guests should base\ninclude/xen/interface/xen.h:581:\t * their gettimeofday() syscall on this wallclock-base value.\ninclude/xen/interface/xen.h-582-\t */\n--\nipc/Makefile=6=obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o\nipc/Makefile:7:obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o syscall.o\nipc/Makefile-8-obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o\n--\nkernel/bpf/Makefile=7=CFLAGS_core.o += -Wno-override-init $(cflags-nogcse-yy)\nkernel/bpf/Makefile-8-\nkernel/bpf/Makefile:9:obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o cnum.o log.o token.o liveness.o const_fold.o\nkernel/bpf/Makefile-10-obj-$(CONFIG_BPF_SYSCALL) += bpf_iter.o map_iter.o task_iter.o prog_iter.o link_iter.o\n--\nkernel/bpf/arraymap.c=161=static void *array_map_elem_ptr(struct bpf_array* array, u32 index)\n--\nkernel/bpf/arraymap.c-165-\nkernel/bpf/arraymap.c:166:/* Called from syscall or from eBPF program */\nkernel/bpf/arraymap.c-167-static void *array_map_lookup_elem(struct bpf_map *map, void *key)\n--\nkernel/bpf/arraymap.c=343=int bpf_array_get_next_key(struct bpf_map *map, void *key, void *next_key)\n--\nkernel/bpf/arraymap.c-359-\nkernel/bpf/arraymap.c:360:/* Called from syscall or from eBPF program */\nkernel/bpf/arraymap.c-361-static long array_map_update_elem(struct bpf_map *map, void *key, void *value,\n--\nkernel/bpf/arraymap.c=400=int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,\n--\nkernel/bpf/arraymap.c-448-\nkernel/bpf/arraymap.c:449:/* Called from syscall or from eBPF program */\nkernel/bpf/arraymap.c-450-static long array_map_delete_elem(struct bpf_map *map, void *key)\n--\nkernel/bpf/hashtab.c=712=static struct htab_elem *lookup_nulls_elem_raw(struct hlist_nulls_head *head,\n--\nkernel/bpf/hashtab.c-729-\nkernel/bpf/hashtab.c:730:/* Called from syscall or from eBPF program directly, so\nkernel/bpf/hashtab.c-731- * arguments have to match bpf_map_lookup_elem() exactly.\n--\nkernel/bpf/hashtab.c=1159=static int check_flags(struct bpf_htab *htab, struct htab_elem *l_old,\n--\nkernel/bpf/hashtab.c-1172-\nkernel/bpf/hashtab.c:1173:/* Called from syscall or from eBPF program */\nkernel/bpf/hashtab.c-1174-static long htab_map_update_elem(struct bpf_map *map, void *key, void *value,\n--\nkernel/bpf/hashtab.c=1494=static long htab_lru_percpu_map_update_elem(struct bpf_map *map, void *key,\n--\nkernel/bpf/hashtab.c-1500-\nkernel/bpf/hashtab.c:1501:/* Called from syscall or from eBPF program */\nkernel/bpf/hashtab.c-1502-static long htab_map_delete_elem(struct bpf_map *map, void *key)\n--\nkernel/bpf/lpm_trie.c=230=static size_t longest_prefix_match(const struct lpm_trie *trie,\n--\nkernel/bpf/lpm_trie.c-236-\nkernel/bpf/lpm_trie.c:237:/* Called from syscall or from eBPF program */\nkernel/bpf/lpm_trie.c-238-static void *trie_lookup_elem(struct bpf_map *map, void *_key)\n--\nkernel/bpf/lpm_trie.c=311=static int trie_check_add_elem(struct lpm_trie *trie, u64 flags)\n--\nkernel/bpf/lpm_trie.c-320-\nkernel/bpf/lpm_trie.c:321:/* Called from syscall or from eBPF program */\nkernel/bpf/lpm_trie.c-322-static long trie_update_elem(struct bpf_map *map,\n--\nkernel/bpf/lpm_trie.c-455-\nkernel/bpf/lpm_trie.c:456:/* Called from syscall or from eBPF program */\nkernel/bpf/lpm_trie.c-457-static long trie_delete_elem(struct bpf_map *map, void *_key)\n--\nkernel/bpf/queue_stack_maps.c=127=static long __stack_map_get(struct bpf_map *map, void *value, bool delete)\n--\nkernel/bpf/queue_stack_maps.c-160-\nkernel/bpf/queue_stack_maps.c:161:/* Called from syscall or from eBPF program */\nkernel/bpf/queue_stack_maps.c-162-static long queue_map_peek_elem(struct bpf_map *map, void *value)\n--\nkernel/bpf/queue_stack_maps.c-166-\nkernel/bpf/queue_stack_maps.c:167:/* Called from syscall or from eBPF program */\nkernel/bpf/queue_stack_maps.c-168-static long stack_map_peek_elem(struct bpf_map *map, void *value)\n--\n\n"
} |
| 13/2 | 2026/07/23 01:17 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 20475 output: 164 thoughts: 713 Thoughts: **My Analysis of the BPF Array Map Lazy Page Faulting Patch** Okay, so this patch is clearly centered around enabling lazy page faulting for BPF array maps that are `mmap`-ed into user space. My initial thought process is to understand the scope and reachability of this change. First, I confirmed that the BPF subsystem, enabled via `CONFIG_BPF_SYSCALL`, is the entry point. The patch modifies `arraymap.c` and `syscall.c` within the `kernel/bpf` directory, which immediately focuses my attention on those files. A quick check reveals that both are conditionally compiled only if `CONFIG_BPF_SYSCALL` is set, meaning that it is the *only* required config. Now, how does this actually work? The patch modifies `array_map_mmap` to set the `VM_DONTEXPAND | VM_DONTDUMP` flags on the virtual memory area and return 0, instead of eagerly mapping the memory. Critically, it then adds `array_map_mmap_fault`, which is called by `bpf_map_mmap_fault` when a page fault occurs. This signals the *lazy* nature of the page allocation. The key to verifying this is the selftest, `bench_arraymap_mmap.c`. This is crucial – it confirms the path is valid! The test creates a BPF array map using `BPF_F_MMAPABLE`, maps it using `mmap`, and subsequently accesses the memory, effectively triggering the page fault handling. This highlights the practical reachability and the intended function of the patch. I've determined that the focus symbols are: `array_map_mmap_fault`, `bpf_map_mmap_fault`, and `array_map_mmap`. The `array_map_mmap` function is impacted by a small change. I'm comfortable that this patch introduces a functional change that provides lazy page faulting for BPF array maps. Given the functional change, and reachability via user space and with this selftest, I'm marking this as `WorthFuzzing: true`. The `EnableConfigs` are obviously `BPF_SYSCALL` and I am going to log the function symbols to the tool. |
| 14/2 | 2026/07/23 01:17 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"BPF_SYSCALL"
],
"FocusSymbols": [
"array_map_mmap_fault",
"bpf_map_mmap_fault",
"array_map_mmap"
],
"Reasoning": "The patch introduces lazy page faulting for BPF array maps mapped to user space. It modifies `array_map_mmap` to not eagerly map the memory and adds `array_map_mmap_fault` and `bpf_map_mmap_fault` to handle page faults on demand. This is a functional change in the core BPF subsystem and is reachable from user space by creating and mmap-ing a BPF array map.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"BPF_SYSCALL"
],
"FocusSymbols": [
"array_map_mmap_fault",
"bpf_map_mmap_fault",
"array_map_mmap"
],
"Reasoning": "The patch introduces lazy page faulting for BPF array maps mapped to user space. It modifies `array_map_mmap` to not eagerly map the memory and adds `array_map_mmap_fault` and `bpf_map_mmap_fault` to handle page faults on demand. This is a functional change in the core BPF subsystem and is reachable from user space by creating and mmap-ing a BPF array map.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|