linux-acpi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/11] Convert moduleparams to seq_buf
@ 2026-05-21 13:33 Kees Cook
  2026-05-21 13:33 ` [PATCH 01/11] params: bound array element output to the caller's page buffer Kees Cook
                   ` (11 more replies)
  0 siblings, 12 replies; 33+ messages in thread
From: Kees Cook @ 2026-05-21 13:33 UTC (permalink / raw)
  To: Luis Chamberlain
  Cc: 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, x86,
	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, kvm, dmaengine,
	linux-modules, kasan-dev, linux-mm, apparmor,
	linux-security-module, linux-um, linux-acpi, openipmi-developer,
	qemu-devel, intel-gfx, dri-devel, linux-rdma, linux-media,
	linux-pci, linux-scsi, linux-pm, linuxppc-dev, linux-serial,
	linux-usb, usb-storage, virtualization, linux-kernel, linux-arch,
	netdev, linux-fsdevel, linux-hardening

Hi,

I tried to trim the CC list here, but it's still pretty huge...

We've had a long-standing issue with "write to a string pointer" callbacks
that don't bounds check the destination (and for which the bounds is
also not part of the callback prototype, even if it is "known" to be
PAGE_SIZE, which sysfs_emit() depends on). Both moduleparams and sysfs
use this pattern. As a first step, and to test the migration method,
migrate moduleparams first.

There are 2 "mechanical" treewide patches that are handled by Coccinelle:
- treewide: Convert struct kernel_param_ops initializers to DEFINE_KERNEL_PARAM_OPS
- treewide: Convert custom kernel_param_ops .get callbacks to seq_buf via cocci

The last treewide patch is manual, and may need to be broken up into
per-subsystem patches, though I'd prefer to avoid this, as it would
extend the migration from 1 relase to at least 2 releases. (1 to
release the migration infrastructure, then 1 release to collect all the
subsystem changes, and possibly 1 more release to remove the migration
infrastructure.)

Thoughts, questions?

-Kees

Kees Cook (10):
  panic: Replace panic_print_get() with generic helper
  moduleparam: Add DEFINE_KERNEL_PARAM_OPS macro family
  treewide: Convert struct kernel_param_ops initializers to
    DEFINE_KERNEL_PARAM_OPS
  moduleparam: Rename .get field to .get_str
  moduleparam: Add seq_buf-based .get callback alongside .get_str
  moduleparam: Route DEFINE_KERNEL_PARAM_OPS get pointer via _Generic
  params: Convert generic kernel_param_ops .get helpers to seq_buf
  treewide: Convert custom kernel_param_ops .get callbacks to seq_buf
    via cocci
  treewide: Manually convert custom kernel_param_ops .get callbacks
  moduleparam: Drop legacy kernel_param_ops .get_str field and dispatch
    logic

Pengpeng Hou (1):
  params: bound array element output to the caller's page buffer

 include/linux/dynamic_debug.h                 |   8 +-
 include/linux/moduleparam.h                   |  65 +++++++---
 security/apparmor/include/lib.h               |   3 +-
 mm/kfence/core.c                              |  15 ++-
 arch/powerpc/kvm/book3s_hv.c                  |   5 +-
 arch/s390/kernel/perf_cpum_sf.c               |  12 +-
 arch/um/drivers/vfio_kern.c                   |   9 +-
 arch/um/drivers/virtio_uml.c                  |  18 +--
 arch/x86/kernel/msr.c                         |  11 +-
 arch/x86/kvm/mmu/mmu.c                        |  28 ++--
 arch/x86/kvm/svm/avic.c                       |  14 +-
 arch/x86/kvm/vmx/vmx.c                        |  24 ++--
 arch/x86/platform/uv/uv_nmi.c                 |  24 ++--
 block/disk-events.c                           |   6 +-
 drivers/acpi/button.c                         |  19 ++-
 drivers/acpi/ec.c                             |  14 +-
 drivers/acpi/sysfs.c                          | 114 ++++++++--------
 drivers/block/loop.c                          |  12 +-
 drivers/block/null_blk/main.c                 |  12 +-
 drivers/block/rnbd/rnbd-srv.c                 |   6 +-
 drivers/block/ublk_drv.c                      |  12 +-
 drivers/char/ipmi/ipmi_msghandler.c           |  12 +-
 drivers/char/ipmi/ipmi_watchdog.c             |  50 +++----
 drivers/crypto/hisilicon/hpre/hpre_main.c     |  16 +--
 drivers/crypto/hisilicon/sec2/sec_main.c      |  23 +---
 drivers/crypto/hisilicon/zip/zip_crypto.c     |   5 +-
 drivers/crypto/hisilicon/zip/zip_main.c       |  21 +--
 drivers/dma/dmatest.c                         |  34 ++---
 drivers/edac/i10nm_base.c                     |   6 +-
 drivers/firmware/efi/efi-pstore.c             |   6 +-
 drivers/firmware/qcom/qcom_scm.c              |  18 +--
 drivers/firmware/qemu_fw_cfg.c                |  40 +++---
 drivers/gpu/drm/drm_panic.c                   |  13 +-
 drivers/gpu/drm/i915/i915_mitigations.c       |  31 ++---
 drivers/gpu/drm/imagination/pvr_fw_trace.c    |   6 +-
 drivers/hid/hid-cougar.c                      |   6 +-
 drivers/hid/hid-steam.c                       |   6 +-
 drivers/infiniband/hw/hfi1/driver.c           |  12 +-
 drivers/infiniband/ulp/iser/iscsi_iser.c      |   6 +-
 drivers/infiniband/ulp/isert/ib_isert.c       |   6 +-
 drivers/infiniband/ulp/srp/ib_srp.c           |  12 +-
 drivers/infiniband/ulp/srpt/ib_srpt.c         |   5 +-
 drivers/input/misc/ati_remote2.c              |  23 ++--
 drivers/input/mouse/psmouse-base.c            |  15 ++-
 drivers/md/md.c                               |   5 +-
 drivers/media/pci/tw686x/tw686x-core.c        |   6 +-
 drivers/media/usb/uvc/uvc_driver.c            |  14 +-
 drivers/misc/lis3lv02d/lis3lv02d.c            |   5 +-
 drivers/net/wireless/ath/wil6210/main.c       |  10 +-
 drivers/nvme/host/multipath.c                 |  17 +--
 drivers/nvme/host/pci.c                       |  18 +--
 drivers/nvme/target/rdma.c                    |   5 +-
 drivers/nvme/target/tcp.c                     |   5 +-
 drivers/pci/pcie/aspm.c                       |  17 ++-
 drivers/platform/x86/acerhdf.c                |   5 +-
 drivers/power/supply/bq27xxx_battery.c        |   6 +-
 drivers/power/supply/test_power.c             | 122 +++++++++---------
 drivers/scsi/fcoe/fcoe_transport.c            |  22 ++--
 drivers/scsi/sg.c                             |   6 +-
 drivers/target/target_core_user.c             |  25 ++--
 .../processor_thermal_soc_slider.c            |  24 ++--
 drivers/thermal/intel/intel_powerclamp.c      |  34 ++---
 drivers/tty/hvc/hvc_iucv.c                    |  24 ++--
 drivers/tty/sysrq.c                           |   6 +-
 drivers/ufs/core/ufs-fault-injection.c        |  12 +-
 drivers/ufs/core/ufs-mcq.c                    |  18 +--
 drivers/ufs/core/ufs-txeq.c                   |   5 +-
 drivers/ufs/core/ufshcd.c                     |  12 +-
 drivers/usb/core/quirks.c                     |   6 +-
 drivers/usb/gadget/legacy/serial.c            |   5 +-
 drivers/usb/storage/usb.c                     |  25 ++--
 drivers/vhost/scsi.c                          |  12 +-
 drivers/virt/nitro_enclaves/ne_misc_dev.c     |   6 +-
 drivers/virtio/virtio_mmio.c                  |  27 ++--
 fs/ceph/super.c                               |  10 +-
 fs/fuse/dir.c                                 |   5 +-
 fs/nfs/namespace.c                            |  12 +-
 fs/nfs/super.c                                |   6 +-
 fs/ocfs2/dlmfs/dlmfs.c                        |   5 +-
 fs/overlayfs/copy_up.c                        |   5 +-
 fs/ubifs/super.c                              |   6 +-
 kernel/locking/locktorture.c                  |  12 +-
 kernel/panic.c                                |  11 +-
 kernel/params.c                               | 122 +++++++++---------
 kernel/power/hibernate.c                      |   6 +-
 kernel/rcu/tree.c                             |  24 ++--
 kernel/sched/ext.c                            |  11 +-
 kernel/workqueue.c                            |  18 ++-
 lib/dynamic_debug.c                           |  16 ++-
 lib/test_dynamic_debug.c                      |  12 +-
 mm/damon/lru_sort.c                           |  33 +++--
 mm/damon/reclaim.c                            |  33 +++--
 mm/damon/stat.c                               |  16 +--
 mm/memory_hotplug.c                           |  30 +++--
 mm/page_reporting.c                           |  11 +-
 mm/shuffle.c                                  |   6 +-
 mm/zswap.c                                    |  14 +-
 net/batman-adv/bat_algo.c                     |   6 +-
 net/ceph/ceph_common.c                        |  10 +-
 net/ipv4/tcp_dctcp.c                          |   6 +-
 net/sunrpc/auth.c                             |  12 +-
 net/sunrpc/svc.c                              |   5 +-
 net/sunrpc/xprtsock.c                         |  18 +--
 samples/damon/mtier.c                         |   6 +-
 samples/damon/prcl.c                          |   6 +-
 samples/damon/wsse.c                          |   6 +-
 security/apparmor/lib.c                       |  27 ++--
 security/apparmor/lsm.c                       |  75 +++++------
 sound/hda/controllers/intel.c                 |   5 +-
 sound/usb/card.c                              |   7 +-
 110 files changed, 854 insertions(+), 1066 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 01/11] params: bound array element output to the caller's page buffer
  2026-05-21 13:33 [PATCH 00/11] Convert moduleparams to seq_buf Kees Cook
@ 2026-05-21 13:33 ` Kees Cook
  2026-05-21 16:46   ` David Laight
  2026-06-02 11:26   ` Andy Shevchenko
  2026-05-21 13:33 ` [PATCH 02/11] panic: Replace panic_print_get() with generic helper Kees Cook
                   ` (10 subsequent siblings)
  11 siblings, 2 replies; 33+ messages in thread
From: Kees Cook @ 2026-05-21 13:33 UTC (permalink / raw)
  To: Luis Chamberlain
  Cc: Kees Cook, Pengpeng Hou, stable, 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, x86,
	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, kvm, dmaengine,
	linux-modules, kasan-dev, linux-mm, apparmor,
	linux-security-module, linux-um, linux-acpi, openipmi-developer,
	qemu-devel, intel-gfx, dri-devel, linux-rdma, linux-media,
	linux-pci, linux-scsi, linux-pm, linuxppc-dev, linux-serial,
	linux-usb, usb-storage, virtualization, linux-kernel, linux-arch,
	netdev, linux-fsdevel, linux-hardening

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

param_array_get() appends each element's string representation into the
shared sysfs page buffer by passing buffer + off to the element getter.

That works for getters that only write a small bounded string, but
param_get_charp() and similar helpers format against PAGE_SIZE from the
pointer they receive. Once off is non-zero, an element getter can
therefore write past the end of the original sysfs page buffer.

Collect each element into a temporary PAGE_SIZE buffer first and then
copy only the remaining space into the caller's page buffer.

Cc: stable@vger.kernel.org
Reviewed-by: Petr Pavlu <petr.pavlu@suse.com>
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: Kees Cook <kees@kernel.org>
---
 kernel/params.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/kernel/params.c b/kernel/params.c
index 74d620bc2521..752721922a15 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -475,22 +475,36 @@ static int param_array_set(const char *val, const struct kernel_param *kp)
 static int param_array_get(char *buffer, const struct kernel_param *kp)
 {
 	int i, off, ret;
+	char *elem_buf;
 	const struct kparam_array *arr = kp->arr;
 	struct kernel_param p = *kp;
 
+	elem_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!elem_buf)
+		return -ENOMEM;
+
 	for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) {
-		/* Replace \n with comma */
-		if (i)
-			buffer[off - 1] = ',';
 		p.arg = arr->elem + arr->elemsize * i;
 		check_kparam_locked(p.mod);
-		ret = arr->ops->get(buffer + off, &p);
+		ret = arr->ops->get(elem_buf, &p);
 		if (ret < 0)
-			return ret;
+			goto out;
+		ret = min(ret, (int)(PAGE_SIZE - 1 - off));
+		if (!ret)
+			break;
+		/* Replace the previous element's trailing newline with a comma. */
+		if (i)
+			buffer[off - 1] = ',';
+		memcpy(buffer + off, elem_buf, ret);
 		off += ret;
+		if (off == PAGE_SIZE - 1)
+			break;
 	}
 	buffer[off] = '\0';
-	return off;
+	ret = off;
+out:
+	kfree(elem_buf);
+	return ret;
 }
 
 static void param_array_free(void *arg)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 02/11] panic: Replace panic_print_get() with generic helper
  2026-05-21 13:33 [PATCH 00/11] Convert moduleparams to seq_buf Kees Cook
  2026-05-21 13:33 ` [PATCH 01/11] params: bound array element output to the caller's page buffer Kees Cook
@ 2026-05-21 13:33 ` Kees Cook
  2026-05-21 13:33 ` [PATCH 03/11] moduleparam: Add DEFINE_KERNEL_PARAM_OPS macro family Kees Cook
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 33+ messages in thread
From: Kees Cook @ 2026-05-21 13:33 UTC (permalink / raw)
  To: Luis Chamberlain
  Cc: 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, x86,
	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, kvm, dmaengine,
	linux-modules, kasan-dev, linux-mm, apparmor,
	linux-security-module, linux-um, linux-acpi, openipmi-developer,
	qemu-devel, intel-gfx, dri-devel, linux-rdma, linux-media,
	linux-pci, linux-scsi, linux-pm, linuxppc-dev, linux-serial,
	linux-usb, usb-storage, virtualization, linux-kernel, linux-arch,
	netdev, linux-fsdevel, linux-hardening

Since panic_print_get() just calls the ulong helper directly, there is
no need for it to exist as a wrapper.

Signed-off-by: Kees Cook <kees@kernel.org>
---
 kernel/panic.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/kernel/panic.c b/kernel/panic.c
index 20feada5319d..42e5ebde4585 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -1214,14 +1214,9 @@ static int panic_print_set(const char *val, const struct kernel_param *kp)
 	return  param_set_ulong(val, kp);
 }
 
-static int panic_print_get(char *val, const struct kernel_param *kp)
-{
-	return  param_get_ulong(val, kp);
-}
-
 static const struct kernel_param_ops panic_print_ops = {
 	.set	= panic_print_set,
-	.get	= panic_print_get,
+	.get	= param_get_ulong,
 };
 __core_param_cb(panic_print, &panic_print_ops, &panic_print, 0644);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 03/11] moduleparam: Add DEFINE_KERNEL_PARAM_OPS macro family
  2026-05-21 13:33 [PATCH 00/11] Convert moduleparams to seq_buf Kees Cook
  2026-05-21 13:33 ` [PATCH 01/11] params: bound array element output to the caller's page buffer Kees Cook
  2026-05-21 13:33 ` [PATCH 02/11] panic: Replace panic_print_get() with generic helper Kees Cook
@ 2026-05-21 13:33 ` Kees Cook
  2026-05-25 13:27   ` Petr Pavlu
  2026-05-21 13:33 ` [PATCH 04/11] treewide: Convert struct kernel_param_ops initializers to DEFINE_KERNEL_PARAM_OPS Kees Cook
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 33+ messages in thread
From: Kees Cook @ 2026-05-21 13:33 UTC (permalink / raw)
  To: Luis Chamberlain
  Cc: 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, x86,
	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, kvm, dmaengine,
	linux-modules, kasan-dev, linux-mm, apparmor,
	linux-security-module, linux-um, linux-acpi, openipmi-developer,
	qemu-devel, intel-gfx, dri-devel, linux-rdma, linux-media,
	linux-pci, linux-scsi, linux-pm, linuxppc-dev, linux-serial,
	linux-usb, usb-storage, virtualization, linux-kernel, linux-arch,
	netdev, linux-fsdevel, linux-hardening

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 <kees@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


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 04/11] treewide: Convert struct kernel_param_ops initializers to DEFINE_KERNEL_PARAM_OPS
  2026-05-21 13:33 [PATCH 00/11] Convert moduleparams to seq_buf Kees Cook
                   ` (2 preceding siblings ...)
  2026-05-21 13:33 ` [PATCH 03/11] moduleparam: Add DEFINE_KERNEL_PARAM_OPS macro family Kees Cook
@ 2026-05-21 13:33 ` Kees Cook
  2026-05-21 13:59   ` Sean Christopherson
                     ` (3 more replies)
  2026-05-21 13:33 ` [PATCH 05/11] moduleparam: Rename .get field to .get_str Kees Cook
                   ` (7 subsequent siblings)
  11 siblings, 4 replies; 33+ messages in thread
From: Kees Cook @ 2026-05-21 13:33 UTC (permalink / raw)
  To: Luis Chamberlain
  Cc: 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, x86,
	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, kvm, dmaengine,
	linux-modules, kasan-dev, linux-mm, apparmor,
	linux-security-module, linux-um, linux-acpi, openipmi-developer,
	qemu-devel, intel-gfx, dri-devel, linux-rdma, linux-media,
	linux-pci, linux-scsi, linux-pm, linuxppc-dev, linux-serial,
	linux-usb, usb-storage, virtualization, linux-kernel, linux-arch,
	netdev, linux-fsdevel, linux-hardening

Using Coccinelle, rewrite every struct kernel_param_ops initializer that
sets .get into a DEFINE_KERNEL_PARAM_OPS-family macro invocation,
for example:

@@
declarer name DEFINE_KERNEL_PARAM_OPS;
identifier OPS;
expression SET, GET;
@@
- const struct kernel_param_ops OPS = {
-       .set = SET,
-       .get = GET,
- };
+ DEFINE_KERNEL_PARAM_OPS(OPS, SET, GET);

Using the macro for initialization means future changes can manipulate
the struct layout and callback prototypes without having to change every
initializer.

Signed-off-by: Kees Cook <kees@kernel.org>
---
 mm/kfence/core.c                              |  7 +-
 arch/powerpc/kvm/book3s_hv.c                  |  5 +-
 arch/s390/kernel/perf_cpum_sf.c               |  6 +-
 arch/um/drivers/vfio_kern.c                   |  6 +-
 arch/um/drivers/virtio_uml.c                  |  6 +-
 arch/x86/kernel/msr.c                         |  6 +-
 arch/x86/kvm/mmu/mmu.c                        | 12 +--
 arch/x86/kvm/svm/avic.c                       |  6 +-
 arch/x86/kvm/vmx/vmx.c                        |  6 +-
 arch/x86/platform/uv/uv_nmi.c                 | 12 +--
 block/disk-events.c                           |  6 +-
 drivers/acpi/sysfs.c                          | 25 +++----
 drivers/block/loop.c                          | 12 +--
 drivers/block/null_blk/main.c                 | 12 +--
 drivers/block/rnbd/rnbd-srv.c                 |  6 +-
 drivers/block/ublk_drv.c                      |  7 +-
 drivers/char/ipmi/ipmi_msghandler.c           |  6 +-
 drivers/char/ipmi/ipmi_watchdog.c             | 17 ++---
 drivers/crypto/hisilicon/hpre/hpre_main.c     | 16 +---
 drivers/crypto/hisilicon/sec2/sec_main.c      | 23 ++----
 drivers/crypto/hisilicon/zip/zip_crypto.c     |  5 +-
 drivers/crypto/hisilicon/zip/zip_main.c       | 21 ++----
 drivers/dma/dmatest.c                         | 20 ++---
 drivers/edac/i10nm_base.c                     |  6 +-
 drivers/firmware/efi/efi-pstore.c             |  6 +-
 drivers/firmware/qcom/qcom_scm.c              |  6 +-
 drivers/firmware/qemu_fw_cfg.c                |  6 +-
 drivers/gpu/drm/drm_panic.c                   |  6 +-
 drivers/gpu/drm/i915/i915_mitigations.c       |  5 +-
 drivers/gpu/drm/imagination/pvr_fw_trace.c    |  6 +-
 drivers/hid/hid-cougar.c                      |  6 +-
 drivers/hid/hid-steam.c                       |  6 +-
 drivers/infiniband/hw/hfi1/driver.c           |  5 +-
 drivers/infiniband/ulp/iser/iscsi_iser.c      |  6 +-
 drivers/infiniband/ulp/isert/ib_isert.c       |  6 +-
 drivers/infiniband/ulp/srp/ib_srp.c           |  5 +-
 drivers/input/misc/ati_remote2.c              | 13 ++--
 drivers/input/mouse/psmouse-base.c            |  6 +-
 drivers/media/usb/uvc/uvc_driver.c            |  6 +-
 drivers/misc/lis3lv02d/lis3lv02d.c            |  5 +-
 drivers/net/wireless/ath/wil6210/main.c       | 10 +--
 drivers/nvme/host/multipath.c                 | 12 +--
 drivers/nvme/host/pci.c                       | 18 ++---
 drivers/nvme/target/rdma.c                    |  5 +-
 drivers/nvme/target/tcp.c                     |  5 +-
 drivers/platform/x86/acerhdf.c                |  5 +-
 drivers/power/supply/bq27xxx_battery.c        |  6 +-
 drivers/power/supply/test_power.c             | 75 ++++++++-----------
 drivers/scsi/sg.c                             |  6 +-
 drivers/target/target_core_user.c             | 13 ++--
 .../processor_thermal_soc_slider.c            | 12 +--
 drivers/thermal/intel/intel_powerclamp.c      | 20 +----
 drivers/tty/hvc/hvc_iucv.c                    |  6 +-
 drivers/tty/sysrq.c                           |  6 +-
 drivers/ufs/core/ufs-fault-injection.c        |  5 +-
 drivers/ufs/core/ufs-mcq.c                    | 18 ++---
 drivers/ufs/core/ufs-txeq.c                   |  5 +-
 drivers/ufs/core/ufshcd.c                     | 12 +--
 drivers/usb/core/quirks.c                     |  6 +-
 drivers/usb/gadget/legacy/serial.c            |  5 +-
 drivers/usb/storage/usb.c                     |  5 +-
 drivers/vhost/scsi.c                          |  7 +-
 drivers/virt/nitro_enclaves/ne_misc_dev.c     |  6 +-
 drivers/virtio/virtio_mmio.c                  |  6 +-
 fs/ceph/super.c                               | 10 +--
 fs/fuse/dir.c                                 |  5 +-
 fs/nfs/namespace.c                            |  6 +-
 fs/nfs/super.c                                |  6 +-
 fs/ubifs/super.c                              |  6 +-
 kernel/locking/locktorture.c                  |  6 +-
 kernel/panic.c                                |  6 +-
 kernel/params.c                               | 44 +++--------
 kernel/power/hibernate.c                      |  6 +-
 kernel/rcu/tree.c                             | 18 ++---
 kernel/sched/ext.c                            | 11 +--
 kernel/workqueue.c                            | 12 +--
 lib/dynamic_debug.c                           |  6 +-
 lib/test_dynamic_debug.c                      |  6 +-
 mm/damon/lru_sort.c                           | 19 ++---
 mm/damon/reclaim.c                            | 19 ++---
 mm/damon/stat.c                               |  6 +-
 mm/memory_hotplug.c                           | 12 +--
 mm/page_reporting.c                           | 11 +--
 mm/shuffle.c                                  |  6 +-
 mm/zswap.c                                    | 14 ++--
 net/batman-adv/bat_algo.c                     |  6 +-
 net/ceph/ceph_common.c                        |  5 +-
 net/ipv4/tcp_dctcp.c                          |  6 +-
 net/sunrpc/auth.c                             |  6 +-
 net/sunrpc/xprtsock.c                         | 18 ++---
 samples/damon/mtier.c                         |  6 +-
 samples/damon/prcl.c                          |  6 +-
 samples/damon/wsse.c                          |  6 +-
 security/apparmor/lsm.c                       | 34 +++------
 sound/hda/controllers/intel.c                 |  5 +-
 sound/usb/card.c                              |  7 +-
 96 files changed, 307 insertions(+), 660 deletions(-)

diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 655dc5ce3240..e14102c01520 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -92,10 +92,9 @@ static int param_get_sample_interval(char *buffer, const struct kernel_param *kp
 	return param_get_ulong(buffer, kp);
 }
 
-static const struct kernel_param_ops sample_interval_param_ops = {
-	.set = param_set_sample_interval,
-	.get = param_get_sample_interval,
-};
+static DEFINE_KERNEL_PARAM_OPS(sample_interval_param_ops,
+			       param_set_sample_interval,
+			       param_get_sample_interval);
 module_param_cb(sample_interval, &sample_interval_param_ops, &kfence_sample_interval, 0600);
 
 /* Pool usage% threshold when currently covered allocations are skipped. */
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 61dbeea317f3..0c15f0426671 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -114,10 +114,7 @@ module_param(one_vm_per_core, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(one_vm_per_core, "Only run vCPUs from the same VM on a core (requires POWER8 or older)");
 
 #ifdef CONFIG_KVM_XICS
-static const struct kernel_param_ops module_param_ops = {
-	.set = param_set_int,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(module_param_ops, param_set_int, param_get_int);
 
 module_param_cb(kvm_irq_bypass, &module_param_ops, &kvm_irq_bypass, 0644);
 MODULE_PARM_DESC(kvm_irq_bypass, "Bypass passthrough interrupt optimization");
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c
index 7bfeb5208177..76119542562b 100644
--- a/arch/s390/kernel/perf_cpum_sf.c
+++ b/arch/s390/kernel/perf_cpum_sf.c
@@ -2029,10 +2029,8 @@ static int param_set_sfb_size(const char *val, const struct kernel_param *kp)
 }
 
 #define param_check_sfb_size(name, p) __param_check(name, p, void)
-static const struct kernel_param_ops param_ops_sfb_size = {
-	.set = param_set_sfb_size,
-	.get = param_get_sfb_size,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_sfb_size, param_set_sfb_size,
+			       param_get_sfb_size);
 
 enum {
 	RS_INIT_FAILURE_BSDES	= 2,	/* Bad basic sampling size */
diff --git a/arch/um/drivers/vfio_kern.c b/arch/um/drivers/vfio_kern.c
index e6dab473cde4..fb7988dc5482 100644
--- a/arch/um/drivers/vfio_kern.c
+++ b/arch/um/drivers/vfio_kern.c
@@ -628,10 +628,8 @@ static int uml_vfio_cmdline_get(char *buffer, const struct kernel_param *kp)
 	return 0;
 }
 
-static const struct kernel_param_ops uml_vfio_cmdline_param_ops = {
-	.set = uml_vfio_cmdline_set,
-	.get = uml_vfio_cmdline_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(uml_vfio_cmdline_param_ops, uml_vfio_cmdline_set,
+			       uml_vfio_cmdline_get);
 
 device_param_cb(device, &uml_vfio_cmdline_param_ops, NULL, 0400);
 __uml_help(uml_vfio_cmdline_param_ops,
diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
index 7425a8548141..f9ae745f4586 100644
--- a/arch/um/drivers/virtio_uml.c
+++ b/arch/um/drivers/virtio_uml.c
@@ -1398,10 +1398,8 @@ static int vu_cmdline_get(char *buffer, const struct kernel_param *kp)
 	return strlen(buffer) + 1;
 }
 
-static const struct kernel_param_ops vu_cmdline_param_ops = {
-	.set = vu_cmdline_set,
-	.get = vu_cmdline_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(vu_cmdline_param_ops, vu_cmdline_set,
+			       vu_cmdline_get);
 
 device_param_cb(device, &vu_cmdline_param_ops, NULL, S_IRUSR);
 __uml_help(vu_cmdline_param_ops,
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 4469c784eaa0..5f4e1814dc4d 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -322,10 +322,8 @@ static int get_allow_writes(char *buf, const struct kernel_param *kp)
 	return sprintf(buf, "%s\n", res);
 }
 
-static const struct kernel_param_ops allow_writes_ops = {
-	.set = set_allow_writes,
-	.get = get_allow_writes
-};
+static DEFINE_KERNEL_PARAM_OPS(allow_writes_ops, set_allow_writes,
+			       get_allow_writes);
 
 module_param_cb(allow_writes, &allow_writes_ops, NULL, 0600);
 
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 24fbc9ea502a..996818ee9b09 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -74,15 +74,11 @@ static int get_nx_huge_pages(char *buffer, const struct kernel_param *kp);
 static int set_nx_huge_pages(const char *val, const struct kernel_param *kp);
 static int set_nx_huge_pages_recovery_param(const char *val, const struct kernel_param *kp);
 
-static const struct kernel_param_ops nx_huge_pages_ops = {
-	.set = set_nx_huge_pages,
-	.get = get_nx_huge_pages,
-};
+static DEFINE_KERNEL_PARAM_OPS(nx_huge_pages_ops, set_nx_huge_pages,
+			       get_nx_huge_pages);
 
-static const struct kernel_param_ops nx_huge_pages_recovery_param_ops = {
-	.set = set_nx_huge_pages_recovery_param,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(nx_huge_pages_recovery_param_ops,
+			       set_nx_huge_pages_recovery_param, param_get_uint);
 
 module_param_cb(nx_huge_pages, &nx_huge_pages_ops, &nx_huge_pages, 0644);
 __MODULE_PARM_TYPE(nx_huge_pages, "bool");
diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
index adf211860949..7907f9addff9 100644
--- a/arch/x86/kvm/svm/avic.c
+++ b/arch/x86/kvm/svm/avic.c
@@ -87,11 +87,7 @@ static int avic_param_get(char *buffer, const struct kernel_param *kp)
 	return param_get_bool(buffer, kp);
 }
 
-static const struct kernel_param_ops avic_ops = {
-	.flags = KERNEL_PARAM_OPS_FL_NOARG,
-	.set = avic_param_set,
-	.get = avic_param_get,
-};
+static DEFINE_KERNEL_PARAM_OPS_NOARG(avic_ops, avic_param_set, avic_param_get);
 
 /*
  * Enable / disable AVIC.  In "auto" mode (default behavior), AVIC is enabled
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index a29896a9ef14..07f4c7209ac0 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -465,10 +465,8 @@ static int vmentry_l1d_flush_get(char *s, const struct kernel_param *kp)
 }
 #endif
 
-static const struct kernel_param_ops vmentry_l1d_flush_ops = {
-	.set = vmentry_l1d_flush_set,
-	.get = vmentry_l1d_flush_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(vmentry_l1d_flush_ops, vmentry_l1d_flush_set,
+			       vmentry_l1d_flush_get);
 module_param_cb(vmentry_l1d_flush, &vmentry_l1d_flush_ops, NULL, 0644);
 
 static __always_inline void vmx_disable_fb_clear(struct vcpu_vmx *vmx)
diff --git a/arch/x86/platform/uv/uv_nmi.c b/arch/x86/platform/uv/uv_nmi.c
index 5c50e550ab63..a7ac80b5f8d9 100644
--- a/arch/x86/platform/uv/uv_nmi.c
+++ b/arch/x86/platform/uv/uv_nmi.c
@@ -123,10 +123,8 @@ static int param_set_local64(const char *val, const struct kernel_param *kp)
 	return 0;
 }
 
-static const struct kernel_param_ops param_ops_local64 = {
-	.get = param_get_local64,
-	.set = param_set_local64,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_local64, param_set_local64,
+			       param_get_local64);
 #define param_check_local64(name, p) __param_check(name, p, local64_t)
 
 static local64_t uv_nmi_count;
@@ -232,10 +230,8 @@ static int param_set_action(const char *val, const struct kernel_param *kp)
 	return -EINVAL;
 }
 
-static const struct kernel_param_ops param_ops_action = {
-	.get = param_get_action,
-	.set = param_set_action,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_action, param_set_action,
+			       param_get_action);
 #define param_check_action(name, p) __param_check(name, p, enum action_t)
 
 module_param_named(action, uv_nmi_action, action, 0644);
diff --git a/block/disk-events.c b/block/disk-events.c
index 074731ecc3d2..f2d4b48294c6 100644
--- a/block/disk-events.c
+++ b/block/disk-events.c
@@ -416,10 +416,8 @@ static int disk_events_set_dfl_poll_msecs(const char *val,
 	return 0;
 }
 
-static const struct kernel_param_ops disk_events_dfl_poll_msecs_param_ops = {
-	.set	= disk_events_set_dfl_poll_msecs,
-	.get	= param_get_ulong,
-};
+static DEFINE_KERNEL_PARAM_OPS(disk_events_dfl_poll_msecs_param_ops,
+			       disk_events_set_dfl_poll_msecs, param_get_ulong);
 
 #undef MODULE_PARAM_PREFIX
 #define MODULE_PARAM_PREFIX	"block."
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index a625de3c3c8b..3d32a5280432 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -138,15 +138,11 @@ static int param_get_debug_level(char *buffer, const struct kernel_param *kp)
 	return result;
 }
 
-static const struct kernel_param_ops param_ops_debug_layer = {
-	.set = param_set_uint,
-	.get = param_get_debug_layer,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_debug_layer, param_set_uint,
+			       param_get_debug_layer);
 
-static const struct kernel_param_ops param_ops_debug_level = {
-	.set = param_set_uint,
-	.get = param_get_debug_level,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_debug_level, param_set_uint,
+			       param_get_debug_level);
 
 module_param_cb(debug_layer, &param_ops_debug_layer, &acpi_dbg_layer, 0644);
 module_param_cb(debug_level, &param_ops_debug_level, &acpi_dbg_level, 0644);
@@ -201,15 +197,12 @@ static int param_get_trace_method_name(char *buffer, const struct kernel_param *
 	return sysfs_emit(buffer, "%s\n", acpi_gbl_trace_method_name);
 }
 
-static const struct kernel_param_ops param_ops_trace_method = {
-	.set = param_set_trace_method_name,
-	.get = param_get_trace_method_name,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_trace_method,
+			       param_set_trace_method_name,
+			       param_get_trace_method_name);
 
-static const struct kernel_param_ops param_ops_trace_attrib = {
-	.set = param_set_uint,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_trace_attrib, param_set_uint,
+			       param_get_uint);
 
 module_param_cb(trace_method_name, &param_ops_trace_method, &trace_method_name, 0644);
 module_param_cb(trace_debug_layer, &param_ops_trace_attrib, &acpi_gbl_trace_dbg_layer, 0644);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 0000913f7efc..147ad561e584 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1806,10 +1806,8 @@ static int max_loop_param_set_int(const char *val,
 	return 0;
 }
 
-static const struct kernel_param_ops max_loop_param_ops = {
-	.set = max_loop_param_set_int,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(max_loop_param_ops, max_loop_param_set_int,
+			       param_get_int);
 
 module_param_cb(max_loop, &max_loop_param_ops, &max_loop, 0444);
 MODULE_PARM_DESC(max_loop, "Maximum number of loop devices");
@@ -1836,10 +1834,8 @@ static int loop_set_hw_queue_depth(const char *s, const struct kernel_param *p)
 	return 0;
 }
 
-static const struct kernel_param_ops loop_hw_qdepth_param_ops = {
-	.set	= loop_set_hw_queue_depth,
-	.get	= param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(loop_hw_qdepth_param_ops,
+			       loop_set_hw_queue_depth, param_get_int);
 
 device_param_cb(hw_queue_depth, &loop_hw_qdepth_param_ops, &hw_queue_depth, 0444);
 MODULE_PARM_DESC(hw_queue_depth, "Queue depth for each hardware queue. Default: " __stringify(LOOP_DEFAULT_HW_Q_DEPTH));
diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c
index f8c0fd57e041..332ad6ac838a 100644
--- a/drivers/block/null_blk/main.c
+++ b/drivers/block/null_blk/main.c
@@ -149,10 +149,8 @@ static int null_set_queue_mode(const char *str, const struct kernel_param *kp)
 	return null_param_store_val(str, &g_queue_mode, NULL_Q_BIO, NULL_Q_MQ);
 }
 
-static const struct kernel_param_ops null_queue_mode_param_ops = {
-	.set	= null_set_queue_mode,
-	.get	= param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(null_queue_mode_param_ops, null_set_queue_mode,
+			       param_get_int);
 
 device_param_cb(queue_mode, &null_queue_mode_param_ops, &g_queue_mode, 0444);
 MODULE_PARM_DESC(queue_mode, "Block interface to use (0=bio,1=rq,2=multiqueue)");
@@ -193,10 +191,8 @@ static int null_set_irqmode(const char *str, const struct kernel_param *kp)
 					NULL_IRQ_TIMER);
 }
 
-static const struct kernel_param_ops null_irqmode_param_ops = {
-	.set	= null_set_irqmode,
-	.get	= param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(null_irqmode_param_ops, null_set_irqmode,
+			       param_get_int);
 
 device_param_cb(irqmode, &null_irqmode_param_ops, &g_irqmode, 0444);
 MODULE_PARM_DESC(irqmode, "IRQ completion handler. 0-none, 1-softirq, 2-timer");
diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c
index 10e8c438bb43..81961f7c883a 100644
--- a/drivers/block/rnbd/rnbd-srv.c
+++ b/drivers/block/rnbd/rnbd-srv.c
@@ -49,10 +49,8 @@ static struct kparam_string dev_search_path_kparam_str = {
 	.string	= dev_search_path
 };
 
-static const struct kernel_param_ops dev_search_path_ops = {
-	.set	= dev_search_path_set,
-	.get	= param_get_string,
-};
+static DEFINE_KERNEL_PARAM_OPS(dev_search_path_ops, dev_search_path_set,
+			       param_get_string);
 
 module_param_cb(dev_search_path, &dev_search_path_ops,
 		&dev_search_path_kparam_str, 0444);
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 8e5f3738c203..f7bf7ea2d088 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -5874,10 +5874,9 @@ static int ublk_get_max_unprivileged_ublks(char *buf,
 	return sysfs_emit(buf, "%u\n", unprivileged_ublks_max);
 }
 
-static const struct kernel_param_ops ublk_max_unprivileged_ublks_ops = {
-	.set = ublk_set_max_unprivileged_ublks,
-	.get = ublk_get_max_unprivileged_ublks,
-};
+static DEFINE_KERNEL_PARAM_OPS(ublk_max_unprivileged_ublks_ops,
+			       ublk_set_max_unprivileged_ublks,
+			       ublk_get_max_unprivileged_ublks);
 
 module_param_cb(ublks_max, &ublk_max_unprivileged_ublks_ops,
 		&unprivileged_ublks_max, 0644);
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 869ac87a4b6a..b5fed11707e8 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -102,10 +102,8 @@ static int panic_op_read_handler(char *buffer, const struct kernel_param *kp)
 	return sprintf(buffer, "%s\n", event_str);
 }
 
-static const struct kernel_param_ops panic_op_ops = {
-	.set = panic_op_write_handler,
-	.get = panic_op_read_handler
-};
+static DEFINE_KERNEL_PARAM_OPS(panic_op_ops, panic_op_write_handler,
+			       panic_op_read_handler);
 module_param_cb(panic_op, &panic_op_ops, NULL, 0600);
 MODULE_PARM_DESC(panic_op, "Sets if the IPMI driver will attempt to store panic information in the event log in the event of a panic.  Set to 'none' for no, 'event' for a single event, or 'string' for a generic event and the panic string in IPMI OEM events.");
 
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index a013ddbf1466..91a99417d204 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -193,10 +193,8 @@ static int set_param_timeout(const char *val, const struct kernel_param *kp)
 	return rv;
 }
 
-static const struct kernel_param_ops param_ops_timeout = {
-	.set = set_param_timeout,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_timeout, set_param_timeout,
+			       param_get_int);
 #define param_check_timeout param_check_int
 
 typedef int (*action_fn)(const char *intval, char *outval);
@@ -259,17 +257,12 @@ static int set_param_wdog_ifnum(const char *val, const struct kernel_param *kp)
 	return 0;
 }
 
-static const struct kernel_param_ops param_ops_wdog_ifnum = {
-	.set = set_param_wdog_ifnum,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_wdog_ifnum, set_param_wdog_ifnum,
+			       param_get_int);
 
 #define param_check_wdog_ifnum param_check_int
 
-static const struct kernel_param_ops param_ops_str = {
-	.set = set_param_str,
-	.get = get_param_str,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_str, set_param_str, get_param_str);
 
 module_param(ifnum_to_use, wdog_ifnum, 0644);
 MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog "
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
index 357ab5e5887e..1104184c2f63 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -420,10 +420,8 @@ static int hpre_cluster_regs_show(struct seq_file *s, void *unused)
 
 DEFINE_SHOW_ATTRIBUTE(hpre_cluster_regs);
 
-static const struct kernel_param_ops hpre_uacce_mode_ops = {
-	.set = uacce_mode_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(hpre_uacce_mode_ops, uacce_mode_set,
+			       param_get_int);
 
 /*
  * uacce_mode = 0 means hpre only register to crypto,
@@ -441,19 +439,13 @@ static int pf_q_num_set(const char *val, const struct kernel_param *kp)
 	return hisi_qm_q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_HPRE_PF);
 }
 
-static const struct kernel_param_ops hpre_pf_q_num_ops = {
-	.set = pf_q_num_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(hpre_pf_q_num_ops, pf_q_num_set, param_get_int);
 
 static u32 pf_q_num = HPRE_PF_DEF_Q_NUM;
 module_param_cb(pf_q_num, &hpre_pf_q_num_ops, &pf_q_num, 0444);
 MODULE_PARM_DESC(pf_q_num, "Number of queues in PF of CS(2-1024)");
 
-static const struct kernel_param_ops vfs_num_ops = {
-	.set = vfs_num_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(vfs_num_ops, vfs_num_set, param_get_int);
 
 static u32 vfs_num;
 module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444);
diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
index 056bd8f4da5a..3d13f2faa3d0 100644
--- a/drivers/crypto/hisilicon/sec2/sec_main.c
+++ b/drivers/crypto/hisilicon/sec2/sec_main.c
@@ -362,10 +362,8 @@ static int sec_pf_q_num_set(const char *val, const struct kernel_param *kp)
 	return hisi_qm_q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_SEC_PF);
 }
 
-static const struct kernel_param_ops sec_pf_q_num_ops = {
-	.set = sec_pf_q_num_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(sec_pf_q_num_ops, sec_pf_q_num_set,
+			       param_get_int);
 
 static u32 pf_q_num = SEC_PF_DEF_Q_NUM;
 module_param_cb(pf_q_num, &sec_pf_q_num_ops, &pf_q_num, 0444);
@@ -391,18 +389,13 @@ static int sec_ctx_q_num_set(const char *val, const struct kernel_param *kp)
 	return param_set_int(val, kp);
 }
 
-static const struct kernel_param_ops sec_ctx_q_num_ops = {
-	.set = sec_ctx_q_num_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(sec_ctx_q_num_ops, sec_ctx_q_num_set,
+			       param_get_int);
 static u32 ctx_q_num = SEC_CTX_Q_NUM_DEF;
 module_param_cb(ctx_q_num, &sec_ctx_q_num_ops, &ctx_q_num, 0444);
 MODULE_PARM_DESC(ctx_q_num, "Queue num in ctx (2 default, 2, 4, ..., 32)");
 
-static const struct kernel_param_ops vfs_num_ops = {
-	.set = vfs_num_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(vfs_num_ops, vfs_num_set, param_get_int);
 
 static u32 vfs_num;
 module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444);
@@ -454,10 +447,8 @@ u64 sec_get_alg_bitmap(struct hisi_qm *qm, u32 high, u32 low)
 	return ((u64)cap_val_h << SEC_ALG_BITMAP_SHIFT) | (u64)cap_val_l;
 }
 
-static const struct kernel_param_ops sec_uacce_mode_ops = {
-	.set = uacce_mode_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(sec_uacce_mode_ops, uacce_mode_set,
+			       param_get_int);
 
 /*
  * uacce_mode = 0 means sec only register to crypto,
diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c
index 70adde049b53..8f8d57420fb4 100644
--- a/drivers/crypto/hisilicon/zip/zip_crypto.c
+++ b/drivers/crypto/hisilicon/zip/zip_crypto.c
@@ -108,10 +108,7 @@ static int sgl_sge_nr_set(const char *val, const struct kernel_param *kp)
 	return param_set_ushort(val, kp);
 }
 
-static const struct kernel_param_ops sgl_sge_nr_ops = {
-	.set = sgl_sge_nr_set,
-	.get = param_get_ushort,
-};
+static DEFINE_KERNEL_PARAM_OPS(sgl_sge_nr_ops, sgl_sge_nr_set, param_get_ushort);
 
 static u16 sgl_sge_nr = HZIP_SGL_SGE_NR;
 module_param_cb(sgl_sge_nr, &sgl_sge_nr_ops, &sgl_sge_nr, 0444);
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
index 44df9c859bd8..e07d0cf8eca8 100644
--- a/drivers/crypto/hisilicon/zip/zip_main.c
+++ b/drivers/crypto/hisilicon/zip/zip_main.c
@@ -394,10 +394,7 @@ static int perf_mode_set(const char *val, const struct kernel_param *kp)
 	return param_set_int(val, kp);
 }
 
-static const struct kernel_param_ops zip_com_perf_ops = {
-	.set = perf_mode_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(zip_com_perf_ops, perf_mode_set, param_get_int);
 
 /*
  * perf_mode = 0 means enable high compression rate mode,
@@ -408,10 +405,8 @@ static u32 perf_mode = HZIP_HIGH_COMP_RATE;
 module_param_cb(perf_mode, &zip_com_perf_ops, &perf_mode, 0444);
 MODULE_PARM_DESC(perf_mode, "ZIP high perf mode 0(default), 1(enable)");
 
-static const struct kernel_param_ops zip_uacce_mode_ops = {
-	.set = uacce_mode_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(zip_uacce_mode_ops, uacce_mode_set,
+			       param_get_int);
 
 /*
  * uacce_mode = 0 means zip only register to crypto,
@@ -429,19 +424,13 @@ static int pf_q_num_set(const char *val, const struct kernel_param *kp)
 	return hisi_qm_q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_ZIP_PF);
 }
 
-static const struct kernel_param_ops pf_q_num_ops = {
-	.set = pf_q_num_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(pf_q_num_ops, pf_q_num_set, param_get_int);
 
 static u32 pf_q_num = HZIP_PF_DEF_Q_NUM;
 module_param_cb(pf_q_num, &pf_q_num_ops, &pf_q_num, 0444);
 MODULE_PARM_DESC(pf_q_num, "Number of queues in PF(v1 2-4096, v2 2-1024)");
 
-static const struct kernel_param_ops vfs_num_ops = {
-	.set = vfs_num_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(vfs_num_ops, vfs_num_set, param_get_int);
 
 static u32 vfs_num;
 module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444);
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index df38681a1ff4..a7bddadcc52d 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -154,20 +154,15 @@ static struct dmatest_info {
 
 static int dmatest_run_set(const char *val, const struct kernel_param *kp);
 static int dmatest_run_get(char *val, const struct kernel_param *kp);
-static const struct kernel_param_ops run_ops = {
-	.set = dmatest_run_set,
-	.get = dmatest_run_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(run_ops, dmatest_run_set, dmatest_run_get);
 static bool dmatest_run;
 module_param_cb(run, &run_ops, &dmatest_run, 0644);
 MODULE_PARM_DESC(run, "Run the test (default: false)");
 
 static int dmatest_chan_set(const char *val, const struct kernel_param *kp);
 static int dmatest_chan_get(char *val, const struct kernel_param *kp);
-static const struct kernel_param_ops multi_chan_ops = {
-	.set = dmatest_chan_set,
-	.get = dmatest_chan_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(multi_chan_ops, dmatest_chan_set,
+			       dmatest_chan_get);
 
 static char test_channel[20];
 static struct kparam_string newchan_kps = {
@@ -178,9 +173,7 @@ module_param_cb(channel, &multi_chan_ops, &newchan_kps, 0644);
 MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)");
 
 static int dmatest_test_list_get(char *val, const struct kernel_param *kp);
-static const struct kernel_param_ops test_list_ops = {
-	.get = dmatest_test_list_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(test_list_ops, NULL, dmatest_test_list_get);
 module_param_cb(test_list, &test_list_ops, NULL, 0444);
 MODULE_PARM_DESC(test_list, "Print current test list");
 
@@ -292,10 +285,7 @@ static int dmatest_wait_get(char *val, const struct kernel_param *kp)
 	return param_get_bool(val, kp);
 }
 
-static const struct kernel_param_ops wait_ops = {
-	.get = dmatest_wait_get,
-	.set = param_set_bool,
-};
+static DEFINE_KERNEL_PARAM_OPS(wait_ops, param_set_bool, dmatest_wait_get);
 module_param_cb(wait, &wait_ops, &wait, 0444);
 MODULE_PARM_DESC(wait, "Wait for tests to complete (default: false)");
 
diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c
index 63df35444214..ab05e58faaa8 100644
--- a/drivers/edac/i10nm_base.c
+++ b/drivers/edac/i10nm_base.c
@@ -1284,10 +1284,8 @@ static int set_decoding_via_mca(const char *buf, const struct kernel_param *kp)
 	return ret;
 }
 
-static const struct kernel_param_ops decoding_via_mca_param_ops = {
-	.set = set_decoding_via_mca,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(decoding_via_mca_param_ops, set_decoding_via_mca,
+			       param_get_int);
 
 module_param_cb(decoding_via_mca, &decoding_via_mca_param_ops, &decoding_via_mca, 0644);
 MODULE_PARM_DESC(decoding_via_mca, "decoding_via_mca: 0=off(default), 1=enable");
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index a253b6144945..fd0f3579fd54 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -43,10 +43,8 @@ static int efi_pstore_disable_set(const char *val, const struct kernel_param *kp
 	return 0;
 }
 
-static const struct kernel_param_ops pstore_disable_ops = {
-	.set	= efi_pstore_disable_set,
-	.get	= param_get_bool,
-};
+static DEFINE_KERNEL_PARAM_OPS(pstore_disable_ops, efi_pstore_disable_set,
+			       param_get_bool);
 
 module_param_cb(pstore_disable, &pstore_disable_ops, &pstore_disable, 0644);
 __MODULE_PARM_TYPE(pstore_disable, "bool");
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 9b06a69d3a6d..ef57df53e087 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -2725,10 +2725,8 @@ static int set_download_mode(const char *val, const struct kernel_param *kp)
 	return 0;
 }
 
-static const struct kernel_param_ops download_mode_param_ops = {
-	.get = get_download_mode,
-	.set = set_download_mode,
-};
+static DEFINE_KERNEL_PARAM_OPS(download_mode_param_ops, set_download_mode,
+			       get_download_mode);
 
 module_param_cb(download_mode, &download_mode_param_ops, NULL, 0644);
 MODULE_PARM_DESC(download_mode, "download mode: off/0/N for no dump mode, full/on/1/Y for full dump mode, mini for minidump mode and full,mini for both full and minidump mode together are acceptable values");
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
index 87a5421bc7d5..c87a5449ba8c 100644
--- a/drivers/firmware/qemu_fw_cfg.c
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -897,10 +897,8 @@ static int fw_cfg_cmdline_get(char *buf, const struct kernel_param *kp)
 	return 0;
 }
 
-static const struct kernel_param_ops fw_cfg_cmdline_param_ops = {
-	.set = fw_cfg_cmdline_set,
-	.get = fw_cfg_cmdline_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(fw_cfg_cmdline_param_ops, fw_cfg_cmdline_set,
+			       fw_cfg_cmdline_get);
 
 device_param_cb(ioport, &fw_cfg_cmdline_param_ops, NULL, S_IRUSR);
 device_param_cb(mmio, &fw_cfg_cmdline_param_ops, NULL, S_IRUSR);
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index d6d3b8d85dea..c35d1adf2ce3 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -847,10 +847,8 @@ static int drm_panic_type_get(char *buffer, const struct kernel_param *kp)
 			 drm_panic_type_map[drm_panic_type]);
 }
 
-static const struct kernel_param_ops drm_panic_ops = {
-	.set = drm_panic_type_set,
-	.get = drm_panic_type_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(drm_panic_ops, drm_panic_type_set,
+			       drm_panic_type_get);
 
 module_param_cb(panic_screen, &drm_panic_ops, NULL, 0644);
 MODULE_PARM_DESC(panic_screen,
diff --git a/drivers/gpu/drm/i915/i915_mitigations.c b/drivers/gpu/drm/i915/i915_mitigations.c
index def7302ef7fe..6061eae84e9c 100644
--- a/drivers/gpu/drm/i915/i915_mitigations.c
+++ b/drivers/gpu/drm/i915/i915_mitigations.c
@@ -124,10 +124,7 @@ static int mitigations_get(char *buffer, const struct kernel_param *kp)
 	return count;
 }
 
-static const struct kernel_param_ops ops = {
-	.set = mitigations_set,
-	.get = mitigations_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(ops, mitigations_set, mitigations_get);
 
 module_param_cb_unsafe(mitigations, &ops, NULL, 0600);
 MODULE_PARM_DESC(mitigations,
diff --git a/drivers/gpu/drm/imagination/pvr_fw_trace.c b/drivers/gpu/drm/imagination/pvr_fw_trace.c
index 6193811ef7be..2df7274e21a8 100644
--- a/drivers/gpu/drm/imagination/pvr_fw_trace.c
+++ b/drivers/gpu/drm/imagination/pvr_fw_trace.c
@@ -71,10 +71,8 @@ pvr_fw_trace_init_mask_set(const char *val, const struct kernel_param *kp)
 	return 0;
 }
 
-const struct kernel_param_ops pvr_fw_trace_init_mask_ops = {
-	.set = pvr_fw_trace_init_mask_set,
-	.get = param_get_hexint,
-};
+DEFINE_KERNEL_PARAM_OPS(pvr_fw_trace_init_mask_ops, pvr_fw_trace_init_mask_set,
+			param_get_hexint);
 
 param_check_hexint(init_fw_trace_mask, &pvr_fw_trace_init_mask);
 module_param_cb(init_fw_trace_mask, &pvr_fw_trace_init_mask_ops, &pvr_fw_trace_init_mask, 0600);
diff --git a/drivers/hid/hid-cougar.c b/drivers/hid/hid-cougar.c
index ad027c45f162..271048bdf7fc 100644
--- a/drivers/hid/hid-cougar.c
+++ b/drivers/hid/hid-cougar.c
@@ -314,10 +314,8 @@ static int cougar_param_set_g6_is_space(const char *val,
 	return 0;
 }
 
-static const struct kernel_param_ops cougar_g6_is_space_ops = {
-	.set	= cougar_param_set_g6_is_space,
-	.get	= param_get_bool,
-};
+static DEFINE_KERNEL_PARAM_OPS(cougar_g6_is_space_ops,
+			       cougar_param_set_g6_is_space, param_get_bool);
 module_param_cb(g6_is_space, &cougar_g6_is_space_ops, &g6_is_space, 0644);
 
 static const struct hid_device_id cougar_id_table[] = {
diff --git a/drivers/hid/hid-steam.c b/drivers/hid/hid-steam.c
index 197126d6e081..962ed60492ea 100644
--- a/drivers/hid/hid-steam.c
+++ b/drivers/hid/hid-steam.c
@@ -1840,10 +1840,8 @@ static int steam_param_set_lizard_mode(const char *val,
 	return 0;
 }
 
-static const struct kernel_param_ops steam_lizard_mode_ops = {
-	.set	= steam_param_set_lizard_mode,
-	.get	= param_get_bool,
-};
+static DEFINE_KERNEL_PARAM_OPS(steam_lizard_mode_ops,
+			       steam_param_set_lizard_mode, param_get_bool);
 
 module_param_cb(lizard_mode, &steam_lizard_mode_ops, &lizard_mode, 0644);
 MODULE_PARM_DESC(lizard_mode,
diff --git a/drivers/infiniband/hw/hfi1/driver.c b/drivers/infiniband/hw/hfi1/driver.c
index c7259cc39013..5b9b0b38b419 100644
--- a/drivers/infiniband/hw/hfi1/driver.c
+++ b/drivers/infiniband/hw/hfi1/driver.c
@@ -42,10 +42,7 @@ MODULE_PARM_DESC(cu, "Credit return units");
 unsigned long hfi1_cap_mask = HFI1_CAP_MASK_DEFAULT;
 static int hfi1_caps_set(const char *val, const struct kernel_param *kp);
 static int hfi1_caps_get(char *buffer, const struct kernel_param *kp);
-static const struct kernel_param_ops cap_ops = {
-	.set = hfi1_caps_set,
-	.get = hfi1_caps_get
-};
+static DEFINE_KERNEL_PARAM_OPS(cap_ops, hfi1_caps_set, hfi1_caps_get);
 module_param_cb(cap_mask, &cap_ops, &hfi1_cap_mask, S_IWUSR | S_IRUGO);
 MODULE_PARM_DESC(cap_mask, "Bit mask of enabled/disabled HW features");
 
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 7df441685780..758e527ca7c4 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -90,10 +90,8 @@ module_param_named(debug_level, iser_debug_level, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0 (default:disabled)");
 
 static int iscsi_iser_set(const char *val, const struct kernel_param *kp);
-static const struct kernel_param_ops iscsi_iser_size_ops = {
-	.set = iscsi_iser_set,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(iscsi_iser_size_ops, iscsi_iser_set,
+			       param_get_uint);
 
 static unsigned int iscsi_max_lun = 512;
 module_param_cb(max_lun, &iscsi_iser_size_ops, &iscsi_max_lun, S_IRUGO);
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 348005e71891..bd91900a0ebf 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -30,10 +30,8 @@ MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0 (default:0)");
 
 static int isert_sg_tablesize_set(const char *val,
 				  const struct kernel_param *kp);
-static const struct kernel_param_ops sg_tablesize_ops = {
-	.set = isert_sg_tablesize_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(sg_tablesize_ops, isert_sg_tablesize_set,
+			       param_get_int);
 
 static int isert_sg_tablesize = ISCSI_ISER_MIN_SG_TABLESIZE;
 module_param_cb(sg_tablesize, &sg_tablesize_ops, &isert_sg_tablesize, 0644);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index b58868e1cf11..a81515f52a4f 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -195,10 +195,7 @@ static int srp_tmo_set(const char *val, const struct kernel_param *kp)
 	return res;
 }
 
-static const struct kernel_param_ops srp_tmo_ops = {
-	.get = srp_tmo_get,
-	.set = srp_tmo_set,
-};
+static DEFINE_KERNEL_PARAM_OPS(srp_tmo_ops, srp_tmo_set, srp_tmo_get);
 
 static inline struct srp_target_port *host_to_target(struct Scsi_Host *host)
 {
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index 8db2dca84975..8b4ef7e163d3 100644
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -89,19 +89,16 @@ static int ati_remote2_get_mode_mask(char *buffer,
 
 static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK;
 #define param_check_channel_mask(name, p) __param_check(name, p, unsigned int)
-static const struct kernel_param_ops param_ops_channel_mask = {
-	.set = ati_remote2_set_channel_mask,
-	.get = ati_remote2_get_channel_mask,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_channel_mask,
+			       ati_remote2_set_channel_mask,
+			       ati_remote2_get_channel_mask);
 module_param(channel_mask, channel_mask, 0644);
 MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>");
 
 static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK;
 #define param_check_mode_mask(name, p) __param_check(name, p, unsigned int)
-static const struct kernel_param_ops param_ops_mode_mask = {
-	.set = ati_remote2_set_mode_mask,
-	.get = ati_remote2_get_mode_mask,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_mode_mask, ati_remote2_set_mode_mask,
+			       ati_remote2_get_mode_mask);
 module_param(mode_mask, mode_mask, 0644);
 MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");
 
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 6ab5f1d96eae..f9ebb1fd0b6f 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -45,10 +45,8 @@ MODULE_LICENSE("GPL");
 static unsigned int psmouse_max_proto = PSMOUSE_AUTO;
 static int psmouse_set_maxproto(const char *val, const struct kernel_param *);
 static int psmouse_get_maxproto(char *buffer, const struct kernel_param *kp);
-static const struct kernel_param_ops param_ops_proto_abbrev = {
-	.set = psmouse_set_maxproto,
-	.get = psmouse_get_maxproto,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_proto_abbrev, psmouse_set_maxproto,
+			       psmouse_get_maxproto);
 #define param_check_proto_abbrev(name, p)	__param_check(name, p, unsigned int)
 module_param_named(proto, psmouse_max_proto, proto_abbrev, 0644);
 MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps, any). Useful for KVM switches.");
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 31b4ac3b48c1..2338cab7fef9 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -2488,10 +2488,8 @@ static int param_set_nodrop(const char *val, const struct kernel_param *kp)
 	return param_set_bool(val, kp);
 }
 
-static const struct kernel_param_ops param_ops_nodrop = {
-	.set = param_set_nodrop,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_nodrop, param_set_nodrop,
+			       param_get_uint);
 
 param_check_uint(nodrop, &uvc_no_drop_param);
 module_param_cb(nodrop, &param_ops_nodrop, &uvc_no_drop_param, 0644);
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c
index 21e8ad0a7444..6e40c14be51e 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d.c
@@ -103,10 +103,7 @@ static int param_set_axis(const char *val, const struct kernel_param *kp)
 	return ret;
 }
 
-static const struct kernel_param_ops param_ops_axis = {
-	.set = param_set_axis,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_axis, param_set_axis, param_get_int);
 
 #define param_check_axis(name, p) param_check_int(name, p)
 
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index d5aec72ecdce..e566d94d5f5c 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -62,10 +62,7 @@ static int mtu_max_set(const char *val, const struct kernel_param *kp)
 	return ret;
 }
 
-static const struct kernel_param_ops mtu_max_ops = {
-	.set = mtu_max_set,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(mtu_max_ops, mtu_max_set, param_get_uint);
 
 module_param_cb(mtu_max, &mtu_max_ops, &mtu_max, 0444);
 MODULE_PARM_DESC(mtu_max, " Max MTU value.");
@@ -91,10 +88,7 @@ static int ring_order_set(const char *val, const struct kernel_param *kp)
 	return 0;
 }
 
-static const struct kernel_param_ops ring_order_ops = {
-	.set = ring_order_set,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(ring_order_ops, ring_order_set, param_get_uint);
 
 module_param_cb(rx_ring_order, &ring_order_ops, &rx_ring_order, 0444);
 MODULE_PARM_DESC(rx_ring_order, " Rx ring order; size = 1 << order");
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 263161cb8ac0..f7362377e427 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -30,10 +30,8 @@ static int multipath_param_set(const char *val, const struct kernel_param *kp)
 	return 0;
 }
 
-static const struct kernel_param_ops multipath_param_ops = {
-	.set = multipath_param_set,
-	.get = param_get_bool,
-};
+static DEFINE_KERNEL_PARAM_OPS(multipath_param_ops, multipath_param_set,
+			       param_get_bool);
 
 module_param_cb(multipath, &multipath_param_ops, &multipath, 0444);
 MODULE_PARM_DESC(multipath,
@@ -55,10 +53,8 @@ static int multipath_always_on_set(const char *val,
 	return 0;
 }
 
-static const struct kernel_param_ops multipath_always_on_ops = {
-	.set = multipath_always_on_set,
-	.get = param_get_bool,
-};
+static DEFINE_KERNEL_PARAM_OPS(multipath_always_on_ops, multipath_always_on_set,
+			       param_get_bool);
 
 module_param_cb(multipath_always_on, &multipath_always_on_ops,
 		&multipath_always_on, 0444);
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 9fd04cd7c5cb..c77e9b848d03 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -100,10 +100,8 @@ MODULE_PARM_DESC(sgl_threshold,
 #define NVME_PCI_MIN_QUEUE_SIZE 2
 #define NVME_PCI_MAX_QUEUE_SIZE 4095
 static int io_queue_depth_set(const char *val, const struct kernel_param *kp);
-static const struct kernel_param_ops io_queue_depth_ops = {
-	.set = io_queue_depth_set,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(io_queue_depth_ops, io_queue_depth_set,
+			       param_get_uint);
 
 static unsigned int io_queue_depth = 1024;
 module_param_cb(io_queue_depth, &io_queue_depth_ops, &io_queue_depth, 0644);
@@ -232,10 +230,8 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp)
 }
 
 static char quirks_param[128];
-static const struct kernel_param_ops quirks_param_ops = {
-	.set = quirks_param_set,
-	.get = param_get_string,
-};
+static DEFINE_KERNEL_PARAM_OPS(quirks_param_ops, quirks_param_set,
+			       param_get_string);
 
 static struct kparam_string quirks_param_string = {
 	.maxlen = sizeof(quirks_param),
@@ -257,10 +253,8 @@ static int io_queue_count_set(const char *val, const struct kernel_param *kp)
 	return param_set_uint(val, kp);
 }
 
-static const struct kernel_param_ops io_queue_count_ops = {
-	.set = io_queue_count_set,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(io_queue_count_ops, io_queue_count_set,
+			       param_get_uint);
 
 static unsigned int write_queues;
 module_param_cb(write_queues, &io_queue_count_ops, &write_queues, 0644);
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index e6e2c3f9afdf..dc544813300f 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -147,10 +147,7 @@ module_param_named(use_srq, nvmet_rdma_use_srq, bool, 0444);
 MODULE_PARM_DESC(use_srq, "Use shared receive queue.");
 
 static int srq_size_set(const char *val, const struct kernel_param *kp);
-static const struct kernel_param_ops srq_size_ops = {
-	.set = srq_size_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(srq_size_ops, srq_size_set, param_get_int);
 
 static int nvmet_rdma_srq_size = 1024;
 module_param_cb(srq_size, &srq_size_ops, &nvmet_rdma_srq_size, 0644);
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index 164a564ba3b4..2f336cd7e559 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -46,10 +46,7 @@ static int set_params(const char *str, const struct kernel_param *kp)
 	return param_store_val(str, kp->arg, 0, INT_MAX);
 }
 
-static const struct kernel_param_ops set_param_ops = {
-	.set	= set_params,
-	.get	= param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(set_param_ops, set_params, param_get_int);
 
 /* Define the socket priority to use for connections were it is desirable
  * that the NIC consider performing optimized packet processing or filtering.
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index 5ce5ad3efe69..bd59c3f3f2c5 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -762,10 +762,7 @@ static int interval_set_uint(const char *val, const struct kernel_param *kp)
 	return 0;
 }
 
-static const struct kernel_param_ops interval_ops = {
-	.set = interval_set_uint,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(interval_ops, interval_set_uint, param_get_uint);
 
 module_param_cb(interval, &interval_ops, &interval, 0000);
 MODULE_PARM_DESC(interval, "Polling interval of temperature check");
diff --git a/drivers/power/supply/bq27xxx_battery.c b/drivers/power/supply/bq27xxx_battery.c
index 45f0e39b8c2d..09829ee1a49d 100644
--- a/drivers/power/supply/bq27xxx_battery.c
+++ b/drivers/power/supply/bq27xxx_battery.c
@@ -1133,10 +1133,8 @@ static int poll_interval_param_set(const char *val, const struct kernel_param *k
 	return ret;
 }
 
-static const struct kernel_param_ops param_ops_poll_interval = {
-	.get = param_get_uint,
-	.set = poll_interval_param_set,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_poll_interval, poll_interval_param_set,
+			       param_get_uint);
 
 static unsigned int poll_interval = 360;
 module_param_cb(poll_interval, &param_ops_poll_interval, &poll_interval, 0644);
diff --git a/drivers/power/supply/test_power.c b/drivers/power/supply/test_power.c
index 2c0e9ad820c0..0bf2bef3383a 100644
--- a/drivers/power/supply/test_power.c
+++ b/drivers/power/supply/test_power.c
@@ -649,60 +649,47 @@ static int param_set_battery_extension(const char *key,
 
 #define param_get_battery_extension param_get_bool
 
-static const struct kernel_param_ops param_ops_ac_online = {
-	.set = param_set_ac_online,
-	.get = param_get_ac_online,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_ac_online, param_set_ac_online,
+			       param_get_ac_online);
 
-static const struct kernel_param_ops param_ops_usb_online = {
-	.set = param_set_usb_online,
-	.get = param_get_usb_online,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_usb_online, param_set_usb_online,
+			       param_get_usb_online);
 
-static const struct kernel_param_ops param_ops_battery_status = {
-	.set = param_set_battery_status,
-	.get = param_get_battery_status,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_battery_status,
+			       param_set_battery_status,
+			       param_get_battery_status);
 
-static const struct kernel_param_ops param_ops_battery_present = {
-	.set = param_set_battery_present,
-	.get = param_get_battery_present,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_battery_present,
+			       param_set_battery_present,
+			       param_get_battery_present);
 
-static const struct kernel_param_ops param_ops_battery_technology = {
-	.set = param_set_battery_technology,
-	.get = param_get_battery_technology,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_battery_technology,
+			       param_set_battery_technology,
+			       param_get_battery_technology);
 
-static const struct kernel_param_ops param_ops_battery_health = {
-	.set = param_set_battery_health,
-	.get = param_get_battery_health,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_battery_health,
+			       param_set_battery_health,
+			       param_get_battery_health);
 
-static const struct kernel_param_ops param_ops_battery_capacity = {
-	.set = param_set_battery_capacity,
-	.get = param_get_battery_capacity,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_battery_capacity,
+			       param_set_battery_capacity,
+			       param_get_battery_capacity);
 
-static const struct kernel_param_ops param_ops_battery_voltage = {
-	.set = param_set_battery_voltage,
-	.get = param_get_battery_voltage,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_battery_voltage,
+			       param_set_battery_voltage,
+			       param_get_battery_voltage);
 
-static const struct kernel_param_ops param_ops_battery_charge_counter = {
-	.set = param_set_battery_charge_counter,
-	.get = param_get_battery_charge_counter,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_battery_charge_counter,
+			       param_set_battery_charge_counter,
+			       param_get_battery_charge_counter);
 
-static const struct kernel_param_ops param_ops_battery_current = {
-	.set = param_set_battery_current,
-	.get = param_get_battery_current,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_battery_current,
+			       param_set_battery_current,
+			       param_get_battery_current);
 
-static const struct kernel_param_ops param_ops_battery_extension = {
-	.set = param_set_battery_extension,
-	.get = param_get_battery_extension,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_battery_extension,
+			       param_set_battery_extension,
+			       param_get_battery_extension);
 
 #define param_check_ac_online(name, p) __param_check(name, p, void);
 #define param_check_usb_online(name, p) __param_check(name, p, void);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 2b4b2a1a8e44..c075b567f84e 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1644,10 +1644,8 @@ static int def_reserved_size_set(const char *val, const struct kernel_param *kp)
 	return 0;
 }
 
-static const struct kernel_param_ops def_reserved_size_ops = {
-	.set	= def_reserved_size_set,
-	.get	= param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(def_reserved_size_ops, def_reserved_size_set,
+			       param_get_int);
 
 module_param_cb(def_reserved_size, &def_reserved_size_ops, &def_reserved_size,
 		   S_IRUGO | S_IWUSR);
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index edc2afd5f4ee..676a12b44e88 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -255,10 +255,9 @@ static int tcmu_get_global_max_data_area(char *buffer,
 	return sprintf(buffer, "%d\n", TCMU_PAGES_TO_MBS(tcmu_global_max_pages));
 }
 
-static const struct kernel_param_ops tcmu_global_max_data_area_op = {
-	.set = tcmu_set_global_max_data_area,
-	.get = tcmu_get_global_max_data_area,
-};
+static DEFINE_KERNEL_PARAM_OPS(tcmu_global_max_data_area_op,
+			       tcmu_set_global_max_data_area,
+			       tcmu_get_global_max_data_area);
 
 module_param_cb(global_max_data_area_mb, &tcmu_global_max_data_area_op, NULL,
 		S_IWUSR | S_IRUGO);
@@ -292,10 +291,8 @@ static int tcmu_set_block_netlink(const char *str,
 	return 0;
 }
 
-static const struct kernel_param_ops tcmu_block_netlink_op = {
-	.set = tcmu_set_block_netlink,
-	.get = tcmu_get_block_netlink,
-};
+static DEFINE_KERNEL_PARAM_OPS(tcmu_block_netlink_op, tcmu_set_block_netlink,
+			       tcmu_get_block_netlink);
 
 module_param_cb(block_netlink, &tcmu_block_netlink_op, NULL, S_IWUSR | S_IRUGO);
 MODULE_PARM_DESC(block_netlink, "Block new netlink commands.");
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_soc_slider.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_soc_slider.c
index 91f291627132..68275c3f2c9b 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_soc_slider.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_soc_slider.c
@@ -83,10 +83,8 @@ static int slider_def_balance_get(char *buf, const struct kernel_param *kp)
 	return sysfs_emit(buf, "%02x\n", slider_values[SOC_POWER_SLIDER_BALANCE]);
 }
 
-static const struct kernel_param_ops slider_def_balance_ops = {
-	.set = slider_def_balance_set,
-	.get = slider_def_balance_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(slider_def_balance_ops, slider_def_balance_set,
+			       slider_def_balance_get);
 
 module_param_cb(slider_balance, &slider_def_balance_ops, NULL, 0644);
 MODULE_PARM_DESC(slider_balance, "Set slider default value for balance");
@@ -117,10 +115,8 @@ static int slider_def_offset_get(char *buf, const struct kernel_param *kp)
 	return sysfs_emit(buf, "%02x\n", slider_offset);
 }
 
-static const struct kernel_param_ops slider_offset_ops = {
-	.set = slider_def_offset_set,
-	.get = slider_def_offset_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(slider_offset_ops, slider_def_offset_set,
+			       slider_def_offset_get);
 
 /*
  * To enhance power efficiency dynamically, the firmware can optionally
diff --git a/drivers/thermal/intel/intel_powerclamp.c b/drivers/thermal/intel/intel_powerclamp.c
index ccf380da12f2..98fbc6892714 100644
--- a/drivers/thermal/intel/intel_powerclamp.c
+++ b/drivers/thermal/intel/intel_powerclamp.c
@@ -112,10 +112,7 @@ static int duration_get(char *buf, const struct kernel_param *kp)
 	return ret;
 }
 
-static const struct kernel_param_ops duration_ops = {
-	.set = duration_set,
-	.get = duration_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(duration_ops, duration_set, duration_get);
 
 module_param_cb(duration, &duration_ops, NULL, 0644);
 MODULE_PARM_DESC(duration, "forced idle time for each attempt in msec.");
@@ -203,10 +200,7 @@ static int cpumask_get(char *buf, const struct kernel_param *kp)
 	return cpumap_print_to_pagebuf(false, buf, idle_injection_cpu_mask);
 }
 
-static const struct kernel_param_ops cpumask_ops = {
-	.set = cpumask_set,
-	.get = cpumask_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(cpumask_ops, cpumask_set, cpumask_get);
 
 module_param_cb(cpumask, &cpumask_ops, NULL, 0644);
 MODULE_PARM_DESC(cpumask, "Mask of CPUs to use for idle injection.");
@@ -252,10 +246,7 @@ static int max_idle_set(const char *arg, const struct kernel_param *kp)
 	return ret;
 }
 
-static const struct kernel_param_ops max_idle_ops = {
-	.set = max_idle_set,
-	.get = param_get_byte,
-};
+static DEFINE_KERNEL_PARAM_OPS(max_idle_ops, max_idle_set, param_get_byte);
 
 module_param_cb(max_idle, &max_idle_ops, &max_idle, 0644);
 MODULE_PARM_DESC(max_idle, "maximum injected idle time to the total CPU time ratio in percent range:1-100");
@@ -299,10 +290,7 @@ static int window_size_set(const char *arg, const struct kernel_param *kp)
 	return ret;
 }
 
-static const struct kernel_param_ops window_size_ops = {
-	.set = window_size_set,
-	.get = param_get_int,
-};
+static DEFINE_KERNEL_PARAM_OPS(window_size_ops, window_size_set, param_get_int);
 
 module_param_cb(window_size, &window_size_ops, &window_size, 0644);
 MODULE_PARM_DESC(window_size, "sliding window in number of clamping cycles\n"
diff --git a/drivers/tty/hvc/hvc_iucv.c b/drivers/tty/hvc/hvc_iucv.c
index 37db8a3e5158..29612a4a32cb 100644
--- a/drivers/tty/hvc/hvc_iucv.c
+++ b/drivers/tty/hvc/hvc_iucv.c
@@ -1290,10 +1290,8 @@ static int param_get_vmidfilter(char *buffer, const struct kernel_param *kp)
 
 #define param_check_vmidfilter(name, p) __param_check(name, p, void)
 
-static const struct kernel_param_ops param_ops_vmidfilter = {
-	.set = param_set_vmidfilter,
-	.get = param_get_vmidfilter,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_vmidfilter, param_set_vmidfilter,
+			       param_get_vmidfilter);
 
 /**
  * hvc_iucv_init() - z/VM IUCV HVC device driver initialization
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index c2e4b31b699a..c6279c496279 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -1074,10 +1074,8 @@ static int sysrq_reset_seq_param_set(const char *buffer,
 	return 0;
 }
 
-static const struct kernel_param_ops param_ops_sysrq_reset_seq = {
-	.get	= param_get_ushort,
-	.set	= sysrq_reset_seq_param_set,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_sysrq_reset_seq,
+			       sysrq_reset_seq_param_set, param_get_ushort);
 
 #define param_check_sysrq_reset_seq(name, p)	\
 	__param_check(name, p, unsigned short)
diff --git a/drivers/ufs/core/ufs-fault-injection.c b/drivers/ufs/core/ufs-fault-injection.c
index 55db38e75cc4..7d2873da7dc5 100644
--- a/drivers/ufs/core/ufs-fault-injection.c
+++ b/drivers/ufs/core/ufs-fault-injection.c
@@ -11,10 +11,7 @@
 static int ufs_fault_get(char *buffer, const struct kernel_param *kp);
 static int ufs_fault_set(const char *val, const struct kernel_param *kp);
 
-static const struct kernel_param_ops ufs_fault_ops = {
-	.get = ufs_fault_get,
-	.set = ufs_fault_set,
-};
+static DEFINE_KERNEL_PARAM_OPS(ufs_fault_ops, ufs_fault_set, ufs_fault_get);
 
 enum { FAULT_INJ_STR_SIZE = 80 };
 
diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c
index c1b1d67a1ddc..83100aad2a97 100644
--- a/drivers/ufs/core/ufs-mcq.c
+++ b/drivers/ufs/core/ufs-mcq.c
@@ -43,10 +43,8 @@ static int rw_queue_count_set(const char *val, const struct kernel_param *kp)
 				     num_possible_cpus());
 }
 
-static const struct kernel_param_ops rw_queue_count_ops = {
-	.set = rw_queue_count_set,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(rw_queue_count_ops, rw_queue_count_set,
+			       param_get_uint);
 
 static unsigned int rw_queues;
 module_param_cb(rw_queues, &rw_queue_count_ops, &rw_queues, 0644);
@@ -59,10 +57,8 @@ static int read_queue_count_set(const char *val, const struct kernel_param *kp)
 				     num_possible_cpus());
 }
 
-static const struct kernel_param_ops read_queue_count_ops = {
-	.set = read_queue_count_set,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(read_queue_count_ops, read_queue_count_set,
+			       param_get_uint);
 
 static unsigned int read_queues;
 module_param_cb(read_queues, &read_queue_count_ops, &read_queues, 0644);
@@ -75,10 +71,8 @@ static int poll_queue_count_set(const char *val, const struct kernel_param *kp)
 				     num_possible_cpus());
 }
 
-static const struct kernel_param_ops poll_queue_count_ops = {
-	.set = poll_queue_count_set,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(poll_queue_count_ops, poll_queue_count_set,
+			       param_get_uint);
 
 static unsigned int poll_queues = 1;
 module_param_cb(poll_queues, &poll_queue_count_ops, &poll_queues, 0644);
diff --git a/drivers/ufs/core/ufs-txeq.c b/drivers/ufs/core/ufs-txeq.c
index b2dc89124353..3bdd87b434ad 100644
--- a/drivers/ufs/core/ufs-txeq.c
+++ b/drivers/ufs/core/ufs-txeq.c
@@ -23,10 +23,7 @@ static int txeq_gear_set(const char *val, const struct kernel_param *kp)
 	return param_set_uint_minmax(val, kp, UFS_HS_G1, UFS_HS_GEAR_MAX);
 }
 
-static const struct kernel_param_ops txeq_gear_ops = {
-	.set = txeq_gear_set,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(txeq_gear_ops, txeq_gear_set, param_get_uint);
 
 static unsigned int adaptive_txeq_gear = UFS_HS_G6;
 module_param_cb(adaptive_txeq_gear, &txeq_gear_ops, &adaptive_txeq_gear, 0644);
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 4805e40ed4d7..4e930710d9a6 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -128,10 +128,8 @@ static int uic_cmd_timeout_set(const char *val, const struct kernel_param *kp)
 				     UIC_CMD_TIMEOUT_MAX);
 }
 
-static const struct kernel_param_ops uic_cmd_timeout_ops = {
-	.set = uic_cmd_timeout_set,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(uic_cmd_timeout_ops, uic_cmd_timeout_set,
+			       param_get_uint);
 
 module_param_cb(uic_cmd_timeout, &uic_cmd_timeout_ops, &uic_cmd_timeout, 0644);
 MODULE_PARM_DESC(uic_cmd_timeout,
@@ -145,10 +143,8 @@ static int dev_cmd_timeout_set(const char *val, const struct kernel_param *kp)
 				     QUERY_REQ_TIMEOUT_MAX);
 }
 
-static const struct kernel_param_ops dev_cmd_timeout_ops = {
-	.set = dev_cmd_timeout_set,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(dev_cmd_timeout_ops, dev_cmd_timeout_set,
+			       param_get_uint);
 
 module_param_cb(dev_cmd_timeout, &dev_cmd_timeout_ops, &dev_cmd_timeout, 0644);
 MODULE_PARM_DESC(dev_cmd_timeout,
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 0ffdaefba508..d52ecc886925 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -160,10 +160,8 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp)
 	return 0;
 }
 
-static const struct kernel_param_ops quirks_param_ops = {
-	.set = quirks_param_set,
-	.get = param_get_string,
-};
+static DEFINE_KERNEL_PARAM_OPS(quirks_param_ops, quirks_param_set,
+			       param_get_string);
 
 static struct kparam_string quirks_param_string = {
 	.maxlen = sizeof(quirks_param),
diff --git a/drivers/usb/gadget/legacy/serial.c b/drivers/usb/gadget/legacy/serial.c
index 4974bee6049a..e34717e553da 100644
--- a/drivers/usb/gadget/legacy/serial.c
+++ b/drivers/usb/gadget/legacy/serial.c
@@ -121,10 +121,7 @@ static int enable_set(const char *s, const struct kernel_param *kp)
 	return ret;
 }
 
-static const struct kernel_param_ops enable_ops = {
-	.set = enable_set,
-	.get = param_get_bool,
-};
+static DEFINE_KERNEL_PARAM_OPS(enable_ops, enable_set, param_get_bool);
 
 module_param_cb(enable, &enable_ops, &enable, 0644);
 
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index fa83fe0defe2..71dd623b95c9 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -158,10 +158,7 @@ static int delay_use_get(char *s, const struct kernel_param *kp)
 	return format_delay_ms(delay_ms, 3, "ms", s, PAGE_SIZE);
 }
 
-static const struct kernel_param_ops delay_use_ops = {
-	.set = delay_use_set,
-	.get = delay_use_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(delay_use_ops, delay_use_set, delay_use_get);
 module_param_cb(delay_use, &delay_use_ops, &delay_use, 0644);
 MODULE_PARM_DESC(delay_use, "time to delay before using a new device");
 
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 9a1253b9d8c5..fd52f2213e27 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -87,10 +87,9 @@ static int vhost_scsi_get_inline_sg_cnt(char *buf,
 	return sprintf(buf, "%u\n", vhost_scsi_inline_sg_cnt);
 }
 
-static const struct kernel_param_ops vhost_scsi_inline_sg_cnt_op = {
-	.get = vhost_scsi_get_inline_sg_cnt,
-	.set = vhost_scsi_set_inline_sg_cnt,
-};
+static DEFINE_KERNEL_PARAM_OPS(vhost_scsi_inline_sg_cnt_op,
+			       vhost_scsi_set_inline_sg_cnt,
+			       vhost_scsi_get_inline_sg_cnt);
 
 module_param_cb(inline_sg_cnt, &vhost_scsi_inline_sg_cnt_op, NULL, 0644);
 MODULE_PARM_DESC(inline_sg_cnt, "Set the number of scatterlist entries to pre-allocate. The default is 2048.");
diff --git a/drivers/virt/nitro_enclaves/ne_misc_dev.c b/drivers/virt/nitro_enclaves/ne_misc_dev.c
index c91300a73f50..218ddd93f960 100644
--- a/drivers/virt/nitro_enclaves/ne_misc_dev.c
+++ b/drivers/virt/nitro_enclaves/ne_misc_dev.c
@@ -86,10 +86,8 @@ struct ne_devs ne_devs = {
  */
 static int ne_set_kernel_param(const char *val, const struct kernel_param *kp);
 
-static const struct kernel_param_ops ne_cpu_pool_ops = {
-	.get	= param_get_string,
-	.set	= ne_set_kernel_param,
-};
+static DEFINE_KERNEL_PARAM_OPS(ne_cpu_pool_ops, ne_set_kernel_param,
+			       param_get_string);
 
 static char ne_cpus[NE_CPUS_SIZE];
 static struct kparam_string ne_cpus_arg = {
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 595c2274fbb5..f6df9c76ee81 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -748,10 +748,8 @@ static int vm_cmdline_get(char *buffer, const struct kernel_param *kp)
 	return strlen(buffer) + 1;
 }
 
-static const struct kernel_param_ops vm_cmdline_param_ops = {
-	.set = vm_cmdline_set,
-	.get = vm_cmdline_get,
-};
+static DEFINE_KERNEL_PARAM_OPS(vm_cmdline_param_ops, vm_cmdline_set,
+			       vm_cmdline_get);
 
 device_param_cb(device, &vm_cmdline_param_ops, NULL, S_IRUSR);
 
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index c05fbd4237f8..dec8024b8ac7 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -1684,10 +1684,8 @@ static int param_set_metrics(const char *val, const struct kernel_param *kp)
 	return 0;
 }
 
-static const struct kernel_param_ops param_ops_metrics = {
-	.set = param_set_metrics,
-	.get = param_get_bool,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_metrics, param_set_metrics,
+			       param_get_bool);
 
 bool disable_send_metrics = false;
 module_param_cb(disable_send_metrics, &param_ops_metrics, &disable_send_metrics, 0644);
@@ -1695,9 +1693,7 @@ MODULE_PARM_DESC(disable_send_metrics, "Enable sending perf metrics to ceph clus
 
 /* for both v1 and v2 syntax */
 static bool mount_support = true;
-static const struct kernel_param_ops param_ops_mount_syntax = {
-	.get = param_get_bool,
-};
+static DEFINE_KERNEL_PARAM_OPS(param_ops_mount_syntax, NULL, param_get_bool);
 module_param_cb(mount_syntax_v1, &param_ops_mount_syntax, &mount_support, 0444);
 module_param_cb(mount_syntax_v2, &param_ops_mount_syntax, &mount_support, 0444);
 
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index b658b6baf72f..cc955c9952d1 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -71,10 +71,7 @@ static int inval_wq_set(const char *val, const struct kernel_param *kp)
 
 	return 0;
 }
-static const struct kernel_param_ops inval_wq_ops = {
-	.set = inval_wq_set,
-	.get = param_get_uint,
-};
+static DEFINE_KERNEL_PARAM_OPS(inval_wq_ops, inval_wq_set, param_get_uint);
 module_param_cb(inval_wq, &inval_wq_ops, &inval_wq, 0644);
 __MODULE_PARM_TYPE(inval_wq, "uint");