| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/06/22 11:24 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch is a pure refactoring that introduces type-safe macros (KHOSER_COPY_TYPESAFE, KHOSER_LOAD_PTR, etc.) for serializing and deserializing pointers in the liveupdate/kexec_handover subsystem. It replaces raw u64 fields with a union and updates the assignments to use the new macros. There are no functional changes to the execution flow or logic that would warrant fuzzing.",
"WorthFuzzing": false
} |
| 1/1 | 2026/06/22 11:24 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 682d0775f696f4351a6ff6767837b1ceb71e7e79\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Mon Jun 22 11:24:09 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/include/linux/kho/abi/kexec_handover.h b/include/linux/kho/abi/kexec_handover.h\nindex 5e2eb8519bda6d..618408fbe9c91f 100644\n--- a/include/linux/kho/abi/kexec_handover.h\n+++ b/include/linux/kho/abi/kexec_handover.h\n@@ -139,6 +139,18 @@\n \t\t(typeof((s).ptr))((s).phys ? phys_to_virt((s).phys) : NULL); \\\n \t})\n \n+/* Copies one serializable pointer to another of same type. */\n+#define KHOSER_COPY_TYPESAFE(dest, src) \\\n+\t({ \\\n+\t\ttypecheck(typeof((dest).ptr), (src).ptr); \\\n+\t\t(dest).phys = (src).phys; \\\n+\t})\n+\n+/* Copies one serializable pointer to another. */\n+#define KHOSER_COPY_TYPEUNSAFE(dest, src) \\\n+\t({ \\\n+\t\t(dest).phys = (src).phys; \\\n+\t})\n /*\n * This header is embedded at the beginning of each `kho_vmalloc_chunk`\n * and contains a pointer to the next chunk in the linked list,\ndiff --git a/include/linux/kho/abi/luo.h b/include/linux/kho/abi/luo.h\nindex 288076de6d4a09..d5b3b1c0fec12c 100644\n--- a/include/linux/kho/abi/luo.h\n+++ b/include/linux/kho/abi/luo.h\n@@ -59,6 +59,7 @@\n \n #include \u003clinux/align.h\u003e\n #include \u003clinux/kho/abi/block.h\u003e\n+#include \u003clinux/kho/abi/kexec_handover.h\u003e\n #include \u003cuapi/linux/liveupdate.h\u003e\n \n /*\n@@ -89,14 +90,14 @@ struct luo_ser {\n /**\n * struct luo_file_ser - Represents the serialized preserves files.\n * @compatible: File handler compatible string.\n- * @data: Private data\n+ * @serialized_data: The serialized pointer union for this file\n * @token: User provided token for this file\n *\n * If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated.\n */\n struct luo_file_ser {\n \tchar compatible[LIVEUPDATE_HNDL_COMPAT_LENGTH];\n-\tu64 data;\n+\tDECLARE_KHOSER_PTR(serialized_data, void *);\n \tu64 token;\n } __packed;\n \ndiff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h\nindex 88722e5caf020b..480d638b7d18c7 100644\n--- a/include/linux/liveupdate.h\n+++ b/include/linux/liveupdate.h\n@@ -33,7 +33,7 @@ struct file;\n * @file: The file object. For retrieve: [OUT] The callback sets\n * this to the new file. For other ops: [IN] The caller sets\n * this to the file being operated on.\n- * @serialized_data: The opaque u64 handle, preserve/prepare/freeze may update\n+ * @serialized_data: The serialized pointer union, preserve/prepare/freeze may update\n * this field.\n * @private_data: Private data for the file used to hold runtime state that\n * is not preserved. Set by the handler's .preserve()\n@@ -47,7 +47,7 @@ struct liveupdate_file_op_args {\n \tstruct liveupdate_file_handler *handler;\n \tint retrieve_status;\n \tstruct file *file;\n-\tu64 serialized_data;\n+\tDECLARE_KHOSER_PTR(serialized_data, void *);\n \tvoid *private_data;\n };\n \ndiff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c\nindex c39f96961a85be..79cfa520189911 100644\n--- a/kernel/liveupdate/luo_file.c\n+++ b/kernel/liveupdate/luo_file.c\n@@ -125,7 +125,7 @@ static DEFINE_XARRAY(luo_preserved_files);\n * @file: Pointer to the kernel's \u0026struct file that is being preserved.\n * This is NULL in the new kernel until the file is successfully\n * retrieved.\n- * @serialized_data: The opaque u64 handle to the serialized state of the file.\n+ * @serialized_data: The serialized pointer union to the serialized state of the file.\n * This handle is passed back to the handler's .freeze(),\n * .retrieve(), and .finish() callbacks, allowing it to track\n * and update its serialized state across phases.\n@@ -161,7 +161,7 @@ static DEFINE_XARRAY(luo_preserved_files);\n struct luo_file {\n \tstruct liveupdate_file_handler *fh;\n \tstruct file *file;\n-\tu64 serialized_data;\n+\tDECLARE_KHOSER_PTR(serialized_data, void *);\n \tvoid *private_data;\n \tint retrieve_status;\n \tstruct mutex mutex;\n@@ -289,7 +289,7 @@ int luo_preserve_file(struct luo_file_set *file_set, u64 token, int fd)\n \tif (err)\n \t\tgoto err_kfree;\n \n-\tluo_file-\u003eserialized_data = args.serialized_data;\n+\tKHOSER_COPY_TYPESAFE(luo_file-\u003eserialized_data, args.serialized_data);\n \tluo_file-\u003eprivate_data = args.private_data;\n \tlist_add_tail(\u0026luo_file-\u003elist, \u0026file_set-\u003efiles_list);\n \tfile_set-\u003ecount++;\n@@ -342,7 +342,7 @@ void luo_file_unpreserve_files(struct luo_file_set *file_set)\n \n \t\targs.handler = luo_file-\u003efh;\n \t\targs.file = luo_file-\u003efile;\n-\t\targs.serialized_data = luo_file-\u003eserialized_data;\n+\t\tKHOSER_COPY_TYPESAFE(args.serialized_data, luo_file-\u003eserialized_data);\n \t\targs.private_data = luo_file-\u003eprivate_data;\n \t\tluo_file-\u003efh-\u003eops-\u003eunpreserve(\u0026args);\n \t\tluo_flb_file_unpreserve(luo_file-\u003efh);\n@@ -375,12 +375,12 @@ static int luo_file_freeze_one(struct luo_file_set *file_set,\n \n \t\targs.handler = luo_file-\u003efh;\n \t\targs.file = luo_file-\u003efile;\n-\t\targs.serialized_data = luo_file-\u003eserialized_data;\n+\t\tKHOSER_COPY_TYPESAFE(args.serialized_data, luo_file-\u003eserialized_data);\n \t\targs.private_data = luo_file-\u003eprivate_data;\n \n \t\terr = luo_file-\u003efh-\u003eops-\u003efreeze(\u0026args);\n \t\tif (!err)\n-\t\t\tluo_file-\u003eserialized_data = args.serialized_data;\n+\t\t\tKHOSER_COPY_TYPESAFE(luo_file-\u003eserialized_data, args.serialized_data);\n \t}\n \n \treturn err;\n@@ -396,7 +396,7 @@ static void luo_file_unfreeze_one(struct luo_file_set *file_set,\n \n \t\targs.handler = luo_file-\u003efh;\n \t\targs.file = luo_file-\u003efile;\n-\t\targs.serialized_data = luo_file-\u003eserialized_data;\n+\t\tKHOSER_COPY_TYPESAFE(args.serialized_data, luo_file-\u003eserialized_data);\n \t\targs.private_data = luo_file-\u003eprivate_data;\n \n \t\tluo_file-\u003efh-\u003eops-\u003eunfreeze(\u0026args);\n@@ -483,7 +483,7 @@ int luo_file_freeze(struct luo_file_set *file_set,\n \n \t\tstrscpy(file_ser-\u003ecompatible, luo_file-\u003efh-\u003ecompatible,\n \t\t\tsizeof(file_ser-\u003ecompatible));\n-\t\tfile_ser-\u003edata = luo_file-\u003eserialized_data;\n+\t\tKHOSER_COPY_TYPESAFE(file_ser-\u003eserialized_data, luo_file-\u003eserialized_data);\n \t\tfile_ser-\u003etoken = luo_file-\u003etoken;\n \t}\n \n@@ -587,7 +587,7 @@ int luo_retrieve_file(struct luo_file_set *file_set, u64 token,\n \t}\n \n \targs.handler = luo_file-\u003efh;\n-\targs.serialized_data = luo_file-\u003eserialized_data;\n+\tKHOSER_COPY_TYPESAFE(args.serialized_data, luo_file-\u003eserialized_data);\n \terr = luo_file-\u003efh-\u003eops-\u003eretrieve(\u0026args);\n \tif (err) {\n \t\t/* Keep the error code for later use. */\n@@ -621,7 +621,7 @@ static int luo_file_can_finish_one(struct luo_file_set *file_set,\n \n \t\targs.handler = luo_file-\u003efh;\n \t\targs.file = luo_file-\u003efile;\n-\t\targs.serialized_data = luo_file-\u003eserialized_data;\n+\t\tKHOSER_COPY_TYPESAFE(args.serialized_data, luo_file-\u003eserialized_data);\n \t\targs.retrieve_status = luo_file-\u003eretrieve_status;\n \t\tcan_finish = luo_file-\u003efh-\u003eops-\u003ecan_finish(\u0026args);\n \t}\n@@ -638,7 +638,7 @@ static void luo_file_finish_one(struct luo_file_set *file_set,\n \n \targs.handler = luo_file-\u003efh;\n \targs.file = luo_file-\u003efile;\n-\targs.serialized_data = luo_file-\u003eserialized_data;\n+\tKHOSER_COPY_TYPESAFE(args.serialized_data, luo_file-\u003eserialized_data);\n \targs.retrieve_status = luo_file-\u003eretrieve_status;\n \n \tluo_file-\u003efh-\u003eops-\u003efinish(\u0026args);\n@@ -748,7 +748,7 @@ static int luo_file_deserialize_one(struct luo_file_set *file_set,\n \n \tluo_file-\u003efh = fh;\n \tluo_file-\u003efile = NULL;\n-\tluo_file-\u003eserialized_data = ser-\u003edata;\n+\tKHOSER_COPY_TYPESAFE(luo_file-\u003eserialized_data, ser-\u003eserialized_data);\n \tluo_file-\u003etoken = ser-\u003etoken;\n \tmutex_init(\u0026luo_file-\u003emutex);\n \tlist_add_tail(\u0026luo_file-\u003elist, \u0026file_set-\u003efiles_list);\ndiff --git a/mm/memfd_luo.c b/mm/memfd_luo.c\nindex 59de210bee5f9e..daf2c4c3da35f3 100644\n--- a/mm/memfd_luo.c\n+++ b/mm/memfd_luo.c\n@@ -257,6 +257,7 @@ static void memfd_luo_unpreserve_folios(struct kho_vmalloc *kho_vmalloc,\n \n static int memfd_luo_preserve(struct liveupdate_file_op_args *args)\n {\n+\tDECLARE_KHOSER_PTR(sd, struct memfd_luo_ser *);\n \tstruct inode *inode = file_inode(args-\u003efile);\n \tstruct memfd_luo_folio_ser *folios_ser;\n \tstruct memfd_luo_ser *ser;\n@@ -309,7 +310,8 @@ static int memfd_luo_preserve(struct liveupdate_file_op_args *args)\n \tinode_unlock(inode);\n \n \targs-\u003eprivate_data = folios_ser;\n-\targs-\u003eserialized_data = virt_to_phys(ser);\n+\tKHOSER_STORE_PTR(sd, ser);\n+\tKHOSER_COPY_TYPEUNSAFE(args-\u003eserialized_data, sd);\n \n \treturn 0;\n \n@@ -325,11 +327,10 @@ static int memfd_luo_freeze(struct liveupdate_file_op_args *args)\n {\n \tstruct memfd_luo_ser *ser;\n \n-\tif (WARN_ON_ONCE(!args-\u003eserialized_data))\n+\tser = KHOSER_LOAD_PTR(args-\u003eserialized_data);\n+\tif (WARN_ON_ONCE(!ser))\n \t\treturn -EINVAL;\n \n-\tser = phys_to_virt(args-\u003eserialized_data);\n-\n \t/*\n \t * The pos might have changed since prepare. Everything else stays the\n \t * same.\n@@ -344,14 +345,13 @@ static void memfd_luo_unpreserve(struct liveupdate_file_op_args *args)\n \tstruct inode *inode = file_inode(args-\u003efile);\n \tstruct memfd_luo_ser *ser;\n \n-\tif (WARN_ON_ONCE(!args-\u003eserialized_data))\n+\tser = KHOSER_LOAD_PTR(args-\u003eserialized_data);\n+\tif (WARN_ON_ONCE(!ser))\n \t\treturn;\n \n \tinode_lock(inode);\n \tshmem_freeze(inode, false);\n \n-\tser = phys_to_virt(args-\u003eserialized_data);\n-\n \tmemfd_luo_unpreserve_folios(\u0026ser-\u003efolios, args-\u003eprivate_data,\n \t\t\t\t ser-\u003enr_folios);\n \n@@ -397,7 +397,7 @@ static void memfd_luo_finish(struct liveupdate_file_op_args *args)\n \tif (args-\u003eretrieve_status)\n \t\treturn;\n \n-\tser = phys_to_virt(args-\u003eserialized_data);\n+\tser = KHOSER_LOAD_PTR(args-\u003eserialized_data);\n \tif (!ser)\n \t\treturn;\n \n@@ -522,7 +522,7 @@ static int memfd_luo_retrieve(struct liveupdate_file_op_args *args)\n \tstruct file *file;\n \tint err;\n \n-\tser = phys_to_virt(args-\u003eserialized_data);\n+\tser = KHOSER_LOAD_PTR(args-\u003eserialized_data);\n \tif (!ser)\n \t\treturn -EINVAL;\n \n"
} |
| 2/1 | 2026/06/22 11:24 | agent | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch is a pure refactoring that introduces type-safe macros (KHOSER_COPY_TYPESAFE, KHOSER_LOAD_PTR, etc.) for serializing and deserializing pointers in the liveupdate/kexec_handover subsystem. It replaces raw u64 fields with a union and updates the assignments to use the new macros. There are no functional changes to the execution flow or logic that would warrant fuzzing.",
"WorthFuzzing": false
}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 682d0775f696f4351a6ff6767837b1ceb71e7e79
Author: syz-cluster <triage@syzkaller.com>
Date: Mon Jun 22 11:24:09 2026 +0000
syz-cluster: applied patch under review
diff --git a/include/linux/kho/abi/kexec_handover.h b/include/linux/kho/abi/kexec_handover.h
index 5e2eb8519bda6d..618408fbe9c91f 100644
--- a/include/linux/kho/abi/kexec_handover.h
+++ b/include/linux/kho/abi/kexec_handover.h
@@ -139,6 +139,18 @@
(typeof((s).ptr))((s).phys ? phys_to_virt((s).phys) : NULL); \
})
+/* Copies one serializable pointer to another of same type. */
+#define KHOSER_COPY_TYPESAFE(dest, src) \
+ ({ \
+ typecheck(typeof((dest).ptr), (src).ptr); \
+ (dest).phys = (src).phys; \
+ })
+
+/* Copies one serializable pointer to another. */
+#define KHOSER_COPY_TYPEUNSAFE(dest, src) \
+ ({ \
+ (dest).phys = (src).phys; \
+ })
/*
* This header is embedded at the beginning of each `kho_vmalloc_chunk`
* and contains a pointer to the next chunk in the linked list,
diff --git a/include/linux/kho/abi/luo.h b/include/linux/kho/abi/luo.h
index 288076de6d4a09..d5b3b1c0fec12c 100644
--- a/include/linux/kho/abi/luo.h
+++ b/include/linux/kho/abi/luo.h
@@ -59,6 +59,7 @@
#include <linux/align.h>
#include <linux/kho/abi/block.h>
+#include <linux/kho/abi/kexec_handover.h>
#include <uapi/linux/liveupdate.h>
/*
@@ -89,14 +90,14 @@ struct luo_ser {
/**
* struct luo_file_ser - Represents the serialized preserves files.
* @compatible: File handler compatible string.
- * @data: Private data
+ * @serialized_data: The serialized pointer union for this file
* @token: User provided token for this file
*
* If this structure is modified, `LUO_ABI_COMPATIBLE` must be updated.
*/
struct luo_file_ser {
char compatible[LIVEUPDATE_HNDL_COMPAT_LENGTH];
- u64 data;
+ DECLARE_KHOSER_PTR(serialized_data, void *);
u64 token;
} __packed;
diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h
index 88722e5caf020b..480d638b7d18c7 100644
--- a/include/linux/liveupdate.h
+++ b/include/linux/liveupdate.h
@@ -33,7 +33,7 @@ struct file;
* @file: The file object. For retrieve: [OUT] The callback sets
* this to the new file. For other ops: [IN] The caller sets
* this to the file being operated on.
- * @serialized_data: The opaque u64 handle, preserve/prepare/freeze may update
+ * @serialized_data: The serialized pointer union, preserve/prepare/freeze may update
* this field.
* @private_data: Private data for the file used to hold runtime state that
* is not preserved. Set by the handler's .preserve()
@@ -47,7 +47,7 @@ struct liveupdate_file_op_args {
struct liveupdate_file_handler *handler;
int retrieve_status;
struct file *file;
- u64 serialized_data;
+ DECLARE_KHOSER_PTR(serialized_data, void *);
void *private_data;
};
diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c
index c39f96961a85be..79cfa520189911 100644
--- a/kernel/liveupdate/luo_file.c
+++ b/kernel/liveupdate/luo_file.c
@@ -125,7 +125,7 @@ static DEFINE_XARRAY(luo_preserved_files);
* @file: Pointer to the kernel's &struct file that is being preserved.
* This is NULL in the new kernel until the file is successfully
* retrieved.
- * @serialized_data: The opaque u64 handle to the serialized state of the file.
+ * @serialized_data: The serialized pointer union to the serialized state of the file.
* This handle is passed back to the handler's .freeze(),
* .retrieve(), and .finish() callbacks, allowing it to track
* and update its serialized state across phases.
@@ -161,7 +161,7 @@ static DEFINE_XARRAY(luo_preserved_files);
struct luo_file {
struct liveupdate_file_handler *fh;
struct file *file;
- u64 serialized_data;
+ DECLARE_KHOSER_PTR(serialized_data, void *);
void *private_data;
int retrieve_status;
struct mutex mutex;
@@ -289,7 +289,7 @@ int luo_preserve_file(struct luo_file_set *file_set, u64 token, int fd)
if (err)
goto err_kfree;
- luo_file->serialized_data = args.serialized_data;
+ KHOSER_COPY_TYPESAFE(luo_file->serialized_data, args.serialized_data);
luo_file->private_data = args.private_data;
list_add_tail(&luo_file->list, &file_set->files_list);
file_set->count++;
@@ -342,7 +342,7 @@ void luo_file_unpreserve_files(struct luo_file_set *file_set)
args.handler = luo_file->fh;
args.file = luo_file->file;
- args.serialized_data = luo_file->serialized_data;
+ KHOSER_COPY_TYPESAFE(args.serialized_data, luo_file->serialized_data);
args.private_data = luo_file->private_data;
luo_file->fh->ops->unpreserve(&args);
luo_flb_file_unpreserve(luo_file->fh);
@@ -375,12 +375,12 @@ static int luo_file_freeze_one(struct luo_file_set *file_set,
args.handler = luo_file->fh;
args.file = luo_file->file;
- args.serialized_data = luo_file->serialized_data;
+ KHOSER_COPY_TYPESAFE(args.serialized_data, luo_file->serialized_data);
args.private_data = luo_file->private_data;
err = luo_file->fh->ops->freeze(&args);
if (!err)
- luo_file->serialized_data = args.serialized_data;
+ KHOSER_COPY_TYPESAFE(luo_file->serialized_data, args.serialized_data);
}
return err;
@@ -396,7 +396,7 @@ static void luo_file_unfreeze_one(struct luo_file_set *file_set,
args.handler = luo_file->fh;
args.file = luo_file->file;
- args.serialized_data = luo_file->serialized_data;
+ KHOSER_COPY_TYPESAFE(args.serialized_data, luo_file->serialized_data);
args.private_data = luo_file->private_data;
luo_file->fh->ops->unfreeze(&args);
@@ -483,7 +483,7 @@ int luo_file_freeze(struct luo_file_set *file_set,
strscpy(file_ser->compatible, luo_file->fh->compatible,
sizeof(file_ser->compatible));
- file_ser->data = luo_file->serialized_data;
+ KHOSER_COPY_TYPESAFE(file_ser->serialized_data, luo_file->serialized_data);
file_ser->token = luo_file->token;
}
@@ -587,7 +587,7 @@ int luo_retrieve_file(struct luo_file_set *file_set, u64 token,
}
args.handler = luo_file->fh;
- args.serialized_data = luo_file->serialized_data;
+ KHOSER_COPY_TYPESAFE(args.serialized_data, luo_file->serialized_data);
err = luo_file->fh->ops->retrieve(&args);
if (err) {
/* Keep the error code for later use. */
@@ -621,7 +621,7 @@ static int luo_file_can_finish_one(struct luo_file_set *file_set,
args.handler = luo_file->fh;
args.file = luo_file->file;
- args.serialized_data = luo_file->serialized_data;
+ KHOSER_COPY_TYPESAFE(args.serialized_data, luo_file->serialized_data);
args.retrieve_status = luo_file->retrieve_status;
can_finish = luo_file->fh->ops->can_finish(&args);
}
@@ -638,7 +638,7 @@ static void luo_file_finish_one(struct luo_file_set *file_set,
args.handler = luo_file->fh;
args.file = luo_file->file;
- args.serialized_data = luo_file->serialized_data;
+ KHOSER_COPY_TYPESAFE(args.serialized_data, luo_file->serialized_data);
args.retrieve_status = luo_file->retrieve_status;
luo_file->fh->ops->finish(&args);
@@ -748,7 +748,7 @@ static int luo_file_deserialize_one(struct luo_file_set *file_set,
luo_file->fh = fh;
luo_file->file = NULL;
- luo_file->serialized_data = ser->data;
+ KHOSER_COPY_TYPESAFE(luo_file->serialized_data, ser->serialized_data);
luo_file->token = ser->token;
mutex_init(&luo_file->mutex);
list_add_tail(&luo_file->list, &file_set->files_list);
diff --git a/mm/memfd_luo.c b/mm/memfd_luo.c
index 59de210bee5f9e..daf2c4c3da35f3 100644
--- a/mm/memfd_luo.c
+++ b/mm/memfd_luo.c
@@ -257,6 +257,7 @@ static void memfd_luo_unpreserve_folios(struct kho_vmalloc *kho_vmalloc,
static int memfd_luo_preserve(struct liveupdate_file_op_args *args)
{
+ DECLARE_KHOSER_PTR(sd, struct memfd_luo_ser *);
struct inode *inode = file_inode(args->file);
struct memfd_luo_folio_ser *folios_ser;
struct memfd_luo_ser *ser;
@@ -309,7 +310,8 @@ static int memfd_luo_preserve(struct liveupdate_file_op_args *args)
inode_unlock(inode);
args->private_data = folios_ser;
- args->serialized_data = virt_to_phys(ser);
+ KHOSER_STORE_PTR(sd, ser);
+ KHOSER_COPY_TYPEUNSAFE(args->serialized_data, sd);
return 0;
@@ -325,11 +327,10 @@ static int memfd_luo_freeze(struct liveupdate_file_op_args *args)
{
struct memfd_luo_ser *ser;
- if (WARN_ON_ONCE(!args->serialized_data))
+ ser = KHOSER_LOAD_PTR(args->serialized_data);
+ if (WARN_ON_ONCE(!ser))
return -EINVAL;
- ser = phys_to_virt(args->serialized_data);
-
/*
* The pos might have changed since prepare. Everything else stays the
* same.
@@ -344,14 +345,13 @@ static void memfd_luo_unpreserve(struct liveupdate_file_op_args *args)
struct inode *inode = file_inode(args->file);
struct memfd_luo_ser *ser;
- if (WARN_ON_ONCE(!args->serialized_data))
+ ser = KHOSER_LOAD_PTR(args->serialized_data);
+ if (WARN_ON_ONCE(!ser))
return;
inode_lock(inode);
shmem_freeze(inode, false);
- ser = phys_to_virt(args->serialized_data);
-
memfd_luo_unpreserve_folios(&ser->folios, args->private_data,
ser->nr_folios);
@@ -397,7 +397,7 @@ static void memfd_luo_finish(struct liveupdate_file_op_args *args)
if (args->retrieve_status)
return;
- ser = phys_to_virt(args->serialized_data);
+ ser = KHOSER_LOAD_PTR(args->serialized_data);
if (!ser)
return;
@@ -522,7 +522,7 @@ static int memfd_luo_retrieve(struct liveupdate_file_op_args *args)
struct file *file;
int err;
- ser = phys_to_virt(args->serialized_data);
+ ser = KHOSER_LOAD_PTR(args->serialized_data);
if (!ser)
return -EINVAL;
|
| 3/2 | 2026/06/22 11:24 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 5401 output: 21 thoughts: 514 Thoughts: **Refactoring Serialization/Deserialization in the KHO Subsystem** Alright, let's break down this patch. My initial impression is that it's a refactoring effort within the liveupdate/kexec_handover (KHO) subsystem. Specifically, it seems like a move away from using raw `u64` for serialized pointers and towards a more structured approach leveraging `DECLARE_KHOSER_PTR` and associated macros. The core of the change appears to be in `include/linux/kho/abi/kexec_handover.h`. It introduces two new macros: `KHOSER_COPY_TYPESAFE` and `KHOSER_COPY_TYPEUNSAFE`. It looks like `KHOSER_COPY_TYPESAFE` performs a `typecheck` before copying the physical address, while `KHOSER_COPY_TYPEUNSAFE` copies the physical address directly. I need to dig deeper into the actual definition of `DECLARE_KHOSER_PTR` to fully understand the implications. The patch also updates several key data structures, namely `struct luo_file_ser` and `struct liveupdate_file_op_args` to use these new macros and the `DECLARE_KHOSER_PTR` data structure. The change touches `kernel/liveupdate/luo_file.c` and `mm/memfd_luo.c`, so it's clearly impacting the implementation side, too. Given the file locations and the nature of the changes, this seems to be about improving the way pointers are handled during live updates and kexec handovers – which makes sense. I see the main impact is replacing assignments and pointer conversions, like `virt_to_phys`/`phys_to_virt`, with the macros `KHOSER_COPY_TYPESAFE`, `KHOSER_STORE_PTR`, `KHOSER_LOAD_PTR`. Now, I'm trying to ascertain if this is purely a refactoring for type safety, or if there's a functional aspect to it. Looking at the macro definitions, `KHOSER_COPY_TYPESAFE` uses `typecheck`, but both macros ultimately just copy the `.phys` member. Thus, the macros alone don't appear to be introducing a significant functional change. The key must lie in how `DECLARE_KHOSER_PTR` defines the internal structure for these serialized pointers, and how the various copy and load operations are actually implemented. I need to review `include/linux/kho/abi/kexec_handover.h` to see how those are set up. |
| 4/2 | 2026/06/22 11:24 | tool | grepper |
0mArgs:{
"Expression": "DECLARE_KHOSER_PTR"
}Results: {
"Output": "include/linux/kho/abi/kexec_handover.h-120-/* Helper macro to define a union for a serializable pointer. */\ninclude/linux/kho/abi/kexec_handover.h:121:#define DECLARE_KHOSER_PTR(name, type)\t\\\ninclude/linux/kho/abi/kexec_handover.h-122-\tunion { \\\n--\ninclude/linux/kho/abi/kexec_handover.h=159=struct kho_vmalloc_hdr {\ninclude/linux/kho/abi/kexec_handover.h:160:\tDECLARE_KHOSER_PTR(next, struct kho_vmalloc_chunk *);\ninclude/linux/kho/abi/kexec_handover.h-161-};\n--\ninclude/linux/kho/abi/kexec_handover.h=185=struct kho_vmalloc {\ninclude/linux/kho/abi/kexec_handover.h:186:\tDECLARE_KHOSER_PTR(first, struct kho_vmalloc_chunk *);\ninclude/linux/kho/abi/kexec_handover.h-187-\tunsigned int total_pages;\n--\ninclude/linux/kho/abi/luo.h=98=struct luo_file_ser {\ninclude/linux/kho/abi/luo.h-99-\tchar compatible[LIVEUPDATE_HNDL_COMPAT_LENGTH];\ninclude/linux/kho/abi/luo.h:100:\tDECLARE_KHOSER_PTR(serialized_data, void *);\ninclude/linux/kho/abi/luo.h-101-\tu64 token;\n--\ninclude/linux/liveupdate.h=46=struct liveupdate_file_op_args {\n--\ninclude/linux/liveupdate.h-49-\tstruct file *file;\ninclude/linux/liveupdate.h:50:\tDECLARE_KHOSER_PTR(serialized_data, void *);\ninclude/linux/liveupdate.h-51-\tvoid *private_data;\n--\nkernel/liveupdate/luo_file.c=161=struct luo_file {\n--\nkernel/liveupdate/luo_file.c-163-\tstruct file *file;\nkernel/liveupdate/luo_file.c:164:\tDECLARE_KHOSER_PTR(serialized_data, void *);\nkernel/liveupdate/luo_file.c-165-\tvoid *private_data;\n--\nmm/memfd_luo.c=258=static int memfd_luo_preserve(struct liveupdate_file_op_args *args)\nmm/memfd_luo.c-259-{\nmm/memfd_luo.c:260:\tDECLARE_KHOSER_PTR(sd, struct memfd_luo_ser *);\nmm/memfd_luo.c-261-\tstruct inode *inode = file_inode(args-\u003efile);\n"
} |
| 5/2 | 2026/06/22 11:24 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 7221 output: 121 thoughts: 1533 Thoughts: **Analysis of the Pointer Serialization Patch** Okay, let's break this down. The core of this patch seems to be about how pointers are serialized and deserialized within this system. It replaces a straightforward `u64` for storing physical addresses with a `union` containing both a pointer (`ptr`) and a physical address (`phys`) – essentially, a typed wrapper around the existing physical address representation. My initial thought is to ascertain if this represents a functional change. Looking at the code snippets, the *actual* mechanics remain consistent. The old method stored the result of `virt_to_phys(ser)` directly into a `u64`. The new method uses macros, `KHOSER_STORE_PTR` and `KHOSER_LOAD_PTR`, but essentially does the *same* thing: stores `virt_to_phys(p)` (or zero if the pointer is null) into the `.phys` member, and loads it back using `phys_to_virt`. The key differences I see are type safety and readability, which is good. The fact that `luo_file_ser` is part of the ABI raises a concern. This is an area where changes need to be especially well scrutinized. However, the `DECLARE_KHOSER_PTR` macro ensures the size and layout of the `luo_file_ser` struct remains identical because both the pointer and the `u64` are 8 bytes each, the size of the union. The structure's size isn't impacted by this change. It's a refactoring to improve clarity. Digging deeper, I see a check: `if (WARN_ON_ONCE(!args->serialized_data))`. This has been updated to use the macro: `ser = KHOSER_LOAD_PTR(args->serialized_data); if (WARN_ON_ONCE(!ser))`. Previously, it checked a `u64` directly; now it checks the dereferenced pointer from that `u64`. `KHOSER_LOAD_PTR` handles the translation, and correctly returns `NULL` if the `.phys` member is zero. This, on its face, appears functionally identical. If `phys` is zero, it correctly returns `NULL`, and the warning fires as it should. Now, here's a subtle but important point. In the older version, `phys_to_virt(0)` *might* not necessarily return `NULL` on all architectures. On x86, for instance, `phys_to_virt(0)` would return `PAGE_OFFSET`, which is *not* zero. This could create a divergence. However, the code's behavior *shouldn't* depend on `phys_to_virt(0)` yielding `NULL`, but on the value being uninitialized. It seems like the original code did not account for that edge case, and has now been corrected (in a minor way, it seems) because `KHOSER_LOAD_PTR` *always* returns `NULL` when `.phys` is 0. Looking at where the `serialized_data` is initialized, it is set with `virt_to_phys(ser)` where `ser` is allocated with `kzalloc`. So, `virt_to_phys(ser)` is not zero, and `args->serialized_data` would not be zero. It's safe to assume that `args->serialized_data` should never be 0 in practice and it is a bug if it is. So, functionally, the change makes a small correction in the rare event of `args->serialized_data` being uninitialized, and does not alter the execution flow or introduce any new functional logic. In conclusion, I'm confident that this is a purely refactoring patch, aimed at improving type safety and potentially fixing a minor theoretical bug related to how `phys_to_virt(0)` is handled. Since it's a refactoring and doesn't introduce any new logic or expose new attack surfaces, I would classify this as WorthFuzzing=false. |
| 6/2 | 2026/06/22 11:24 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch is a pure refactoring that introduces type-safe macros (KHOSER_COPY_TYPESAFE, KHOSER_LOAD_PTR, etc.) for serializing and deserializing pointers in the liveupdate/kexec_handover subsystem. It replaces raw u64 fields with a union and updates the assignments to use the new macros. There are no functional changes to the execution flow or logic that would warrant fuzzing.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch is a pure refactoring that introduces type-safe macros (KHOSER_COPY_TYPESAFE, KHOSER_LOAD_PTR, etc.) for serializing and deserializing pointers in the liveupdate/kexec_handover subsystem. It replaces raw u64 fields with a union and updates the assignments to use the new macros. There are no functional changes to the execution flow or logic that would warrant fuzzing.",
"WorthFuzzing": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|