| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/10/28 14:47 | flow | patch-triage |
1mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"KMSANReasoning": "",
"NeedsKMSAN": false,
"Reasoning": "The patch series is a purely syntactic cleanup replacing direct usages of `__attribute__((nonnull...))` with the standardized kernel macro `__nonnull_args(...)` across various headers, source files, and user-space tools/scripts. Because `__nonnull_args(x...)` expands directly to `__attribute__((__nonnull__(x)))`, this does not alter compiled C logic, control flow, runtime checks, or data structures. There are no executable code changes to fuzz.",
"WorthFuzzing": false
} |
| 1/1 | 2026/10/28 14:47 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit f9b0a56b29a07f32144f6c32920f991ad9961147\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Wed Oct 28 14:47:05 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c\nindex 8f0720a7752051..c238564b4a314a 100644\n--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c\n+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c\n@@ -307,7 +307,7 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity,\n * move and different for a BO to BO copy.\n *\n */\n-__attribute__((nonnull))\n+__nonnull_args()\n static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,\n \t\t\t\t struct amdgpu_ttm_buffer_entity *entity,\n \t\t\t\t const struct amdgpu_copy_mem *src,\ndiff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h\nindex a2f4b6758a65b0..648d0b4139cf10 100644\n--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h\n+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h\n@@ -127,7 +127,7 @@ __deprecated\n struct drm_gem_object *\n drm_gem_object_lookup(struct drm_file *file, u32 handle);\n \n-__attribute__((nonnull))\n+__nonnull_args()\n static inline struct drm_i915_gem_object *\n i915_gem_object_get(struct drm_i915_gem_object *obj)\n {\n@@ -135,7 +135,7 @@ i915_gem_object_get(struct drm_i915_gem_object *obj)\n \treturn obj;\n }\n \n-__attribute__((nonnull))\n+__nonnull_args()\n static inline void\n i915_gem_object_put(struct drm_i915_gem_object *obj)\n {\ndiff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h\nindex b09135301f395a..f559203c332d53 100644\n--- a/drivers/gpu/drm/i915/i915_request.h\n+++ b/drivers/gpu/drm/i915/i915_request.h\n@@ -437,12 +437,12 @@ void i915_request_cancel(struct i915_request *rq, int error);\n long i915_request_wait_timeout(struct i915_request *rq,\n \t\t\t unsigned int flags,\n \t\t\t long timeout)\n-\t__attribute__((nonnull(1)));\n+\t__nonnull_args(1);\n \n long i915_request_wait(struct i915_request *rq,\n \t\t unsigned int flags,\n \t\t long timeout)\n-\t__attribute__((nonnull(1)));\n+\t__nonnull_args(1);\n #define I915_WAIT_INTERRUPTIBLE\tBIT(0)\n #define I915_WAIT_PRIORITY\tBIT(1) /* small priority bump for the request */\n #define I915_WAIT_ALL\t\tBIT(2) /* used by i915_gem_object_wait() */\ndiff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c\nindex 6c1f2f50ff854f..0363d370828b62 100644\n--- a/drivers/leds/leds-pwm.c\n+++ b/drivers/leds/leds-pwm.c\n@@ -80,7 +80,7 @@ static int led_pwm_default_brightness_get(struct fwnode_handle *fwnode,\n \treturn default_brightness;\n }\n \n-__attribute__((nonnull))\n+__nonnull_args()\n static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,\n \t\t struct led_pwm *led, struct fwnode_handle *fwnode)\n {\ndiff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c\nindex b09dca34099fe5..ee84a06a035e8a 100644\n--- a/drivers/soc/aspeed/aspeed-lpc-snoop.c\n+++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c\n@@ -226,7 +226,7 @@ static int aspeed_lpc_snoop_config_irq(struct aspeed_lpc_snoop *lpc_snoop,\n \treturn 0;\n }\n \n-__attribute__((nonnull))\n+__nonnull_args()\n static int aspeed_lpc_enable_snoop(struct device *dev,\n \t\t\t\t struct aspeed_lpc_snoop *lpc_snoop,\n \t\t\t\t struct aspeed_lpc_snoop_channel *channel,\n@@ -279,7 +279,7 @@ static int aspeed_lpc_enable_snoop(struct device *dev,\n \treturn rc;\n }\n \n-__attribute__((nonnull))\n+__nonnull_args()\n static void aspeed_lpc_disable_snoop(struct aspeed_lpc_snoop *lpc_snoop,\n \t\t\t\t struct aspeed_lpc_snoop_channel *channel)\n {\ndiff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h\nindex ed329408acbea2..56dd15921c7a9b 100644\n--- a/include/drm/drm_gem.h\n+++ b/include/drm/drm_gem.h\n@@ -566,7 +566,7 @@ static inline void drm_gem_object_get(struct drm_gem_object *obj)\n \tkref_get(\u0026obj-\u003erefcount);\n }\n \n-__attribute__((nonnull))\n+__nonnull_args()\n static inline void\n __drm_gem_object_put(struct drm_gem_object *obj)\n {\ndiff --git a/include/linux/list_sort.h b/include/linux/list_sort.h\nindex 453105f74e0504..48a91ef0d751c7 100644\n--- a/include/linux/list_sort.h\n+++ b/include/linux/list_sort.h\n@@ -6,9 +6,9 @@\n \n struct list_head;\n \n-typedef int __attribute__((nonnull(2,3))) (*list_cmp_func_t)(void *,\n+typedef int __nonnull_args(2, 3) (*list_cmp_func_t)(void *,\n \t\tconst struct list_head *, const struct list_head *);\n \n-__attribute__((nonnull(2,3)))\n+__nonnull_args(2, 3)\n void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp);\n #endif\ndiff --git a/include/linux/string.h b/include/linux/string.h\nindex 6cb5cdd01158b2..1f1cb73514e130 100644\n--- a/include/linux/string.h\n+++ b/include/linux/string.h\n@@ -587,7 +587,7 @@ static inline bool strstarts(const char *str, const char *prefix)\n * Returns:\n * True if @str ends with @suffix. False in all other cases.\n */\n-static inline bool __attribute__((nonnull(1, 2)))\n+static inline bool __nonnull_args(1, 2)\n strends(const char *str, const char *suffix)\n {\n \tunsigned int str_len = strlen(str), suffix_len = strlen(suffix);\ndiff --git a/include/linux/xarray.h b/include/linux/xarray.h\nindex be850174e802e6..cf7f8802da5bc4 100644\n--- a/include/linux/xarray.h\n+++ b/include/linux/xarray.h\n@@ -361,9 +361,9 @@ bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t);\n void xa_set_mark(struct xarray *, unsigned long index, xa_mark_t);\n void xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t);\n void *xa_find(struct xarray *xa, unsigned long *index,\n-\t\tunsigned long max, xa_mark_t) __attribute__((nonnull(2)));\n+\t\tunsigned long max, xa_mark_t) __nonnull_args(2);\n void *xa_find_after(struct xarray *xa, unsigned long *index,\n-\t\tunsigned long max, xa_mark_t) __attribute__((nonnull(2)));\n+\t\tunsigned long max, xa_mark_t) __nonnull_args(2);\n unsigned int xa_extract(struct xarray *, void **dst, unsigned long start,\n \t\tunsigned long max, unsigned int n, xa_mark_t);\n void xa_destroy(struct xarray *);\ndiff --git a/lib/list_sort.c b/lib/list_sort.c\nindex ff99203f208f8b..da34c46cf5d8e7 100644\n--- a/lib/list_sort.c\n+++ b/lib/list_sort.c\n@@ -9,7 +9,7 @@\n * to chaining of merge() calls: null-terminated, no reserved or\n * sentinel head node, \"prev\" links not maintained.\n */\n-__attribute__((nonnull(2,3,4)))\n+__nonnull_args(2, 3, 4)\n static struct list_head *merge(void *priv, list_cmp_func_t cmp,\n \t\t\t\tstruct list_head *a, struct list_head *b)\n {\n@@ -45,7 +45,7 @@ static struct list_head *merge(void *priv, list_cmp_func_t cmp,\n * prev-link restoration pass, or maintaining the prev links\n * throughout.\n */\n-__attribute__((nonnull(2,3,4,5)))\n+__nonnull_args(2, 3, 4, 5)\n static void merge_final(void *priv, list_cmp_func_t cmp, struct list_head *head,\n \t\t\tstruct list_head *a, struct list_head *b)\n {\n@@ -175,7 +175,7 @@ static void merge_final(void *priv, list_cmp_func_t cmp, struct list_head *head,\n * of size 2^k varies from 2^(k-1) (cases 3 and 5 when x == 0) to\n * 2^(k+1) - 1 (second merge of case 5 when x == 2^(k-1) - 1).\n */\n-__attribute__((nonnull(2,3)))\n+__nonnull_args(2, 3)\n void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp)\n {\n \tstruct list_head *list = head-\u003enext, *pending = NULL;\ndiff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl\nindex c9840f5219c2a9..e696fcd02337dd 100755\n--- a/scripts/checkpatch.pl\n+++ b/scripts/checkpatch.pl\n@@ -6856,6 +6856,7 @@ sub process {\n \t\t\t\t\"no_caller_saved_registers\"\t=\u003e \"__no_caller_saved_registers\",\n \t\t\t\t\"noclone\"\t\t\t=\u003e \"__noclone\",\n \t\t\t\t\"noinline\"\t\t\t=\u003e \"noinline\",\n+\t\t\t\t\"nonnull\"\t\t\t=\u003e \"__nonnull_args\",\n \t\t\t\t\"nonstring\"\t\t\t=\u003e \"__nonstring\",\n \t\t\t\t\"noreturn\"\t\t\t=\u003e \"__noreturn\",\n \t\t\t\t\"packed\"\t\t\t=\u003e \"__packed\",\n@@ -6876,6 +6877,8 @@ sub process {\n \t\t\t\t\tif ($curr_attr eq \"format\" \u0026\u0026 $params) {\n \t\t\t\t\t\t$params =~ /^\\s*\\(\\s*(\\w+)\\s*,\\s*(.*)/;\n \t\t\t\t\t\t$new = \"__$1\\($2\";\n+\t\t\t\t\t} elsif ($curr_attr eq \"nonnull\" \u0026\u0026 $params eq \"\") {\n+\t\t\t\t\t\t$new = \"$new()\";\n \t\t\t\t\t} else {\n \t\t\t\t\t\t$new = \"$new$params\";\n \t\t\t\t\t}\ndiff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h\nindex 03ecf90866436b..fad2c6131a80c6 100644\n--- a/tools/include/linux/compiler.h\n+++ b/tools/include/linux/compiler.h\n@@ -68,6 +68,10 @@\n #define __naked __attribute__((__naked__))\n #endif\n \n+#ifndef __nonnull_args\n+#define __nonnull_args(x...) __attribute__((__nonnull__(x)))\n+#endif\n+\n /* Are two types/vars the same type (ignoring qualifiers)? */\n #ifndef __same_type\n # define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))\ndiff --git a/tools/lib/python/kdoc/xforms_lists.py b/tools/lib/python/kdoc/xforms_lists.py\nindex 320f977c5bac2c..a8c47ede8637eb 100644\n--- a/tools/lib/python/kdoc/xforms_lists.py\n+++ b/tools/lib/python/kdoc/xforms_lists.py\n@@ -108,6 +108,7 @@ class CTransforms:\n (CMatch(\"__attribute__\"), \"\"),\n (CMatch(\"STATIC_IFN_KUNIT\"), \"\"),\n (CMatch(\"INLINE_IFN_KUNIT\"), \"\"),\n+ (CMatch(\"__nonnull_args\"), \"\"),\n \n #\n # HACK: this is similar to process_export() hack. It is meant to\n"
} |
| 2/1 | 2026/10/28 14:47 | agent | patch-evaluator |
1mModel:core Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch series is a purely syntactic cleanup replacing direct usages of `__attribute__((nonnull...))` with the standardized kernel macro `__nonnull_args(...)` across various headers, source files, and user-space tools/scripts. Because `__nonnull_args(x...)` expands directly to `__attribute__((__nonnull__(x)))`, this does not alter compiled C logic, control flow, runtime checks, or data structures. There are no executable code changes to fuzz.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.
IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.
================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.
- REACHABILITY IS THE PRIMARY GATE:
Fuzzing can only discover bugs in code that can actually execute in standard virtualized
environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
regardless of whether it adds assertions or complex logic.
- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
Patch authors routinely label changes as "cleanups", "refactorings", or state
"No functional change intended". Do NOT take these claims at face value.
Code refactorings that rearrange logic, introduce helper functions, or alter state management
in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
If reachable executable code is modified or refactored, it MUST be fuzzed.
- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
Even if the author believes the invariant always holds, fuzzing is essential to verify whether
an unusual sequence of operations can violate it.
================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:
- Non-kernel and non-executable changes:
* Modifications to Documentation/, comments, or spelling fixes.
* User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
that do not affect the compiled kernel image (vmlinux) or kernel modules.
* Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
that do not alter control flow or data structures.
* Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
* Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
* Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
physical PCI hot-unplug or manual sysfs driver unbinding.
* Code paths exclusive to architectures other than the target architecture.
================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
* Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
* Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
* Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
* Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).
================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:
- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
Do NOT list generic, ubiquitous functions called by almost every program in the corpus
(including, but not limited to: general memory allocators and deallocators, page fault
and trap handlers, or core synchronization primitives; this is not an exhaustive list).
Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
which severely dilutes fuzzing effort away from the actual changes.
- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
List functions that specifically implement the logic being added or altered, or direct API entrypoints
for the subsystem feature under review.
- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).
================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any '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: Target architecture: amd64
For your convenience, here is the diff of the changes:
commit f9b0a56b29a07f32144f6c32920f991ad9961147
Author: syz-cluster <triage@syzkaller.com>
Date: Wed Oct 28 14:47:05 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 8f0720a7752051..c238564b4a314a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -307,7 +307,7 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity,
* move and different for a BO to BO copy.
*
*/
-__attribute__((nonnull))
+__nonnull_args()
static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
struct amdgpu_ttm_buffer_entity *entity,
const struct amdgpu_copy_mem *src,
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index a2f4b6758a65b0..648d0b4139cf10 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -127,7 +127,7 @@ __deprecated
struct drm_gem_object *
drm_gem_object_lookup(struct drm_file *file, u32 handle);
-__attribute__((nonnull))
+__nonnull_args()
static inline struct drm_i915_gem_object *
i915_gem_object_get(struct drm_i915_gem_object *obj)
{
@@ -135,7 +135,7 @@ i915_gem_object_get(struct drm_i915_gem_object *obj)
return obj;
}
-__attribute__((nonnull))
+__nonnull_args()
static inline void
i915_gem_object_put(struct drm_i915_gem_object *obj)
{
diff --git a/drivers/gpu/drm/i915/i915_request.h b/drivers/gpu/drm/i915/i915_request.h
index b09135301f395a..f559203c332d53 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -437,12 +437,12 @@ void i915_request_cancel(struct i915_request *rq, int error);
long i915_request_wait_timeout(struct i915_request *rq,
unsigned int flags,
long timeout)
- __attribute__((nonnull(1)));
+ __nonnull_args(1);
long i915_request_wait(struct i915_request *rq,
unsigned int flags,
long timeout)
- __attribute__((nonnull(1)));
+ __nonnull_args(1);
#define I915_WAIT_INTERRUPTIBLE BIT(0)
#define I915_WAIT_PRIORITY BIT(1) /* small priority bump for the request */
#define I915_WAIT_ALL BIT(2) /* used by i915_gem_object_wait() */
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index 6c1f2f50ff854f..0363d370828b62 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -80,7 +80,7 @@ static int led_pwm_default_brightness_get(struct fwnode_handle *fwnode,
return default_brightness;
}
-__attribute__((nonnull))
+__nonnull_args()
static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
struct led_pwm *led, struct fwnode_handle *fwnode)
{
diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c
index b09dca34099fe5..ee84a06a035e8a 100644
--- a/drivers/soc/aspeed/aspeed-lpc-snoop.c
+++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c
@@ -226,7 +226,7 @@ static int aspeed_lpc_snoop_config_irq(struct aspeed_lpc_snoop *lpc_snoop,
return 0;
}
-__attribute__((nonnull))
+__nonnull_args()
static int aspeed_lpc_enable_snoop(struct device *dev,
struct aspeed_lpc_snoop *lpc_snoop,
struct aspeed_lpc_snoop_channel *channel,
@@ -279,7 +279,7 @@ static int aspeed_lpc_enable_snoop(struct device *dev,
return rc;
}
-__attribute__((nonnull))
+__nonnull_args()
static void aspeed_lpc_disable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
struct aspeed_lpc_snoop_channel *channel)
{
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index ed329408acbea2..56dd15921c7a9b 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -566,7 +566,7 @@ static inline void drm_gem_object_get(struct drm_gem_object *obj)
kref_get(&obj->refcount);
}
-__attribute__((nonnull))
+__nonnull_args()
static inline void
__drm_gem_object_put(struct drm_gem_object *obj)
{
diff --git a/include/linux/list_sort.h b/include/linux/list_sort.h
index 453105f74e0504..48a91ef0d751c7 100644
--- a/include/linux/list_sort.h
+++ b/include/linux/list_sort.h
@@ -6,9 +6,9 @@
struct list_head;
-typedef int __attribute__((nonnull(2,3))) (*list_cmp_func_t)(void *,
+typedef int __nonnull_args(2, 3) (*list_cmp_func_t)(void *,
const struct list_head *, const struct list_head *);
-__attribute__((nonnull(2,3)))
+__nonnull_args(2, 3)
void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp);
#endif
diff --git a/include/linux/string.h b/include/linux/string.h
index 6cb5cdd01158b2..1f1cb73514e130 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -587,7 +587,7 @@ static inline bool strstarts(const char *str, const char *prefix)
* Returns:
* True if @str ends with @suffix. False in all other cases.
*/
-static inline bool __attribute__((nonnull(1, 2)))
+static inline bool __nonnull_args(1, 2)
strends(const char *str, const char *suffix)
{
unsigned int str_len = strlen(str), suffix_len = strlen(suffix);
diff --git a/include/linux/xarray.h b/include/linux/xarray.h
index be850174e802e6..cf7f8802da5bc4 100644
--- a/include/linux/xarray.h
+++ b/include/linux/xarray.h
@@ -361,9 +361,9 @@ bool xa_get_mark(struct xarray *, unsigned long index, xa_mark_t);
void xa_set_mark(struct xarray *, unsigned long index, xa_mark_t);
void xa_clear_mark(struct xarray *, unsigned long index, xa_mark_t);
void *xa_find(struct xarray *xa, unsigned long *index,
- unsigned long max, xa_mark_t) __attribute__((nonnull(2)));
+ unsigned long max, xa_mark_t) __nonnull_args(2);
void *xa_find_after(struct xarray *xa, unsigned long *index,
- unsigned long max, xa_mark_t) __attribute__((nonnull(2)));
+ unsigned long max, xa_mark_t) __nonnull_args(2);
unsigned int xa_extract(struct xarray *, void **dst, unsigned long start,
unsigned long max, unsigned int n, xa_mark_t);
void xa_destroy(struct xarray *);
diff --git a/lib/list_sort.c b/lib/list_sort.c
index ff99203f208f8b..da34c46cf5d8e7 100644
--- a/lib/list_sort.c
+++ b/lib/list_sort.c
@@ -9,7 +9,7 @@
* to chaining of merge() calls: null-terminated, no reserved or
* sentinel head node, "prev" links not maintained.
*/
-__attribute__((nonnull(2,3,4)))
+__nonnull_args(2, 3, 4)
static struct list_head *merge(void *priv, list_cmp_func_t cmp,
struct list_head *a, struct list_head *b)
{
@@ -45,7 +45,7 @@ static struct list_head *merge(void *priv, list_cmp_func_t cmp,
* prev-link restoration pass, or maintaining the prev links
* throughout.
*/
-__attribute__((nonnull(2,3,4,5)))
+__nonnull_args(2, 3, 4, 5)
static void merge_final(void *priv, list_cmp_func_t cmp, struct list_head *head,
struct list_head *a, struct list_head *b)
{
@@ -175,7 +175,7 @@ static void merge_final(void *priv, list_cmp_func_t cmp, struct list_head *head,
* of size 2^k varies from 2^(k-1) (cases 3 and 5 when x == 0) to
* 2^(k+1) - 1 (second merge of case 5 when x == 2^(k-1) - 1).
*/
-__attribute__((nonnull(2,3)))
+__nonnull_args(2, 3)
void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp)
{
struct list_head *list = head->next, *pending = NULL;
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index c9840f5219c2a9..e696fcd02337dd 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -6856,6 +6856,7 @@ sub process {
"no_caller_saved_registers" => "__no_caller_saved_registers",
"noclone" => "__noclone",
"noinline" => "noinline",
+ "nonnull" => "__nonnull_args",
"nonstring" => "__nonstring",
"noreturn" => "__noreturn",
"packed" => "__packed",
@@ -6876,6 +6877,8 @@ sub process {
if ($curr_attr eq "format" && $params) {
$params =~ /^\s*\(\s*(\w+)\s*,\s*(.*)/;
$new = "__$1\($2";
+ } elsif ($curr_attr eq "nonnull" && $params eq "") {
+ $new = "$new()";
} else {
$new = "$new$params";
}
diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h
index 03ecf90866436b..fad2c6131a80c6 100644
--- a/tools/include/linux/compiler.h
+++ b/tools/include/linux/compiler.h
@@ -68,6 +68,10 @@
#define __naked __attribute__((__naked__))
#endif
+#ifndef __nonnull_args
+#define __nonnull_args(x...) __attribute__((__nonnull__(x)))
+#endif
+
/* Are two types/vars the same type (ignoring qualifiers)? */
#ifndef __same_type
# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
diff --git a/tools/lib/python/kdoc/xforms_lists.py b/tools/lib/python/kdoc/xforms_lists.py
index 320f977c5bac2c..a8c47ede8637eb 100644
--- a/tools/lib/python/kdoc/xforms_lists.py
+++ b/tools/lib/python/kdoc/xforms_lists.py
@@ -108,6 +108,7 @@ class CTransforms:
(CMatch("__attribute__"), ""),
(CMatch("STATIC_IFN_KUNIT"), ""),
(CMatch("INLINE_IFN_KUNIT"), ""),
+ (CMatch("__nonnull_args"), ""),
#
# HACK: this is similar to process_export() hack. It is meant to
|
| 3/2 | 2026/10/28 14:47 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 6558 output: 19 thoughts: 290 Thoughts: **Evaluating This Patch Series** Okay, so I need to evaluate this patch series that's been committed as HEAD. My first instinct would be to dive into `git log` or maybe a `grep` to get the context, but hold on, let's just look at the diff the prompt provides directly. Ah, I see, the primary change is a global replacement of `__attribute__((nonnull...))` with `__nonnull_args(...)`. This change touches quite a few files: drivers related to the GPU, some headers in DRM, some core Linux kernel includes, and even a couple of utility scripts. Let me think... this pattern looks familiar. It's likely a refactoring or cleanup related to how null argument annotations are handled. The actual substitution itself seems straightforward enough, but my concern is: where is this new `__nonnull_args` macro *defined* for use in kernel code? It’s important to understand the implications of this new macro. I should check `include/linux/compiler_attributes.h` or somewhere similar in the include path to see what this macro expands to, to be certain. I need to understand what this macro actually does. It's really the crucial thing here; the substitution is just a visual indicator of the underlying change. |
| 4/2 | 2026/10/28 14:47 | tool | grepper |
0mArgs:{
"Expression": "__nonnull_args"
}Results: {
"Output": "drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c=202=static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity,\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c-309- */\ndrivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c:310:__nonnull_args()\ndrivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c-311-static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,\n--\ndrivers/gpu/drm/i915/gem/i915_gem_object.h=128=drm_gem_object_lookup(struct drm_file *file, u32 handle);\ndrivers/gpu/drm/i915/gem/i915_gem_object.h-129-\ndrivers/gpu/drm/i915/gem/i915_gem_object.h:130:__nonnull_args()\ndrivers/gpu/drm/i915/gem/i915_gem_object.h-131-static inline struct drm_i915_gem_object *\ndrivers/gpu/drm/i915/gem/i915_gem_object.h=132=i915_gem_object_get(struct drm_i915_gem_object *obj)\n--\ndrivers/gpu/drm/i915/gem/i915_gem_object.h-137-\ndrivers/gpu/drm/i915/gem/i915_gem_object.h:138:__nonnull_args()\ndrivers/gpu/drm/i915/gem/i915_gem_object.h-139-static inline void\n--\ndrivers/gpu/drm/i915/i915_request.h=437=long i915_request_wait_timeout(struct i915_request *rq,\n--\ndrivers/gpu/drm/i915/i915_request.h-439-\t\t\t long timeout)\ndrivers/gpu/drm/i915/i915_request.h:440:\t__nonnull_args(1);\ndrivers/gpu/drm/i915/i915_request.h-441-\ndrivers/gpu/drm/i915/i915_request.h=442=long i915_request_wait(struct i915_request *rq,\n--\ndrivers/gpu/drm/i915/i915_request.h-444-\t\t long timeout)\ndrivers/gpu/drm/i915/i915_request.h:445:\t__nonnull_args(1);\ndrivers/gpu/drm/i915/i915_request.h-446-#define I915_WAIT_INTERRUPTIBLE\tBIT(0)\n--\ndrivers/leds/leds-pwm.c=69=static int led_pwm_default_brightness_get(struct fwnode_handle *fwnode,\n--\ndrivers/leds/leds-pwm.c-82-\ndrivers/leds/leds-pwm.c:83:__nonnull_args()\ndrivers/leds/leds-pwm.c-84-static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,\n--\ndrivers/soc/aspeed/aspeed-lpc-snoop.c=207=static int aspeed_lpc_snoop_config_irq(struct aspeed_lpc_snoop *lpc_snoop,\n--\ndrivers/soc/aspeed/aspeed-lpc-snoop.c-228-\ndrivers/soc/aspeed/aspeed-lpc-snoop.c:229:__nonnull_args()\ndrivers/soc/aspeed/aspeed-lpc-snoop.c-230-static int aspeed_lpc_enable_snoop(struct device *dev,\n--\ndrivers/soc/aspeed/aspeed-lpc-snoop.c-281-\ndrivers/soc/aspeed/aspeed-lpc-snoop.c:282:__nonnull_args()\ndrivers/soc/aspeed/aspeed-lpc-snoop.c-283-static void aspeed_lpc_disable_snoop(struct aspeed_lpc_snoop *lpc_snoop,\n--\ninclude/drm/drm_gem.h=564=static inline void drm_gem_object_get(struct drm_gem_object *obj)\n--\ninclude/drm/drm_gem.h-568-\ninclude/drm/drm_gem.h:569:__nonnull_args()\ninclude/drm/drm_gem.h-570-static inline void\n--\ninclude/linux/cleanup.h=350=static __maybe_unused const bool class_##_name##_is_conditional = _is_cond\n--\ninclude/linux/cleanup.h-392-#define DEFINE_GUARD(_name, _type, _lock, _unlock) \\\ninclude/linux/cleanup.h:393:\tstatic __always_inline __nonnull_args(1) _type class_##_name##_constructor(_type _T); \\\ninclude/linux/cleanup.h-394-\tDEFINE_CLASS(_name, _type, _unlock, ({ _lock; _T; }), _type _T); \\\n--\ninclude/linux/cleanup.h=491=__DEFINE_GUARD_LOCK_PTR(_name, \u0026_T-\u003elock)\n--\ninclude/linux/cleanup.h-493-#define __DEFINE_LOCK_GUARD_1(_name, _type, ...)\t\t\t\\\ninclude/linux/cleanup.h:494:static __always_inline __nonnull_args(1)\t\t\t\t\\\ninclude/linux/cleanup.h-495-class_##_name##_t class_##_name##_constructor(_type *l)\t\t\t\\\n--\ninclude/linux/compiler_attributes.h-239- */\ninclude/linux/compiler_attributes.h:240:#define __nonnull_args(x...)\t\t__attribute__((__nonnull__(x)))\ninclude/linux/compiler_attributes.h-241-\n--\ninclude/linux/list_sort.h=7=struct list_head;\ninclude/linux/list_sort.h-8-\ninclude/linux/list_sort.h:9:typedef int __nonnull_args(2, 3) (*list_cmp_func_t)(void *,\ninclude/linux/list_sort.h-10-\t\tconst struct list_head *, const struct list_head *);\ninclude/linux/list_sort.h-11-\ninclude/linux/list_sort.h:12:__nonnull_args(2, 3)\ninclude/linux/list_sort.h-13-void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp);\n--\ninclude/linux/string.h=577=static inline bool strstarts(const char *str, const char *prefix)\n--\ninclude/linux/string.h-589- */\ninclude/linux/string.h:590:static inline bool __nonnull_args(1, 2)\ninclude/linux/string.h-591-strends(const char *str, const char *suffix)\n--\ninclude/linux/xarray.h=363=void *xa_find(struct xarray *xa, unsigned long *index,\ninclude/linux/xarray.h:364:\t\tunsigned long max, xa_mark_t) __nonnull_args(2);\ninclude/linux/xarray.h-365-void *xa_find_after(struct xarray *xa, unsigned long *index,\ninclude/linux/xarray.h:366:\t\tunsigned long max, xa_mark_t) __nonnull_args(2);\ninclude/linux/xarray.h-367-unsigned int xa_extract(struct xarray *, void **dst, unsigned long start,\n--\nlib/list_sort.c-11- */\nlib/list_sort.c:12:__nonnull_args(2, 3, 4)\nlib/list_sort.c-13-static struct list_head *merge(void *priv, list_cmp_func_t cmp,\n--\nlib/list_sort.c-47- */\nlib/list_sort.c:48:__nonnull_args(2, 3, 4, 5)\nlib/list_sort.c-49-static void merge_final(void *priv, list_cmp_func_t cmp, struct list_head *head,\n--\nlib/list_sort.c-177- */\nlib/list_sort.c:178:__nonnull_args(2, 3)\nlib/list_sort.c-179-void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp)\n--\nscripts/checkpatch.pl=2670=sub process {\n--\nscripts/checkpatch.pl-6858-\t\t\t\t\"noinline\"\t\t\t=\u003e \"noinline\",\nscripts/checkpatch.pl:6859:\t\t\t\t\"nonnull\"\t\t\t=\u003e \"__nonnull_args\",\nscripts/checkpatch.pl-6860-\t\t\t\t\"nonstring\"\t\t\t=\u003e \"__nonstring\",\n--\ntools/include/linux/compiler.h-70-\ntools/include/linux/compiler.h:71:#ifndef __nonnull_args\ntools/include/linux/compiler.h:72:#define __nonnull_args(x...) __attribute__((__nonnull__(x)))\ntools/include/linux/compiler.h-73-#endif\n--\ntools/lib/python/kdoc/xforms_lists.py=13=class CTransforms:\n--\ntools/lib/python/kdoc/xforms_lists.py-110- (CMatch(\"INLINE_IFN_KUNIT\"), \"\"),\ntools/lib/python/kdoc/xforms_lists.py:111: (CMatch(\"__nonnull_args\"), \"\"),\ntools/lib/python/kdoc/xforms_lists.py-112-\n"
} |
| 5/2 | 2026/10/28 14:47 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 9700 output: 22 thoughts: 18 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience, presented in the first person: **Analyzing the Patch's Intent** Alright, before I dive into the code, I need to get a high-level understanding of what this patch is even *trying* to accomplish. My first instinct is to immediately consult the commit message. Is it clear and concise? Does it articulate the problem being addressed and the rationale for the solution? If not, that's a red flag. I'll need to dig deeper. Next, I'll quickly scan the preceding commits in the chain. Seeing the evolution of the changes will give context. Were there preliminary discussions, experiments, or related fixes? This timeline might reveal assumptions or architectural considerations that aren't immediately obvious from the diff itself. I'm looking for the "why" as much as the "what." A well-defined history often makes a difficult patch trivial to understand. On the other hand, if the history is opaque, I'll need to prepare myself for a deeper forensic analysis. Ultimately, my goal is to frame these changes within the existing codebase and assess their impact. |
| 6/2 | 2026/10/28 14:47 | tool | grepper |
0mArgs:{
"Expression": "__attribute__\\(\\(nonnull"
}Results: {
"Output": "tools/include/linux/list_sort.h=7=struct list_head;\ntools/include/linux/list_sort.h-8-\ntools/include/linux/list_sort.h:9:typedef int __attribute__((nonnull(2,3))) (*list_cmp_func_t)(void *,\ntools/include/linux/list_sort.h-10-\t\tconst struct list_head *, const struct list_head *);\ntools/include/linux/list_sort.h-11-\ntools/include/linux/list_sort.h:12:__attribute__((nonnull(2,3)))\ntools/include/linux/list_sort.h-13-void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp);\n--\ntools/lib/list_sort.c-11- */\ntools/lib/list_sort.c:12:__attribute__((nonnull(2,3,4)))\ntools/lib/list_sort.c-13-static struct list_head *merge(void *priv, list_cmp_func_t cmp,\n--\ntools/lib/list_sort.c-47- */\ntools/lib/list_sort.c:48:__attribute__((nonnull(2,3,4,5)))\ntools/lib/list_sort.c-49-static void merge_final(void *priv, list_cmp_func_t cmp, struct list_head *head,\n--\ntools/lib/list_sort.c-170- */\ntools/lib/list_sort.c:171:__attribute__((nonnull(2,3)))\ntools/lib/list_sort.c-172-void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp)\n--\ntools/perf/util/parse-events.h=32=int parse_events_option_new_evlist(const struct option *opt, const char *str, int unset);\ntools/perf/util/parse-events.h:33:__attribute__((nonnull(1, 2, 5))) int\ntools/perf/util/parse-events.h-34-__parse_events(struct evlist *evlist, const char *str, const char *pmu_filter,\n--\ntools/perf/util/parse-events.h-37-\ntools/perf/util/parse-events.h:38:__attribute__((nonnull(1, 2, 3)))\ntools/perf/util/parse-events.h-39-static inline int parse_events(struct evlist *evlist, const char *str,\n"
} |
| 7/2 | 2026/10/28 14:47 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 10628 output: 37 thoughts: 41 Thoughts: Here's my take on the thought process: **Diving into Compiler Attributes in the Kernel** Okay, so I need to understand something about how these compiler attributes work, particularly in `include/linux/compiler_attributes.h` around line 240. My first step is going to be to look at the commit history or the current state. Let's see... `git show HEAD` might be useful to get a snapshot of the current version. Alternatively, a quick `git log -n 5` could show me the last few commits that touched that file, which could be more helpful to give me context of recent changes. The goal is to rapidly understand the present state of this particular code block. I'll need to use something like `read-file` to grab the file content and pinpoint the code section in question and start my analysis from there. |
| 8/2 | 2026/10/28 14:47 | tool | read-file |
0mArgs:{
"File": "include/linux/compiler_attributes.h",
"FirstLine": 230,
"LineCount": 20
}Results: {
"Contents": " 230:\t */\n 231:\t#define noinline __attribute__((__noinline__))\n 232:\t\n 233:\t/*\n 234:\t * Note: deliberately not named '__nonnull', to avoid clashing with glibc's\n 235:\t * __nonnull() when kernel and userspace headers are combined.\n 236:\t *\n 237:\t * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-nonnull\n 238:\t * clang: https://clang.llvm.org/docs/AttributeReference.html#nonnull\n 239:\t */\n 240:\t#define __nonnull_args(x...)\t\t__attribute__((__nonnull__(x)))\n 241:\t\n 242:\t/*\n 243:\t * Optional: only supported since gcc \u003e= 8\n 244:\t * Optional: not supported by clang\n 245:\t *\n 246:\t * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-nonstring-variable-attribute\n 247:\t */\n 248:\t#if __has_attribute(__nonstring__)\n 249:\t# define __nonstring __attribute__((__nonstring__))\n"
} |
| 9/2 | 2026/10/28 14:47 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 11239 output: 39 thoughts: 3738 Thoughts: **Analysis of the `__nonnull_args` Macro Replacement** Okay, so I'm looking at this patch and it's all about replacing instances of `__attribute__((nonnull))` or `__attribute__((nonnull(...)))` with the `__nonnull_args()` macro. The macro is defined as `#define __nonnull_args(x...) __attribute__((__nonnull__(x)))`. I need to figure out if this actually *does* anything, or if it's just cosmetic. My initial thought is to go through the diffs. It looks like it's a simple find and replace. I see instances like `__attribute__((nonnull))` becoming `__nonnull_args()`, and `__attribute__((nonnull(1)))` becoming `__nonnull_args(1)`. Right, so let's see, what does that translate to. If I call it with no args: `__nonnull_args()` it expands to `__attribute__((__nonnull__()))`. Then I need to check. In GCC/Clang `__attribute__((nonnull))` with no arguments means all pointer arguments are non-null. So, what did it replace? Looks like: * `__attribute__((nonnull))` -> `__nonnull_args()` expands to `__attribute__((__nonnull__()))` * `__attribute__((nonnull(1)))` -> `__nonnull_args(1)` I need to make sure that these are identical. Let me check the kernel coding style. This is likely a standard kernel macro. This is a refactoring, right? I need to check the exact semantics. I have to be extremely careful here. Let's make sure it doesn't change anything at all. Okay, let's step back, and check that macro definition again, `#define __nonnull_args(x...) __attribute__((__nonnull__(x)))`. When `__nonnull_args()` is called with no arguments: `__attribute__((__nonnull__()))` is produced, and `__attribute__((nonnull))` means ALL pointer args are non-null, and `__attribute__((nonnull(1,2)))` means arguments 1 and 2 are nonnull. I keep going through the diffs. I need to know. Does this patch *actually* modify any executable code? Does it change semantics, control flow, runtime checks, or data structures? I need to know the triage philosophy here. I need to make sure to read section 1, 2, and 3 carefully: Section 1: "The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs, and newly triggered assertions introduced by the patch series". It says: "REACHABILITY IS THE PRIMARY GATE". Does this change *reach* anything? Okay, let's consider the negative criteria in Section 2: Is it "Non-kernel and non-executable changes"? * Are these modifications to Documentation/, comments, or spelling fixes? No. * Are these user-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/) that do not affect the compiled kernel image (vmlinux) or kernel modules? No. * Is this Purely decorative logging (e.g., message strings in pr\_err, printk, dev\_info) or tracepoints that do not alter control flow or data structures? No. * Is it Build system or Kconfig changes that do not alter compiled C logic? No. Wait, are compiler attributes considered non-executable changes when they are literally 1-to-1 equivalent aliases (syntactic macro replacement)? I need to verify the code does *not* alter control flow. This is key. Does this change *anything* at the *compiled* level? Let me be sure. Let's check Section 3: When to return WorthFuzzing=true * Is there any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/), BPF, scheduler, core networking, VFS, or syscall handling? No. * Is there any restructuring of reachable data structures, helper abstractions, or algorithm flows? No. * Is there any introduction or alteration of assertions (WARN\_ON\*, VM\_WARN\_ON\*, BUG\_ON\*, etc.) in reachable paths? No. * Are there Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.)? No. Ah-ha! Is this really just a purely syntactic cleanup? I need to confirm. What is `__nonnull_args(x...)`? `#define __nonnull |
| 10/2 | 2026/10/28 14:48 | tool | grepper |
0mError:no matches Args: {
"Expression": "Deliberately not named '__nonnull'",
"PathPrefixes": [
"include/linux/compiler_attributes.h"
]
}Results: {
"error": "no matches"
} |
| 11/2 | 2026/10/28 14:48 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 16055 output: 37 thoughts: 26 Thoughts: Okay, let's dive into this. Here's my take on those lines from `include/linux/compiler_attributes.h`, specifically lines 230-245. **Analyzing Compiler Attribute Definitions** Alright, I'm pulling up that section now. It looks like we're focused on defining some compiler attributes, specifically those related to handling potential overflow and underflow scenarios in the kernel. I can immediately tell this is about code safety and optimization, which makes sense. I see `__must_check`, which, as I recall, forces a return value to be checked. That's a good defensive programming technique, especially within the kernel where failures can be catastrophic. The code probably defines a macro to specify that a function's return value *must* be inspected to prevent subtle bugs caused by unchecked return codes. Looking further, there is likely a macro to warn about integer overflow, likely using a compiler-specific attribute, like `__attribute__((warn_unused_result))`, or a similar construct, which is also used to help catch errors during the code. We also have, at least, the structure, if not the actual definition, for an attribute that's meant to tell the compiler to be more aggressive, with an "overflow-safe" kind of function. We're probably seeing ways to flag functions for special handling during compilation, possibly involving inserting checks or using different arithmetic instructions to prevent these kinds of problems. These attributes help the compiler identify opportunities for optimizations, or to issue warnings when potential issues are detected. This is all standard stuff, trying to squeeze performance while minimizing risk. It's a key part of writing robust kernel code. |
| 12/2 | 2026/10/28 14:48 | tool | read-file |
0mArgs:{
"File": "include/linux/compiler_attributes.h",
"FirstLine": 230,
"LineCount": 15
}Results: {
"Contents": " 230:\t */\n 231:\t#define noinline __attribute__((__noinline__))\n 232:\t\n 233:\t/*\n 234:\t * Note: deliberately not named '__nonnull', to avoid clashing with glibc's\n 235:\t * __nonnull() when kernel and userspace headers are combined.\n 236:\t *\n 237:\t * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Attributes.html#index-nonnull\n 238:\t * clang: https://clang.llvm.org/docs/AttributeReference.html#nonnull\n 239:\t */\n 240:\t#define __nonnull_args(x...)\t\t__attribute__((__nonnull__(x)))\n 241:\t\n 242:\t/*\n 243:\t * Optional: only supported since gcc \u003e= 8\n 244:\t * Optional: not supported by clang\n"
} |
| 13/2 | 2026/10/28 14:48 | llm | patch-evaluator |
0mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 16722 output: 133 thoughts: 1997 Thoughts: **Analysis of a Non-Functional Change: No Fuzzing Required** Okay, so I'm looking at this patch series. It's making a consistent change across a bunch of files, replacing instances of `__attribute__((nonnull))` with the macro `__nonnull_args()`. My initial thought was to use git to track the specific line change and look for commits that mentioned the nonnull attribute. While I don't have git log, I can see that the changes are fairly widespread, touching a good number of files. Let's dig in and figure out exactly *what* is being changed. After reviewing each of the modified files, it's clear this is just a syntactic conversion. Everywhere `__attribute__((nonnull))` appears, it's being switched to `__nonnull_args()`. So far, so good – the code is only changing attributes for the compiler. Now, critically, does this actually *do* anything? The macro `__nonnull_args(x...)` expands directly to `__attribute__((__nonnull__(x)))`. This is a straightforward find-and-replace for the C compiler. Nothing functional, zero semantic changes, and no changes to generated code. No code is changed - the raw compiler attribute is simply replaced by its macro equivalent. Now, let's step back and consider the fuzzing guidance. Section 1 and Section 2 explicitly mention to *not* trust "no functional change" (NFCI) or "refactoring" claims. Refactorings that touch executable code *must* be fuzzed. But did this patch rearrange logic? No. Introduce helper functions? No. Alter state management? No. Modify runtime checks or assertions? No. Is this *executable* code? No, these are compiler attributes. It's just a macro expansion. Looking at Section 2, the patch qualifies for "WorthFuzzing=false" because it falls squarely into: "Non-kernel and non-executable changes" and specifically "User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/) that do not affect the compiled kernel image (vmlinux) or kernel modules". This change is purely syntactic, and the user-space changes support the main effort by maintaining consistency. Since there's no change to executable code, compiled C logic, data structures or control flow, fuzzing will not be fruitful. Therefore, `WorthFuzzing = false`. No crashes, regressions, exposed latent bugs, or newly triggered assertions are possible here. So, the parameters for `set-results` should be: * `WorthFuzzing`: false * `FocusSymbols`: \[ ] * `EnableConfigs`: \[ ] The reasoning is pretty clear: The patch series performs a purely syntactic refactoring across kernel headers, drivers, and scripts, replacing direct usages of `__attribute__((nonnull...))` with the standardized macro `__nonnull_args(...)`. Since `__nonnull_args(x...)` expands directly to `__attribute__((__nonnull__(x)))`, the change introduces no modifications to executable code, logic, data structures, runtime checks, or compiler code generation. Furthermore, the accompanying changes in scripts/ and tools/ are user-space scripts and utilities that do not affect the compiled kernel image. Therefore, there are no executable logic changes to fuzz. |
| 14/2 | 2026/10/28 14:48 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch series is a purely syntactic cleanup replacing direct usages of `__attribute__((nonnull...))` with the standardized kernel macro `__nonnull_args(...)` across various headers, source files, and user-space tools/scripts. Because `__nonnull_args(x...)` expands directly to `__attribute__((__nonnull__(x)))`, this does not alter compiled C logic, control flow, runtime checks, or data structures. There are no executable code changes to fuzz.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch series is a purely syntactic cleanup replacing direct usages of `__attribute__((nonnull...))` with the standardized kernel macro `__nonnull_args(...)` across various headers, source files, and user-space tools/scripts. Because `__nonnull_args(x...)` expands directly to `__attribute__((__nonnull__(x)))`, this does not alter compiled C logic, control flow, runtime checks, or data structures. There are no executable code changes to fuzz.",
"WorthFuzzing": false
} |
| 15/1 | 2026/10/28 14:48 | action | If |
0mArgs:{
"WorthFuzzing": false
}Results: null |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|