[PATCH 03/11] moduleparam: Add DEFINE_KERNEL_PARAM_OPS macro family

2 views
Skip to first unread message

Kees Cook

unread,
May 21, 2026, 11:11:26 AMMay 21
to Luis Chamberlain, Kees Cook, Pengpeng Hou, Petr Pavlu, Richard Weinberger, Anton Ivanov, Johannes Berg, Rafael J. Wysocki, Len Brown, Corey Minyard, Gabriel Somlo, Michael S. Tsirkin, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, David Airlie, Simona Vetter, Bart Van Assche, Jason Gunthorpe, Leon Romanovsky, Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab, Bjorn Helgaas, Hannes Reinecke, James E.J. Bottomley, Martin K. Petersen, Daniel Lezcano, Zhang Rui, Lukasz Luba, Greg Kroah-Hartman, Jiri Slaby, Alan Stern, Jason Wang, Xuan Zhuo, Eugenio Pérez, Jason Baron, Jim Cromie, Tiwei Bie, Benjamin Berg, Ilpo Järvinen, David E. Box, Maciej W. Rozycki, Srinivas Pandruvada, Peter Zijlstra, Heiko Carstens, Vasily Gorbik, Sean Christopherson, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x...@kernel.org, H. Peter Anvin, Vinod Koul, Frank Li, Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Alexander Potapenko, Marco Elver, Dmitry Vyukov, Andrew Morton, John Johansen, Paul Moore, James Morris, Serge E. Hallyn, Andy Shevchenko, Georgia Garcia, k...@vger.kernel.org, dmae...@vger.kernel.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linu...@kvack.org, appa...@lists.ubuntu.com, linux-secu...@vger.kernel.org, linu...@lists.infradead.org, linux...@vger.kernel.org, openipmi-...@lists.sourceforge.net, qemu-...@nongnu.org, inte...@lists.freedesktop.org, dri-...@lists.freedesktop.org, linux...@vger.kernel.org, linux...@vger.kernel.org, linu...@vger.kernel.org, linux...@vger.kernel.org, linu...@vger.kernel.org, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, linu...@vger.kernel.org, usb-s...@lists.one-eyed-alien.net, virtual...@lists.linux.dev, linux-...@vger.kernel.org, linux...@vger.kernel.org, net...@vger.kernel.org, linux-...@vger.kernel.org, linux-h...@vger.kernel.org
Add macros that define a struct kernel_param_ops initializer through a
macro so the underlying field layout can evolve without touching every
call site. Three variants cover the three cases:

DEFINE_KERNEL_PARAM_OPS(name, set, get) // basic
DEFINE_KERNEL_PARAM_OPS_NOARG(name, set, get) // set KERNEL_PARAM_OPS_FL_NOARG
DEFINE_KERNEL_PARAM_OPS_FREE(name, set, get, free) // also set .free

Callers prefix their own visibility qualifiers, e.g.:

static DEFINE_KERNEL_PARAM_OPS(my_ops, my_set, my_get);

Also update module_param_call() and STANDARD_PARAM_DEF() to use
DEFINE_KERNEL_PARAM_OPS internally so the generated ops table will go
through the same macro as everything else.

Subsequent commits convert all open-coded struct kernel_param_ops
definitions to use these macros, in preparation for migrating to a
seq_buf .get API.

Signed-off-by: Kees Cook <ke...@kernel.org>
---
include/linux/moduleparam.h | 36 ++++++++++++++++++++++++++++++++++--
kernel/params.c | 6 ++----
2 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index 075f28585074..26bf45b36d02 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -68,6 +68,39 @@ struct kernel_param_ops {
void (*free)(void *arg);
};

+/*
+ * Define a const struct kernel_param_ops initializer. Callers prefix with
+ * any required visibility qualifiers (typically "static"):
+ *
+ * static DEFINE_KERNEL_PARAM_OPS(my_ops, my_set, my_get);
+ *
+ * Routing the @_set and @_get function pointers through the macro
+ * (rather than naming the struct fields at every call site) lets the
+ * field layout change in one place when callbacks are migrated to a
+ * new signature.
+ */
+#define DEFINE_KERNEL_PARAM_OPS(_name, _set, _get) \
+ const struct kernel_param_ops _name = { \
+ .set = (_set), \
+ .get = (_get), \
+ }
+
+/* As DEFINE_KERNEL_PARAM_OPS, with KERNEL_PARAM_OPS_FL_NOARG set. */
+#define DEFINE_KERNEL_PARAM_OPS_NOARG(_name, _set, _get) \
+ const struct kernel_param_ops _name = { \
+ .flags = KERNEL_PARAM_OPS_FL_NOARG, \
+ .set = (_set), \
+ .get = (_get), \
+ }
+
+/* As DEFINE_KERNEL_PARAM_OPS, with an additional .free callback. */
+#define DEFINE_KERNEL_PARAM_OPS_FREE(_name, _set, _get, _free) \
+ const struct kernel_param_ops _name = { \
+ .set = (_set), \
+ .get = (_get), \
+ .free = (_free), \
+ }
+
/*
* Flags available for kernel_param
*
@@ -311,8 +344,7 @@ struct kparam_array
* kernel_param_ops), use module_param_cb() instead.
*/
#define module_param_call(name, _set, _get, arg, perm) \
- static const struct kernel_param_ops __param_ops_##name = \
- { .flags = 0, .set = _set, .get = _get }; \
+ static DEFINE_KERNEL_PARAM_OPS(__param_ops_##name, _set, _get); \
__module_param_call(MODULE_PARAM_PREFIX, \
name, &__param_ops_##name, arg, perm, -1, 0)

diff --git a/kernel/params.c b/kernel/params.c
index 752721922a15..2cbad1f4dd06 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -222,10 +222,8 @@ char *parse_args(const char *doing,
return scnprintf(buffer, PAGE_SIZE, format "\n", \
*((type *)kp->arg)); \
} \
- const struct kernel_param_ops param_ops_##name = { \
- .set = param_set_##name, \
- .get = param_get_##name, \
- }; \
+ DEFINE_KERNEL_PARAM_OPS(param_ops_##name, \
+ param_set_##name, param_get_##name); \
EXPORT_SYMBOL(param_set_##name); \
EXPORT_SYMBOL(param_get_##name); \
EXPORT_SYMBOL(param_ops_##name)
--
2.34.1

Petr Pavlu

unread,
May 25, 2026, 12:21:14 PMMay 25
to Kees Cook, Luis Chamberlain, Pengpeng Hou, Richard Weinberger, Anton Ivanov, Johannes Berg, Rafael J. Wysocki, Len Brown, Corey Minyard, Gabriel Somlo, Michael S. Tsirkin, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, David Airlie, Simona Vetter, Bart Van Assche, Jason Gunthorpe, Leon Romanovsky, Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab, Bjorn Helgaas, Hannes Reinecke, James E.J. Bottomley, Martin K. Petersen, Daniel Lezcano, Zhang Rui, Lukasz Luba, Greg Kroah-Hartman, Jiri Slaby, Alan Stern, Jason Wang, Xuan Zhuo, Eugenio Pérez, Jason Baron, Jim Cromie, Tiwei Bie, Benjamin Berg, Ilpo Järvinen, David E. Box, Maciej W. Rozycki, Srinivas Pandruvada, Peter Zijlstra, Heiko Carstens, Vasily Gorbik, Sean Christopherson, Paolo Bonzini, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x...@kernel.org, H. Peter Anvin, Vinod Koul, Frank Li, Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Alexander Potapenko, Marco Elver, Dmitry Vyukov, Andrew Morton, John Johansen, Paul Moore, James Morris, Serge E. Hallyn, Andy Shevchenko, Georgia Garcia, k...@vger.kernel.org, dmae...@vger.kernel.org, linux-...@vger.kernel.org, kasa...@googlegroups.com, linu...@kvack.org, appa...@lists.ubuntu.com, linux-secu...@vger.kernel.org, linu...@lists.infradead.org, linux...@vger.kernel.org, openipmi-...@lists.sourceforge.net, qemu-...@nongnu.org, inte...@lists.freedesktop.org, dri-...@lists.freedesktop.org, linux...@vger.kernel.org, linux...@vger.kernel.org, linu...@vger.kernel.org, linux...@vger.kernel.org, linu...@vger.kernel.org, linuxp...@lists.ozlabs.org, linux-...@vger.kernel.org, linu...@vger.kernel.org, usb-s...@lists.one-eyed-alien.net, virtual...@lists.linux.dev, linux-...@vger.kernel.org, linux...@vger.kernel.org, net...@vger.kernel.org, linux-...@vger.kernel.org, linux-h...@vger.kernel.org
Nit: The newly introduced DEFINE_KERNEL_PARAM_OPS*() macros remain in
place at the end of the series after the migration is complete and this
comment is removed in patch 7. It would be helpful to describe in the
commit message why these macros are generally preferable to defining
kernel_param_ops instances directly.

I assume the motivation is that the structure is simple enough and using
macros then makes defining kernel_param_ops instances a bit more
concise. A minor disadvantage is that some analysis tools, such as
ctags, may no longer see the generated definition, but that is also the
case for DEFINE_MUTEX() and other similar macros.

--
Thanks,
Petr
Reply all
Reply to author
Forward
0 new messages