Linux Documentation
 help / color / mirror / Atom feed
* [PATCH v5 04/11] PCI: liveupdate: Document driver binding responsibilities
From: David Matlack @ 2026-05-12 18:48 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-mm, linux-pci
  Cc: Adithya Jayachandran, Alexander Graf, Alex Williamson,
	Bjorn Helgaas, Chris Li, David Matlack, David Rientjes, Jacob Pan,
	Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
	Lukas Wunner, Mike Rapoport, Parav Pandit, Pasha Tatashin,
	Pranjal Shrivastava, Pratyush Yadav, Saeed Mahameed,
	Samiullah Khawaja, Shuah Khan, Vipin Sharma, William Tu, Yi Liu
In-Reply-To: <20260512184846.119396-1-dmatlack@google.com>

Document how driver binding works during a Live Update and what the PCI
core expects of drivers and users. Note that this is only a description
of the current division of responsibilities. These can change in the
future if we decide.

Signed-off-by: David Matlack <dmatlack@google.com>
---
 drivers/pci/liveupdate.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
index f14396dd1477..d77e64906a25 100644
--- a/drivers/pci/liveupdate.c
+++ b/drivers/pci/liveupdate.c
@@ -77,6 +77,22 @@
  * preserved. These may be relaxed in the future:
  *
  *  * The device cannot be a Virtual Function (VF).
+ *
+ * Driver Binding
+ * ==============
+ *
+ * In the outgoing kernel, it is the driver's responsibility to ensure that it
+ * does not release a device between pci_liveupdate_preserve() and
+ * pci_liveupdate_unpreserve().
+ *
+ * In the incoming kernel, it is the driver's responsibility to ensure that it
+ * does not release a preserved device between probe() and
+ * pci_liveupdate_finish().
+ *
+ * It is the user's responsibility to ensure that incoming preserved devices are
+ * bound to the correct driver. i.e. The PCI core does not protect against a
+ * device getting preserved by driver A in the outgoing kernel and then getting
+ * bound to driver B in the incoming kernel.
  */
 
 #define pr_fmt(fmt) "PCI: liveupdate: " fmt
-- 
2.54.0.563.g4f69b47b94-goog


^ permalink raw reply related

* [PATCH v5 03/11] PCI: liveupdate: Track incoming preserved PCI devices
From: David Matlack @ 2026-05-12 18:48 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-mm, linux-pci
  Cc: Adithya Jayachandran, Alexander Graf, Alex Williamson,
	Bjorn Helgaas, Chris Li, David Matlack, David Rientjes, Jacob Pan,
	Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
	Lukas Wunner, Mike Rapoport, Parav Pandit, Pasha Tatashin,
	Pranjal Shrivastava, Pratyush Yadav, Saeed Mahameed,
	Samiullah Khawaja, Shuah Khan, Vipin Sharma, William Tu, Yi Liu
In-Reply-To: <20260512184846.119396-1-dmatlack@google.com>

During PCI enumeration, the previous kernel might have passed state about
devices that were preserved across kexec. The PCI core needs to fetch
this state to identify which devices are "incoming" and require special
handling.

Add pci_liveupdate_setup_device() which is called during device setup
to fetch the serialized state (struct pci_ser) from the Live Update
Orchestrator. The first time this happens, pci_flb_retrieve() will run
and convert the array of pci_dev_ser structs into an xarray so that it
can be looked up efficiently.

If a device is found in the xarray, the PCI core stores a pointer to its
state in dev->liveupdate_incoming and holds a reference to the incoming
FLB until pci_liveupdate_finish() is called by the driver.

This ensures proper lifecycle management for incoming preserved devices
and allows the PCI core and drivers to apply specific Live Update
logic to them in subsequent commits.

Drivers can check if a device is an incoming preserved device (e.g.
during probe) by calling pci_liveupdate_is_incoming().

CONFIG_64BIT is now required to enable CONFIG_PCI_LIVEUPDATE so that the
domain and bdf can be guaranteed to fit in an unsigned long and be used
as the xarray key.

Signed-off-by: David Matlack <dmatlack@google.com>
---
 MAINTAINERS                    |   1 +
 drivers/pci/Kconfig            |   2 +-
 drivers/pci/liveupdate.c       | 223 ++++++++++++++++++++++++++++++++-
 drivers/pci/liveupdate.h       |  26 ++++
 drivers/pci/probe.c            |   5 +
 include/linux/pci_liveupdate.h |  13 ++
 6 files changed, 267 insertions(+), 3 deletions(-)
 create mode 100644 drivers/pci/liveupdate.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6c618830cf61..0e262c0ceb43 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20537,6 +20537,7 @@ L:	linux-pci@vger.kernel.org
 S:	Maintained
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux.git
 F:	drivers/pci/liveupdate.c
+F:	drivers/pci/liveupdate.h
 F:	include/linux/kho/abi/pci.h
 F:	include/linux/pci_liveupdate.h
 
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 08398cbe970c..eea0a6cd388a 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -330,7 +330,7 @@ config VGA_ARB_MAX_GPUS
 
 config PCI_LIVEUPDATE
 	bool "PCI Live Update Support (EXPERIMENTAL)"
-	depends on PCI && LIVEUPDATE
+	depends on PCI && LIVEUPDATE && 64BIT
 	help
 	  Enable PCI core support for preserving PCI devices across Live
 	  Update. This, in combination with support in a device's driver,
diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
index 9c4582ecd55c..f14396dd1477 100644
--- a/drivers/pci/liveupdate.c
+++ b/drivers/pci/liveupdate.c
@@ -56,6 +56,20 @@
  * This allows the PCI core to keep its FLB data (struct pci_ser) up to date
  * with the list of **outgoing** preserved devices for the next kernel.
  *
+ * After kexec, whenever a device is enumerated, the PCI core will check if it
+ * is an **incoming** preserved device (i.e. preserved by the previous kernel)
+ * by checking the incoming FLB data (struct pci_ser).
+ *
+ * Drivers must notify the PCI core when an **incoming** device is done
+ * participating in the incoming Live Update with the following API:
+ *
+ *  * ``pci_liveupdate_finish(pci_dev)``
+ *
+ * The PCI core does not enforce any ordering of ``pci_liveupdate_finish()`` and
+ * ``pci_liveupdate_preserve()``. i.e. A PCI device can be **outgoing**
+ * (preserved for next kernel) and **incoming** (preserved by previous kernel)
+ * at the same time.
+ *
  * Restrictions
  * ============
  *
@@ -75,6 +89,8 @@
 #include <linux/mm.h>
 #include <linux/pci.h>
 
+#include "liveupdate.h"
+
 /**
  * struct pci_flb_outgoing - Outgoing PCI FLB object
  * @ser: The outgoing struct pci_ser for the next kernel.
@@ -85,6 +101,21 @@ struct pci_flb_outgoing {
 	struct mutex lock;
 };
 
+/**
+ * struct pci_flb_incoming - Incoming PCI FLB object
+ * @ser: The incoming struct pci_ser from the previous kernel.
+ * @xa: Xarray used to quickly lookup devices in @ser.
+ */
+struct pci_flb_incoming {
+	struct pci_ser *ser;
+	struct xarray xa;
+};
+
+static unsigned long pci_ser_xa_key(u32 domain, u16 bdf)
+{
+	return domain << 16 | bdf;
+}
+
 static int pci_flb_preserve(struct liveupdate_flb_op_args *args)
 {
 	struct pci_flb_outgoing *outgoing;
@@ -140,13 +171,44 @@ static void pci_flb_unpreserve(struct liveupdate_flb_op_args *args)
 
 static int pci_flb_retrieve(struct liveupdate_flb_op_args *args)
 {
-	args->obj = phys_to_virt(args->data);
+	struct pci_flb_incoming *incoming;
+	int i, ret;
+
+	incoming = kmalloc_obj(*incoming);
+	if (!incoming)
+		return -ENOMEM;
+
+	incoming->ser = phys_to_virt(args->data);
+
+	xa_init(&incoming->xa);
+
+	for (i = 0; i < incoming->ser->max_nr_devices; i++) {
+		struct pci_dev_ser *dev_ser = &incoming->ser->devices[i];
+		unsigned long key;
+
+		if (!dev_ser->refcount)
+			continue;
+
+		key = pci_ser_xa_key(dev_ser->domain, dev_ser->bdf);
+		ret = xa_err(xa_store(&incoming->xa, key, dev_ser, GFP_KERNEL));
+		if (ret) {
+			xa_destroy(&incoming->xa);
+			kfree(incoming);
+			return ret;
+		}
+	}
+
+	args->obj = incoming;
 	return 0;
 }
 
 static void pci_flb_finish(struct liveupdate_flb_op_args *args)
 {
-	kho_restore_free(args->obj);
+	struct pci_flb_incoming *incoming = args->obj;
+
+	xa_destroy(&incoming->xa);
+	kho_restore_free(incoming->ser);
+	kfree(incoming);
 }
 
 static struct liveupdate_flb_ops pci_liveupdate_flb_ops = {
@@ -268,6 +330,163 @@ void pci_liveupdate_unpreserve(struct pci_dev *dev)
 }
 EXPORT_SYMBOL_GPL(pci_liveupdate_unpreserve);
 
+static struct pci_flb_incoming *pci_liveupdate_flb_get_incoming(void)
+{
+	struct pci_flb_incoming *incoming = NULL;
+	int ret;
+
+	ret = liveupdate_flb_get_incoming(&pci_liveupdate_flb, (void **)&incoming);
+
+	/* Live Update is not enabled. */
+	if (ret == -EOPNOTSUPP)
+		return NULL;
+
+	/* Live Update is enabled, but there is no incoming FLB data. */
+	if (ret == -ENODATA)
+		return NULL;
+
+	/*
+	 * Live Update is enabled and there is incoming FLB data, but none of it
+	 * matches pci_liveupdate_flb.compatible.
+	 *
+	 * This could mean that no PCI FLB data was passed by the previous
+	 * kernel, but it could also mean the previous kernel used a different
+	 * compatibility string (i.e. a different ABI).
+	 */
+	if (ret == -ENOENT) {
+		pr_info_once("No incoming FLB matched %s\n", pci_liveupdate_flb.compatible);
+		return NULL;
+	}
+
+	/*
+	 * There is incoming FLB data that matches pci_liveupdate_flb.compatible
+	 * but it cannot be retrieved.
+	 */
+	if (ret) {
+		WARN_ONCE(ret, "Failed to retrieve incoming FLB data\n");
+		return NULL;
+	}
+
+	return incoming;
+}
+
+static void pci_liveupdate_flb_put_incoming(void)
+{
+	liveupdate_flb_put_incoming(&pci_liveupdate_flb);
+}
+
+void pci_liveupdate_setup_device(struct pci_dev *dev)
+{
+	struct pci_flb_incoming *incoming;
+	struct pci_dev_ser *dev_ser;
+	unsigned long key;
+
+	incoming = pci_liveupdate_flb_get_incoming();
+	if (!incoming)
+		return;
+
+	key = pci_ser_xa_key(pci_domain_nr(dev->bus), pci_dev_id(dev));
+	dev_ser = xa_load(&incoming->xa, key);
+
+	/* This device was not preserved across Live Update */
+	if (!dev_ser) {
+		pci_liveupdate_flb_put_incoming();
+		return;
+	}
+
+	/*
+	 * This device was preserved, but has already been probed and gone
+	 * through pci_liveupdate_finish(). This can happen if PCI core probes
+	 * the same device multiple times, e.g. due to hotplug.
+	 */
+	if (!dev_ser->refcount) {
+		pci_liveupdate_flb_put_incoming();
+		return;
+	}
+
+	pci_info(dev, "Device was preserved by previous kernel across Live Update\n");
+	guard(write_lock)(&dev->liveupdate.lock);
+	dev->liveupdate.incoming = dev_ser;
+
+	/*
+	 * Hold the ref on the incoming FLB until pci_liveupdate_finish() so
+	 * that dev->liveupdate.incoming does not get freed while it is in use.
+	 */
+}
+
+void pci_liveupdate_cleanup_device(struct pci_dev *dev)
+{
+	bool incoming;
+
+	scoped_guard(write_lock, &dev->liveupdate.lock)
+		incoming = !!xchg(&dev->liveupdate.incoming, NULL);
+
+	/*
+	 * Drop the FLB reference acquired in pci_liveupdate_setup_device() if
+	 * the device is being cleaned up before pci_liveupdate_finish(), e.g.
+	 * due to allocation failure during setup.
+	 *
+	 * Do not drop dev->liveupdate.incoming->refcount since this device has
+	 * not gone through pci_liveupdate_finish() and thus is still an
+	 * incoming preserved device.
+	 */
+	if (incoming)
+		pci_liveupdate_flb_put_incoming();
+}
+
+/**
+ * pci_liveupdate_finish() - Finish the preservation of a PCI device across Live Update
+ * @dev: The PCI device
+ *
+ * pci_liveupdate_finish() notifies the PCI core that a PCI device that was
+ * preserved across the previous Live Update has finished participating in Live
+ * Update. Drivers must call pci_liveupdate_finish() from their struct
+ * liveupdate_file_handler finish() callback to ensure the incoming struct
+ * pci_ser is allocated.
+ */
+void pci_liveupdate_finish(struct pci_dev *dev)
+{
+	guard(write_lock)(&dev->liveupdate.lock);
+
+	if (!dev->liveupdate.incoming) {
+		pci_warn(dev, "Cannot finish preserving an unpreserved device\n");
+		return;
+	}
+
+	pci_info(dev, "Device is finished participating in Live Update\n");
+
+	/*
+	 * Drop the refcount so this device does not get treated as an incoming
+	 * device again, e.g. in case pci_liveupdate_setup_device() gets called
+	 * again because the device is hot-plugged.
+	 */
+	dev->liveupdate.incoming->refcount = 0;
+	dev->liveupdate.incoming = NULL;
+
+	/* Drop this device's reference on the incoming FLB. */
+	pci_liveupdate_flb_put_incoming();
+}
+EXPORT_SYMBOL_GPL(pci_liveupdate_finish);
+
+/**
+ * pci_liveupdate_is_incoming() - Check if a device is incoming preserved
+ * @dev: The PCI device to check
+ *
+ * Check if a device was preserved across Live Update by the previous kernel,
+ * i.e. the device is incoming preserved. Note that a device is only considered
+ * incoming preserved prior to pci_liveupdate_finish(). It is up to drivers to
+ * synchronize usage of pci_liveupdate_is_incoming() with their own call to
+ * pci_liveupdate_finish() to avoid acting on stale data.
+ *
+ * Returns: True if the device is incoming preserved, false otherwise.
+ */
+bool pci_liveupdate_is_incoming(struct pci_dev *dev)
+{
+	guard(read_lock)(&dev->liveupdate.lock);
+	return dev->liveupdate.incoming;
+}
+EXPORT_SYMBOL_GPL(pci_liveupdate_is_incoming);
+
 /**
  * pci_liveupdate_register_flb() - Register a file handler with the PCI core
  * @fh: The file handler to register.
diff --git a/drivers/pci/liveupdate.h b/drivers/pci/liveupdate.h
new file mode 100644
index 000000000000..eaaa3559fd77
--- /dev/null
+++ b/drivers/pci/liveupdate.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PCI Live Update support (core API)
+ *
+ * Copyright (c) 2026, Google LLC.
+ * David Matlack <dmatlack@google.com>
+ */
+#ifndef DRIVERS_PCI_LIVEUPDATE_H
+#define DRIVERS_PCI_LIVEUPDATE_H
+
+#include <linux/pci.h>
+
+#ifdef CONFIG_PCI_LIVEUPDATE
+void pci_liveupdate_setup_device(struct pci_dev *dev);
+void pci_liveupdate_cleanup_device(struct pci_dev *dev);
+#else
+static inline void pci_liveupdate_setup_device(struct pci_dev *dev)
+{
+}
+
+static inline void pci_liveupdate_cleanup_device(struct pci_dev *dev)
+{
+}
+#endif
+
+#endif /* DRIVERS_PCI_LIVEUPDATE_H */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 54ae32cb0000..b5fdc5017f92 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -24,6 +24,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/bitfield.h>
 #include <trace/events/pci.h>
+#include "liveupdate.h"
 #include "pci.h"
 
 static struct resource busn_resource = {
@@ -2069,6 +2070,8 @@ int pci_setup_device(struct pci_dev *dev)
 	if (pci_early_dump)
 		early_dump_pci_device(dev);
 
+	pci_liveupdate_setup_device(dev);
+
 	/* Need to have dev->class ready */
 	dev->cfg_size = pci_cfg_space_size(dev);
 
@@ -2192,6 +2195,7 @@ int pci_setup_device(struct pci_dev *dev)
 	default:				    /* unknown header */
 		pci_err(dev, "unknown header type %02x, ignoring device\n",
 			dev->hdr_type);
+		pci_liveupdate_cleanup_device(dev);
 		pci_release_of_node(dev);
 		return -EIO;
 
@@ -2490,6 +2494,7 @@ static void pci_release_dev(struct device *dev)
 
 	pci_dev = to_pci_dev(dev);
 	pci_release_capabilities(pci_dev);
+	pci_liveupdate_cleanup_device(pci_dev);
 	pci_release_of_node(pci_dev);
 	pcibios_release_device(pci_dev);
 	pci_bus_put(pci_dev->bus);
diff --git a/include/linux/pci_liveupdate.h b/include/linux/pci_liveupdate.h
index 0803d44becd5..1c2ee32ad058 100644
--- a/include/linux/pci_liveupdate.h
+++ b/include/linux/pci_liveupdate.h
@@ -17,10 +17,12 @@
  * struct pci_liveupdate - PCI Live Update state for a struct pci_dev
  * @lock: Lock used to protect members of struct pci_liveupdate.
  * @outgoing: State preserved for the next kernel.
+ * @incoming: State preserved by the previous kernel.
  */
 struct pci_liveupdate {
 	rwlock_t lock;
 	struct pci_dev_ser *outgoing;
+	struct pci_dev_ser *incoming;
 };
 
 struct pci_dev;
@@ -30,6 +32,8 @@ int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh);
 void pci_liveupdate_unregister_flb(struct liveupdate_file_handler *fh);
 int pci_liveupdate_preserve(struct pci_dev *dev);
 void pci_liveupdate_unpreserve(struct pci_dev *dev);
+void pci_liveupdate_finish(struct pci_dev *dev);
+bool pci_liveupdate_is_incoming(struct pci_dev *dev);
 #else
 static inline int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh)
 {
@@ -48,6 +52,15 @@ static inline int pci_liveupdate_preserve(struct pci_dev *dev)
 static inline void pci_liveupdate_unpreserve(struct pci_dev *dev)
 {
 }
+
+static inline void pci_liveupdate_finish(struct pci_dev *dev)
+{
+}
+
+static inline bool pci_liveupdate_is_incoming(struct pci_dev *dev)
+{
+	return false;
+}
 #endif
 
 #endif /* LINUX_PCI_LIVEUPDATE_H */
-- 
2.54.0.563.g4f69b47b94-goog


^ permalink raw reply related

* [PATCH v5 02/11] PCI: liveupdate: Track outgoing preserved PCI devices
From: David Matlack @ 2026-05-12 18:48 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-mm, linux-pci
  Cc: Adithya Jayachandran, Alexander Graf, Alex Williamson,
	Bjorn Helgaas, Chris Li, David Matlack, David Rientjes, Jacob Pan,
	Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
	Lukas Wunner, Mike Rapoport, Parav Pandit, Pasha Tatashin,
	Pranjal Shrivastava, Pratyush Yadav, Saeed Mahameed,
	Samiullah Khawaja, Shuah Khan, Vipin Sharma, William Tu, Yi Liu
In-Reply-To: <20260512184846.119396-1-dmatlack@google.com>

Add APIs to allow drivers to notify the PCI core of which devices are
being preserved across a Live Update for the next kernel, i.e.
"outgoing" devices.

Drivers must notify the PCI core when devices are preserved so that the
PCI core can update its FLB data (struct pci_ser) and track the list of
outgoing devices. pci_liveupdate_preserve() notifies the PCI core that a
device must be preserved across Live Update. pci_liveupdate_unpreserve()
reverses this (cancels the preservation of the device).

This tracking ensures the PCI core is fully aware of which devices may
need special handling during shutdown and kexec, and so that it can be
handed off to the next kernel.

Signed-off-by: David Matlack <dmatlack@google.com>
---
 drivers/pci/liveupdate.c       | 167 ++++++++++++++++++++++++++++++---
 drivers/pci/probe.c            |   3 +
 include/linux/kho/abi/pci.h    |   9 +-
 include/linux/pci.h            |   3 +
 include/linux/pci_liveupdate.h |  23 +++++
 5 files changed, 191 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
index dd2449e12b6d..9c4582ecd55c 100644
--- a/drivers/pci/liveupdate.c
+++ b/drivers/pci/liveupdate.c
@@ -43,6 +43,26 @@
  *
  *  * ``pci_liveupdate_register_flb(driver_file_handler)``
  *  * ``pci_liveupdate_unregister_flb(driver_file_handler)``
+ *
+ * Device Tracking
+ * ===============
+ *
+ * Drivers must notify the PCI core when specific devices are preserved or
+ * unpreserved with the following APIs:
+ *
+ *  * ``pci_liveupdate_preserve(pci_dev)``
+ *  * ``pci_liveupdate_unpreserve(pci_dev)``
+ *
+ * This allows the PCI core to keep its FLB data (struct pci_ser) up to date
+ * with the list of **outgoing** preserved devices for the next kernel.
+ *
+ * Restrictions
+ * ============
+ *
+ * The PCI core enforces the following restrictions on which devices can be
+ * preserved. These may be relaxed in the future:
+ *
+ *  * The device cannot be a Virtual Function (VF).
  */
 
 #define pr_fmt(fmt) "PCI: liveupdate: " fmt
@@ -55,13 +75,29 @@
 #include <linux/mm.h>
 #include <linux/pci.h>
 
+/**
+ * struct pci_flb_outgoing - Outgoing PCI FLB object
+ * @ser: The outgoing struct pci_ser for the next kernel.
+ * @lock: Lock used to protect against changes to @ser.
+ */
+struct pci_flb_outgoing {
+	struct pci_ser *ser;
+	struct mutex lock;
+};
+
 static int pci_flb_preserve(struct liveupdate_flb_op_args *args)
 {
+	struct pci_flb_outgoing *outgoing;
 	struct pci_dev *dev = NULL;
 	u32 max_nr_devices = 0;
-	struct pci_ser *ser;
 	unsigned long size;
 
+	outgoing = kmalloc_obj(*outgoing);
+	if (!outgoing)
+		return -ENOMEM;
+
+	mutex_init(&outgoing->lock);
+
 	/*
 	 * Allocate enough space to preserve all of the devices that are
 	 * currently present on the system. Extra padding can be added to this
@@ -74,27 +110,30 @@ static int pci_flb_preserve(struct liveupdate_flb_op_args *args)
 
 	size = struct_size_t(struct pci_ser, devices, max_nr_devices);
 
-	ser = kho_alloc_preserve(size);
-	if (IS_ERR(ser))
-		return PTR_ERR(ser);
+	outgoing->ser = kho_alloc_preserve(size);
+	if (IS_ERR(outgoing->ser)) {
+		kfree(outgoing);
+		return PTR_ERR(outgoing->ser);
+	}
 
 	pr_debug("Preserved struct pci_ser with room for %u devices\n",
 		 max_nr_devices);
 
-	ser->max_nr_devices = max_nr_devices;
-	ser->nr_devices = 0;
+	outgoing->ser->max_nr_devices = max_nr_devices;
+	outgoing->ser->nr_devices = 0;
 
-	args->obj = ser;
-	args->data = virt_to_phys(ser);
+	args->obj = outgoing;
+	args->data = virt_to_phys(outgoing->ser);
 	return 0;
 }
 
 static void pci_flb_unpreserve(struct liveupdate_flb_op_args *args)
 {
-	struct pci_ser *ser = args->obj;
+	struct pci_flb_outgoing *outgoing = args->obj;
 
-	WARN_ON_ONCE(ser->nr_devices);
-	kho_unpreserve_free(ser);
+	WARN_ON_ONCE(outgoing->ser->nr_devices);
+	kho_unpreserve_free(outgoing->ser);
+	kfree(outgoing);
 
 	pr_debug("Unpreserved struct pci_ser\n");
 }
@@ -123,6 +162,112 @@ static struct liveupdate_flb pci_liveupdate_flb = {
 	.compatible = PCI_LUO_FLB_COMPATIBLE,
 };
 
+/**
+ * pci_liveupdate_preserve() - Preserve a PCI device across Live Update
+ * @dev: The PCI device to preserve.
+ *
+ * pci_liveupdate_preserve() notifies the PCI core that a PCI device should be
+ * preserved across the next Live Update. Drivers must call
+ * pci_liveupdate_preserve() from their struct liveupdate_file_handler
+ * preserve() callback to ensure the outgoing struct pci_ser is allocated.
+ *
+ * Returns: 0 on success, <0 on failure.
+ */
+int pci_liveupdate_preserve(struct pci_dev *dev)
+{
+	struct pci_flb_outgoing *outgoing = NULL;
+	struct pci_ser *ser;
+	int i, ret;
+
+	if (dev->is_virtfn)
+		return -EINVAL;
+
+	ret = liveupdate_flb_get_outgoing(&pci_liveupdate_flb, (void **)&outgoing);
+	if (ret)
+		return ret;
+
+	if (!outgoing)
+		return -ENOENT;
+
+	guard(mutex)(&outgoing->lock);
+	ser = outgoing->ser;
+
+	guard(write_lock)(&dev->liveupdate.lock);
+
+	if (dev->liveupdate.outgoing)
+		return -EBUSY;
+
+	if (ser->nr_devices == ser->max_nr_devices)
+		return -ENOSPC;
+
+	for (i = 0; i < ser->max_nr_devices; i++) {
+		/*
+		 * Start searching at index ser->nr_devices. This should result
+		 * in a constant time search under expected conditions (devices
+		 * are not getting unpreserved).
+		 */
+		int index = (ser->nr_devices + i) % ser->max_nr_devices;
+		struct pci_dev_ser *dev_ser = &ser->devices[index];
+
+		if (dev_ser->refcount)
+			continue;
+
+		pci_info(dev, "Device will be preserved across next Live Update\n");
+		ser->nr_devices++;
+
+		dev_ser->domain = pci_domain_nr(dev->bus);
+		dev_ser->bdf = pci_dev_id(dev);
+		dev_ser->refcount = 1;
+
+		dev->liveupdate.outgoing = dev_ser;
+		return 0;
+	}
+
+	return -ENOSPC;
+}
+EXPORT_SYMBOL_GPL(pci_liveupdate_preserve);
+
+/**
+ * pci_liveupdate_unpreserve() - Cancel preservation of a PCI device
+ * @dev: The PCI device to preserve.
+ *
+ * pci_liveupdate_unpreserve() notifies the PCI core that a PCI device should no
+ * longer be preserved across the next Live Update. Drivers must call
+ * pci_liveupdate_unpreserve() from their struct liveupdate_file_handler
+ * unpreserve() callback to ensure the outgoing struct pci_ser is allocated.
+ */
+void pci_liveupdate_unpreserve(struct pci_dev *dev)
+{
+	struct pci_flb_outgoing *outgoing = NULL;
+	struct pci_dev_ser *dev_ser;
+	struct pci_ser *ser;
+	int ret;
+
+	ret = liveupdate_flb_get_outgoing(&pci_liveupdate_flb, (void **)&outgoing);
+
+	if (ret || !outgoing) {
+		pci_warn(dev, "Cannot unpreserve device without outgoing Live Update state\n");
+		return;
+	}
+
+	guard(mutex)(&outgoing->lock);
+	ser = outgoing->ser;
+
+	guard(write_lock)(&dev->liveupdate.lock);
+
+	dev_ser = dev->liveupdate.outgoing;
+	if (!dev_ser) {
+		pci_warn(dev, "Cannot unpreserve device that is not preserved\n");
+		return;
+	}
+
+	pci_info(dev, "Device will no longer be preserved across next Live Update\n");
+	ser->nr_devices--;
+	memset(dev_ser, 0, sizeof(*dev_ser));
+	dev->liveupdate.outgoing = NULL;
+}
+EXPORT_SYMBOL_GPL(pci_liveupdate_unpreserve);
+
 /**
  * pci_liveupdate_register_flb() - Register a file handler with the PCI core
  * @fh: The file handler to register.
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b63cd0c310bc..54ae32cb0000 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2522,6 +2522,9 @@ struct pci_dev *pci_alloc_dev(struct pci_bus *bus)
 	spin_lock_init(&dev->pcie_cap_lock);
 #ifdef CONFIG_PCI_MSI
 	raw_spin_lock_init(&dev->msi_lock);
+#endif
+#ifdef CONFIG_PCI_LIVEUPDATE
+	rwlock_init(&dev->liveupdate.lock);
 #endif
 	return dev;
 }
diff --git a/include/linux/kho/abi/pci.h b/include/linux/kho/abi/pci.h
index 6ebcf817fff4..807fe0e6538f 100644
--- a/include/linux/kho/abi/pci.h
+++ b/include/linux/kho/abi/pci.h
@@ -23,19 +23,22 @@
  * incrementing the version number in the PCI_LUO_FLB_COMPATIBLE string.
  */
 
-#define PCI_LUO_FLB_COMPATIBLE "pci-v1"
+#define PCI_LUO_FLB_COMPATIBLE "pci-v2"
 
 /**
  * struct pci_dev_ser - Serialized state about a single PCI device.
  *
  * @domain: The device's PCI domain number (segment).
  * @bdf: The device's PCI bus, device, and function number.
- * @padding: Padding to naturally align struct pci_dev_ser.
+ * @refcount: Reference count used by the PCI core to keep track of whether it
+ *            is done using a device's struct pci_dev_ser. The value of the
+ *            refcount is equal to the number of devices preserved at or below
+ *            this device in the PCI hierarchy.
  */
 struct pci_dev_ser {
 	u32 domain;
 	u16 bdf;
-	u16 padding;
+	u16 refcount;
 } __packed;
 
 /**
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 8cadeeab86fd..a7c3722b1e77 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -594,6 +594,9 @@ struct pci_dev {
 	u8		tph_mode;	/* TPH mode */
 	u8		tph_req_type;	/* TPH requester type */
 #endif
+#ifdef CONFIG_PCI_LIVEUPDATE
+	struct pci_liveupdate liveupdate;
+#endif
 };
 
 static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
diff --git a/include/linux/pci_liveupdate.h b/include/linux/pci_liveupdate.h
index 8ec98beefcb4..0803d44becd5 100644
--- a/include/linux/pci_liveupdate.h
+++ b/include/linux/pci_liveupdate.h
@@ -8,14 +8,28 @@
 #ifndef LINUX_PCI_LIVEUPDATE_H
 #define LINUX_PCI_LIVEUPDATE_H
 
+#include <linux/kho/abi/pci.h>
 #include <linux/liveupdate.h>
 #include <linux/types.h>
+#include <linux/spinlock_types.h>
+
+/**
+ * struct pci_liveupdate - PCI Live Update state for a struct pci_dev
+ * @lock: Lock used to protect members of struct pci_liveupdate.
+ * @outgoing: State preserved for the next kernel.
+ */
+struct pci_liveupdate {
+	rwlock_t lock;
+	struct pci_dev_ser *outgoing;
+};
 
 struct pci_dev;
 
 #ifdef CONFIG_PCI_LIVEUPDATE
 int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh);
 void pci_liveupdate_unregister_flb(struct liveupdate_file_handler *fh);
+int pci_liveupdate_preserve(struct pci_dev *dev);
+void pci_liveupdate_unpreserve(struct pci_dev *dev);
 #else
 static inline int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh)
 {
@@ -25,6 +39,15 @@ static inline int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh
 static inline void pci_liveupdate_unregister_flb(struct liveupdate_file_handler *fh)
 {
 }
+
+static inline int pci_liveupdate_preserve(struct pci_dev *dev)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void pci_liveupdate_unpreserve(struct pci_dev *dev)
+{
+}
 #endif
 
 #endif /* LINUX_PCI_LIVEUPDATE_H */
-- 
2.54.0.563.g4f69b47b94-goog


^ permalink raw reply related

* [PATCH v5 01/11] PCI: liveupdate: Set up FLB handler for the PCI core
From: David Matlack @ 2026-05-12 18:48 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-mm, linux-pci
  Cc: Adithya Jayachandran, Alexander Graf, Alex Williamson,
	Bjorn Helgaas, Chris Li, David Matlack, David Rientjes, Jacob Pan,
	Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
	Lukas Wunner, Mike Rapoport, Parav Pandit, Pasha Tatashin,
	Pranjal Shrivastava, Pratyush Yadav, Saeed Mahameed,
	Samiullah Khawaja, Shuah Khan, Vipin Sharma, William Tu, Yi Liu
In-Reply-To: <20260512184846.119396-1-dmatlack@google.com>

Set up a File-Lifecycle-Bound (FLB) handler for the PCI core to enable
it to participate in the preservation of PCI devices across Live Update.
Essentially, this commit enables the PCI core to allocate a struct
(struct pci_ser) and preserve it across a Live Update whenever at least
one device is preserved.

Preserving PCI devices across Live Update is built on top of the Live
Update Orchestrator's (LUO) support for file preservation. Drivers are
expected to expose a file to userspace to represent a single PCI device
and support preservation of that file. This is intended primarily to
support preservation of PCI devices bound to VFIO drivers.

This commit enables drivers to register their liveupdate_file_handler
with the PCI core so that the PCI core can do its own tracking and
enforcement of which devices are preserved.

  pci_liveupdate_register_flb(driver_file_handler);
  pci_liveupdate_unregister_flb(driver_file_handler);

When the first file (with a handler registered with the PCI core) is
preserved, the PCI core will be notified to allocate its tracking struct
(pci_ser). When the last file is unpreserved (i.e. preservation
cancelled) the PCI core will be notified to free struct pci_ser.

This struct is preserved across a Live Update using KHO and can be
fetched by the PCI core during early boot (e.g. during device
enumeration) so that it knows which devices were preserved.

Note: This commit only allocates struct pci_ser and preserves it across
Live Update. A subsequent commit will add an API for drivers to tell the
PCI core exactly which devices are being preserved.

Note: There is no reason to check for kho_is_enabled() since it can be
assumed to return true. If KHO was not enabled then Live Update would
not be enabled and these routines would never run.

Signed-off-by: David Matlack <dmatlack@google.com>
---
 MAINTAINERS                    |  10 +++
 drivers/pci/Kconfig            |  14 +++
 drivers/pci/Makefile           |   1 +
 drivers/pci/liveupdate.c       | 153 +++++++++++++++++++++++++++++++++
 include/linux/kho/abi/pci.h    |  61 +++++++++++++
 include/linux/pci.h            |   1 +
 include/linux/pci_liveupdate.h |  30 +++++++
 7 files changed, 270 insertions(+)
 create mode 100644 drivers/pci/liveupdate.c
 create mode 100644 include/linux/kho/abi/pci.h
 create mode 100644 include/linux/pci_liveupdate.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 2fb1c75afd16..6c618830cf61 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20530,6 +20530,16 @@ L:	linux-pci@vger.kernel.org
 S:	Supported
 F:	Documentation/PCI/pci-error-recovery.rst
 
+PCI LIVE UPDATE
+M:	David Matlack <dmatlack@google.com>
+L:	kexec@lists.infradead.org
+L:	linux-pci@vger.kernel.org
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux.git
+F:	drivers/pci/liveupdate.c
+F:	include/linux/kho/abi/pci.h
+F:	include/linux/pci_liveupdate.h
+
 PCI MSI DRIVER FOR ALTERA MSI IP
 L:	linux-pci@vger.kernel.org
 S:	Orphan
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 33c88432b728..08398cbe970c 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -328,6 +328,20 @@ config VGA_ARB_MAX_GPUS
 	  Reserves space in the kernel to maintain resource locking for
 	  multiple GPUS.  The overhead for each GPU is very small.
 
+config PCI_LIVEUPDATE
+	bool "PCI Live Update Support (EXPERIMENTAL)"
+	depends on PCI && LIVEUPDATE
+	help
+	  Enable PCI core support for preserving PCI devices across Live
+	  Update. This, in combination with support in a device's driver,
+	  enables PCI devices to run and perform memory transactions
+	  uninterrupted during a kexec for Live Update.
+
+	  This option should only be enabled by developers working on
+	  implementing this support.
+
+	  If unsure, say N.
+
 source "drivers/pci/hotplug/Kconfig"
 source "drivers/pci/controller/Kconfig"
 source "drivers/pci/endpoint/Kconfig"
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 41ebc3b9a518..e8d003cb6757 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_PROC_FS)		+= proc.o
 obj-$(CONFIG_SYSFS)		+= pci-sysfs.o slot.o
 obj-$(CONFIG_ACPI)		+= pci-acpi.o
 obj-$(CONFIG_GENERIC_PCI_IOMAP) += iomap.o
+obj-$(CONFIG_PCI_LIVEUPDATE)	+= liveupdate.o
 endif
 
 obj-$(CONFIG_OF)		+= of.o
diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c
new file mode 100644
index 000000000000..dd2449e12b6d
--- /dev/null
+++ b/drivers/pci/liveupdate.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright (c) 2026, Google LLC.
+ * David Matlack <dmatlack@google.com>
+ */
+
+/**
+ * DOC: PCI Live Update
+ *
+ * The PCI subsystem participates in the Live Update process to enable drivers
+ * to preserve their PCI devices across kexec.
+ *
+ * .. note::
+ *    The support for preserving PCI devices across Live Update is currently
+ *    *partial* and should be considered *experimental*. It should only be
+ *    used by developers working on the implementation for the time being.
+ *
+ *    To enable the support, enable ``CONFIG_PCI_LIVEUPDATE``.
+ *
+ * File-Lifecycle-Bound (FLB) Data
+ * ===============================
+ *
+ * PCI device preservation across Live Update is built on top of the Live Update
+ * Orchestrator's (LUO) support for file preservation across kexec. Drivers
+ * are expected to expose a file to represent a single PCI device and support
+ * preservation of that file with ``ioctl(LIVEUPDATE_SESSION_PRESERVE_FD)``.
+ * This allows userspace to control the preservation of devices and ensure
+ * proper lifecycle management while a device is preserved. The first intended
+ * use-case is preserving vfio-pci device files.
+ *
+ * The PCI core maintains its own state about what devices are being preserved
+ * across Live Update using a feature called File-Lifecycle-Bound (FLB) data in
+ * LUO.  Essentially, this allows the PCI core to allocate struct pci_ser when
+ * the first device (file) is preserved and free it when the last device (file)
+ * is unpreserved. After kexec, the PCI core can fetch the struct pci_ser (which
+ * was constructed by the previous kernel) from LUO at any time (e.g. during
+ * enumeration) so that it knows which devices were preserved.
+ *
+ * To enable the PCI core to be notified whenever a file representing a device
+ * is preserved, drivers must register their struct liveupdate_file_handler with
+ * the PCI core by using the following APIs:
+ *
+ *  * ``pci_liveupdate_register_flb(driver_file_handler)``
+ *  * ``pci_liveupdate_unregister_flb(driver_file_handler)``
+ */
+
+#define pr_fmt(fmt) "PCI: liveupdate: " fmt
+
+#include <linux/io.h>
+#include <linux/kexec_handover.h>
+#include <linux/kho/abi/pci.h>
+#include <linux/liveupdate.h>
+#include <linux/mutex.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+
+static int pci_flb_preserve(struct liveupdate_flb_op_args *args)
+{
+	struct pci_dev *dev = NULL;
+	u32 max_nr_devices = 0;
+	struct pci_ser *ser;
+	unsigned long size;
+
+	/*
+	 * Allocate enough space to preserve all of the devices that are
+	 * currently present on the system. Extra padding can be added to this
+	 * in the future to increase the chances that there is enough room to
+	 * preserve devices that are not yet present on the system (e.g. VFs,
+	 * hot-plugged devices).
+	 */
+	for_each_pci_dev(dev)
+		max_nr_devices++;
+
+	size = struct_size_t(struct pci_ser, devices, max_nr_devices);
+
+	ser = kho_alloc_preserve(size);
+	if (IS_ERR(ser))
+		return PTR_ERR(ser);
+
+	pr_debug("Preserved struct pci_ser with room for %u devices\n",
+		 max_nr_devices);
+
+	ser->max_nr_devices = max_nr_devices;
+	ser->nr_devices = 0;
+
+	args->obj = ser;
+	args->data = virt_to_phys(ser);
+	return 0;
+}
+
+static void pci_flb_unpreserve(struct liveupdate_flb_op_args *args)
+{
+	struct pci_ser *ser = args->obj;
+
+	WARN_ON_ONCE(ser->nr_devices);
+	kho_unpreserve_free(ser);
+
+	pr_debug("Unpreserved struct pci_ser\n");
+}
+
+static int pci_flb_retrieve(struct liveupdate_flb_op_args *args)
+{
+	args->obj = phys_to_virt(args->data);
+	return 0;
+}
+
+static void pci_flb_finish(struct liveupdate_flb_op_args *args)
+{
+	kho_restore_free(args->obj);
+}
+
+static struct liveupdate_flb_ops pci_liveupdate_flb_ops = {
+	.preserve = pci_flb_preserve,
+	.unpreserve = pci_flb_unpreserve,
+	.retrieve = pci_flb_retrieve,
+	.finish = pci_flb_finish,
+	.owner = THIS_MODULE,
+};
+
+static struct liveupdate_flb pci_liveupdate_flb = {
+	.ops = &pci_liveupdate_flb_ops,
+	.compatible = PCI_LUO_FLB_COMPATIBLE,
+};
+
+/**
+ * pci_liveupdate_register_flb() - Register a file handler with the PCI core
+ * @fh: The file handler to register.
+ *
+ * Drivers should call pci_liveupdate_register_flb() to register their
+ * struct liveupdate_file_handler with the PCI core. This enables the PCI core
+ * to allocate its outgoing struct pci_ser whenever the first device is
+ * preserved, and free it when the last device is unpreserved.
+ *
+ * Return: 0 on success, <0 on failure.
+ */
+int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh)
+{
+	pr_debug("Registering file handler \"%s\"\n", fh->compatible);
+	return liveupdate_register_flb(fh, &pci_liveupdate_flb);
+}
+EXPORT_SYMBOL_GPL(pci_liveupdate_register_flb);
+
+/**
+ * pci_liveupdate_unregister_flb() - Unregister a file handler with the PCI core
+ * @fh: The file handler to unregister.
+ */
+void pci_liveupdate_unregister_flb(struct liveupdate_file_handler *fh)
+{
+	pr_debug("Unregistering file handler \"%s\"\n", fh->compatible);
+	liveupdate_unregister_flb(fh, &pci_liveupdate_flb);
+}
+EXPORT_SYMBOL_GPL(pci_liveupdate_unregister_flb);
diff --git a/include/linux/kho/abi/pci.h b/include/linux/kho/abi/pci.h
new file mode 100644
index 000000000000..6ebcf817fff4
--- /dev/null
+++ b/include/linux/kho/abi/pci.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * Copyright (c) 2026, Google LLC.
+ * David Matlack <dmatlack@google.com>
+ */
+
+#ifndef _LINUX_KHO_ABI_PCI_H
+#define _LINUX_KHO_ABI_PCI_H
+
+#include <linux/bug.h>
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+/**
+ * DOC: PCI File-Lifecycle Bound (FLB) Live Update ABI
+ *
+ * This header defines the ABI for preserving core PCI state across kexec using
+ * Live Update File-Lifecycle Bound (FLB) data.
+ *
+ * This interface is a contract. Any modification to any of the serialization
+ * structs defined here constitutes a breaking change. Such changes require
+ * incrementing the version number in the PCI_LUO_FLB_COMPATIBLE string.
+ */
+
+#define PCI_LUO_FLB_COMPATIBLE "pci-v1"
+
+/**
+ * struct pci_dev_ser - Serialized state about a single PCI device.
+ *
+ * @domain: The device's PCI domain number (segment).
+ * @bdf: The device's PCI bus, device, and function number.
+ * @padding: Padding to naturally align struct pci_dev_ser.
+ */
+struct pci_dev_ser {
+	u32 domain;
+	u16 bdf;
+	u16 padding;
+} __packed;
+
+/**
+ * struct pci_ser - PCI Subsystem Live Update State
+ *
+ * This struct tracks state about all devices that are being preserved across
+ * a Live Update for the next kernel.
+ *
+ * @max_nr_devices: The length of the devices[] flexible array.
+ * @nr_devices: The number of devices that were preserved.
+ * @devices: Flexible array of pci_dev_ser structs for each device.
+ */
+struct pci_ser {
+	u32 max_nr_devices;
+	u32 nr_devices;
+	struct pci_dev_ser devices[];
+} __packed;
+
+/* Ensure all elements of devices[] are naturally aligned. */
+static_assert(offsetof(struct pci_ser, devices) % sizeof(unsigned long) == 0);
+static_assert(sizeof(struct pci_dev_ser) % sizeof(unsigned long) == 0);
+
+#endif /* _LINUX_KHO_ABI_PCI_H */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 2c4454583c11..8cadeeab86fd 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -42,6 +42,7 @@
 #include <uapi/linux/pci.h>
 
 #include <linux/pci_ids.h>
+#include <linux/pci_liveupdate.h>
 
 #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY  | \
 			       PCI_STATUS_SIG_SYSTEM_ERROR | \
diff --git a/include/linux/pci_liveupdate.h b/include/linux/pci_liveupdate.h
new file mode 100644
index 000000000000..8ec98beefcb4
--- /dev/null
+++ b/include/linux/pci_liveupdate.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PCI Live Update support (Public/Driver API)
+ *
+ * Copyright (c) 2026, Google LLC.
+ * David Matlack <dmatlack@google.com>
+ */
+#ifndef LINUX_PCI_LIVEUPDATE_H
+#define LINUX_PCI_LIVEUPDATE_H
+
+#include <linux/liveupdate.h>
+#include <linux/types.h>
+
+struct pci_dev;
+
+#ifdef CONFIG_PCI_LIVEUPDATE
+int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh);
+void pci_liveupdate_unregister_flb(struct liveupdate_file_handler *fh);
+#else
+static inline int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline void pci_liveupdate_unregister_flb(struct liveupdate_file_handler *fh)
+{
+}
+#endif
+
+#endif /* LINUX_PCI_LIVEUPDATE_H */
-- 
2.54.0.563.g4f69b47b94-goog


^ permalink raw reply related

* [PATCH v5 00/11] PCI: liveupdate: PCI core support for Live Update
From: David Matlack @ 2026-05-12 18:48 UTC (permalink / raw)
  To: kexec, linux-doc, linux-kernel, linux-mm, linux-pci
  Cc: Adithya Jayachandran, Alexander Graf, Alex Williamson,
	Bjorn Helgaas, Chris Li, David Matlack, David Rientjes, Jacob Pan,
	Jason Gunthorpe, Jonathan Corbet, Josh Hilke, Leon Romanovsky,
	Lukas Wunner, Mike Rapoport, Parav Pandit, Pasha Tatashin,
	Pranjal Shrivastava, Pratyush Yadav, Saeed Mahameed,
	Samiullah Khawaja, Shuah Khan, Vipin Sharma, William Tu, Yi Liu

This series can be found on GitHub:

  https://github.com/dmatlack/linux/tree/liveupdate/pci/base/v5

This patch series introduces the initial support in the PCI core for
Live Update, enabling drivers to preserve PCI devices across a
kexec-based kernel update without interrupting the device. This
functionality is critical for minimizing downtime in environments where
PCI devices (e.g., those assigned to VMs via VFIO) must continue
operating or maintain state across a host kernel upgrade.

Specifically, this patch series allows preserved PCI devices to perform
memory transactions to/from system memory (DMA) uninterrupted across a
Live Update. The devices can be behind a bridge, but must not be a VF.
Support for P2P and preserving VFs will come in future series.

Series Overview
---------------

This series implements the following to support PCI device preservation
across Live Update:

  1. Set up a File-Lifecycle-Bound (FLB) handler to track and preserve
     PCI-specific state (struct pci_ser) across Live Update using Kexec
     Handover (KHO).

  2. Add APIs for drivers to register "outgoing" devices for
     preservation and for the PCI core to identify "incoming" preserved
     devices during enumeration.

  3. Automatically preserve all upstream bridges for any preserved
     endpoint. Use reference counting to ensure bridges remain preserved
     as long as any downstream device is preserved.

  4. Guarantee that preserved devices can be identified by the same
     RequesterID (bus, device, function) for as long as they are
     preserved by always inheriting secondary and subordinate bus
     numbers and ARI Forwarding Enable on bridges with preserved
     downstream endpoints.

  5. Guarantee the memory transactions to/from preserved devices are
     routed the same way by inheriting Access Control Services (ACS)
     flags across a Live Update.

  6. Modify the PCI shutdown path to avoid disabling bus mastering on
     preserved devices and their upstream bridges, allowing memory
     transactions to continue uninterrupted.

  7. Provide comprehensive documentation for the FLB API, device
     tracking mechanisms, and the division of responsibilities between
     the PCI core, drivers, and userspace.

Dependencies
------------

This series is built on top of the next branch of liveupdate.git tree
which has 2 commits to enable refcounting the incoming FLB:

  https://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux.git/log/?h=next

Testing
-------

This series was tested in conjunction with v4 of the VFIO PCI driver
series:

  https://lore.kernel.org/kvm/20260511234802.2280368-1-vipinsh@google.com/

The full set of patches that I used for testing can be found on GitHub:

  https://github.com/dmatlack/linux/tree/liveupdate/pci/base/v5-with-vfio

The full set of patches was tested using the new VFIO selftests:

  - vfio_pci_liveupdate_uapi_test
  - vfio_pci_liveupdate_kexec_test

Both tests were ran in ran in a QEMU-based VM environment, using a
single virtio-net PCIe device connected to a root port (to exercise the
bridge support in this series), and in a baremetal environment on an
Intel EMR server, using 8x Intel DSA PCIe devices (each on a host
bridge) and 1x NVMe device connected to a root port.

Future Work
-----------

After this series we expect to make further improvements to the PCI core
support for Live Update.

  - Allow P2P across Live Update by avoiding sizing or moving preserved
    device BARs and preserving all upstream bridge windows.

  - Support preserving Virtual Functions, by preserving SR-IOV
    configuration on PFs and enumerating VFs after Live Update.

Changelog
---------

v5:
 - Update PCI LIVE UPDATE entry in MAINTAINERS to use liveupdate.git,
   add kexec@ mailing list, and drop Bjorn (Pasha, Bjorn, Pratyush)
 - Create separate headers for Live Update definitions to avoid future
   patch conflicts (me)
 - Add kernel doc for public (Driver) API (me)
 - Rename reserved field to padding (Vipin)
 - Reorder checks outside of mutex where possible (Jacob)
 - Clarify refcount in struct pci_dev_ser in kernel-doc (Sami)
 - Require CONFIG_64BIT to avoid overflowing xarray key (Sashiko)
 - Various spelling and grammar fixes (Bjorn)
 - Ensure incoming and outgoing devices do not have their bus numbers
   changed during manual rescans via sysfs (Jacob)
 - Fix refcount dropping for upstream bridges during finish (Sashiko)
 - Disallow devices with PCI_DEV_FLAGS_ACS_ENABLED_QUIRK to simplify
   ACS inheritence across Live Update (Sashiko)
 - Fix ACS re-enablement via pci_restore_state() (Sashiko)
 - Drop commit that requires singleton iommu groups (me, Sami)
 - Add per-device lock to protect Live Update fields (Sami, Sashiko)

v4: https://lore.kernel.org/linux-pci/20260423212316.3431746-1-dmatlack@google.com/
v3: https://lore.kernel.org/kvm/20260323235817.1960573-1-dmatlack@google.com/
v2: https://lore.kernel.org/kvm/20260129212510.967611-1-dmatlack@google.com/
v1: https://lore.kernel.org/kvm/20251126193608.2678510-1-dmatlack@google.com/
rfc: https://lore.kernel.org/kvm/20251018000713.677779-1-vipinsh@google.com/


David Matlack (11):
  PCI: liveupdate: Set up FLB handler for the PCI core
  PCI: liveupdate: Track outgoing preserved PCI devices
  PCI: liveupdate: Track incoming preserved PCI devices
  PCI: liveupdate: Document driver binding responsibilities
  PCI: liveupdate: Keep bus numbers constant during Live Update
  PCI: liveupdate: Auto-preserve upstream bridges across Live Update
  PCI: liveupdate: Inherit ACS flags in incoming preserved devices
  PCI: liveupdate: Inherit ARI Forwarding Enable on preserved bridges
  PCI: liveupdate: Freeze preservation status during shutdown
  PCI: liveupdate: Do not disable bus mastering on preserved devices
    during kexec
  Documentation: PCI: Add documentation for Live Update

 Documentation/PCI/index.rst                   |   1 +
 Documentation/PCI/liveupdate.rst              |  29 +
 .../admin-guide/kernel-parameters.txt         |   6 +-
 Documentation/core-api/liveupdate.rst         |   1 +
 MAINTAINERS                                   |  12 +
 drivers/pci/Kconfig                           |  14 +
 drivers/pci/Makefile                          |   1 +
 drivers/pci/liveupdate.c                      | 807 ++++++++++++++++++
 drivers/pci/liveupdate.h                      |  66 ++
 drivers/pci/pci-driver.c                      |  33 +-
 drivers/pci/pci.c                             |  13 +-
 drivers/pci/probe.c                           |  29 +-
 include/linux/kho/abi/pci.h                   |  64 ++
 include/linux/pci.h                           |   4 +
 include/linux/pci_liveupdate.h                |  75 ++
 15 files changed, 1140 insertions(+), 15 deletions(-)
 create mode 100644 Documentation/PCI/liveupdate.rst
 create mode 100644 drivers/pci/liveupdate.c
 create mode 100644 drivers/pci/liveupdate.h
 create mode 100644 include/linux/kho/abi/pci.h
 create mode 100644 include/linux/pci_liveupdate.h


base-commit: 34e8f02817e31826e76bb2ded48bf28fe921f20b
-- 
2.54.0.563.g4f69b47b94-goog


^ permalink raw reply

* Re: [RFC net-next 0/4] devlink: Add boot-time defaults
From: Jiri Pirko @ 2026-05-12 18:35 UTC (permalink / raw)
  To: Parav Pandit
  Cc: Mark Bloch, Jakub Kicinski, Eric Dumazet, Paolo Abeni,
	Andrew Lunn, David S. Miller, Jonathan Corbet, Shuah Khan,
	Simon Horman, Saeed Mahameed, Leon Romanovsky, Tariq Toukan,
	Andrew Morton, Borislav Petkov (AMD), Randy Dunlap, Dave Hansen,
	Christian Brauner, Petr Mladek, Peter Zijlstra (Intel),
	Thomas Gleixner, Pawan Gupta, Dapeng Mi, Kees Cook, Marco Elver,
	Eric Biggers, NBU-Contact-Li Rongqing (EXTERNAL),
	Paul E. McKenney, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	linux-rdma@vger.kernel.org
In-Reply-To: <SJ0PR12MB6806D8ADF943B30AD3B479CCDC392@SJ0PR12MB6806.namprd12.prod.outlook.com>

Tue, May 12, 2026 at 05:25:21PM CEST, parav@nvidia.com wrote:
>
>
>> From: Jiri Pirko <jiri@resnulli.us>
>> Sent: 12 May 2026 07:37 PM
>> 
>> Tue, May 12, 2026 at 03:48:32PM CEST, parav@nvidia.com wrote:
>> >
>> >> From: Jiri Pirko <jiri@resnulli.us>
>> >> Sent: 12 May 2026 02:16 PM
>> >>
>> >> Mon, May 11, 2026 at 08:21:37PM +0200, parav@nvidia.com wrote:
>> >> >
>> >> >> From: Mark Bloch <mbloch@nvidia.com>
>> >> >> Sent: 10 May 2026 06:02 PM
>> >> >>
>> >> >
>> >> >[..]
>> >> >
>> >> >> > I look at it from the perspective that from some CX generation,
>> >> >> > switchdev mode should be default. So that is a device-based decision.
>> >> >> > I believe as such it can optionally be permanenty configured (nv config)
>> >> >> > on older device. Why not?
>> >> >>
>> >> >Because sometimes switchdev_inactive is needed and sometimes not.
>> >> >Such knob is not device decision.
>> >>
>> >> That is what I would call corner case. In that, user can use userspace
>> >> configuration to change the mode in runtime.
>> >>
>> >Corner vs common depends on users one talks to. :)
>> >If fw has switchdev(active) as default, and then
>> >And user needs to run switchdev_inactive, it will actually break their switching applications.
>> 
>> Can you describe the actutal breakage please?
>> 
>Driver default was switchdev so all the traffic is forwarded to the switch,
>and user didn't have chance to setup the fdb rules.
>So packets are dropped but user didn't expect the traffic to be forwarded.

User may switch mode to switchdev_inactive early on, before any of the
representors are created. What's the issue then?


>
>With this RFC, the device would start in the switchdev_inactive.
>And user's goal is achieved.
>
>> >
>> >So, one needs to invent switchdev_inactive in the FW.
>> >
>> >Jakub's suggestion in this RFC is covering both the scenarios uniformly without above problems.
>> >Single uapi for all the cases, so looks good to me.
>> >
>> >Moreover, do not understand how alternative solves such problems.
>> >i.e. user is unable to configure the fw because driver is not yet loaded/up.
>> 
>> See my other reply in this thread. I don't think there is a need to
>> configure anything in FW. If we fix the behaviour in switchdev mode for
>> non-sriov user and change the default, no fw knob needed. What am I
>> missing?
>> 
>If I understood your suggestion right, is it the devlinkd based solution?

The suggestion is to use "switchdev" as default with user configuration
no matter if it is devlinkd or something else.


>
>If yes, then Mark explained that it has the issue of all drivers to be loaded, followed by user space to start.

^ permalink raw reply

* Re: [PATCH RFC v4 01/10] dt-bindings: iio: frequency: add ad9910
From: Jonathan Cameron @ 2026-05-12 18:31 UTC (permalink / raw)
  To: Rodrigo Alencar via B4 Relay
  Cc: rodrigo.alencar, linux-iio, devicetree, linux-kernel, linux-doc,
	linux-hardening, Lars-Peter Clausen, Michael Hennerich,
	David Lechner, Andy Shevchenko, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Philipp Zabel, Jonathan Corbet, Shuah Khan,
	Kees Cook, Gustavo A. R. Silva
In-Reply-To: <20260508-ad9910-iio-driver-v4-1-d26bfd20ee3d@analog.com>

On Fri, 08 May 2026 18:00:17 +0100
Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org> wrote:

> From: Rodrigo Alencar <rodrigo.alencar@analog.com>
> 
> DT-bindings for AD9910, a 1 GSPS DDS with 14-bit DAC. It includes
> configurations for clocks, DAC current, reset and basic GPIO control.

I think this is getting close enough now that for next version you should
drop the RFC (which is probably gating DT binding folk giving it
a detailed review!)

> 
> Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>

> +
> +  adi,dac-output-current-microamp:
> +    minimum: 8640
> +    maximum: 31590
> +    default: 20070
> +    description:
> +      DAC full-scale output current in microamps.
> +
Can we use generic dac.yaml defined output-range-microamp? The base will be 0 always but
that shouldn't matter.


^ permalink raw reply

* Re: [PATCH v12 02/11] lib: kstrtox: add kstrtoudec64() and kstrtodec64()
From: Rodrigo Alencar @ 2026-05-12 18:15 UTC (permalink / raw)
  To: Andy Shevchenko, Rodrigo Alencar
  Cc: Andy Shevchenko, Jonathan Cameron, Rodrigo Alencar via B4 Relay,
	rodrigo.alencar, linux-kernel, linux-iio, devicetree, linux-doc,
	David Lechner, Andy Shevchenko, Lars-Peter Clausen,
	Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jonathan Corbet, Andrew Morton, Petr Mladek, Steven Rostedt,
	Rasmus Villemoes, Sergey Senozhatsky, Shuah Khan, David Laight
In-Reply-To: <agNnfWZa9_NyLoWq@ashevche-desk.local>

On 26/05/12 08:46PM, Andy Shevchenko wrote:
> On Tue, May 12, 2026 at 06:26:12PM +0100, Rodrigo Alencar wrote:
> > On 26/05/12 08:13PM, Andy Shevchenko wrote:
> > > On Tue, May 12, 2026 at 05:35:59PM +0100, Rodrigo Alencar wrote:
> > > > On 26/05/12 06:21PM, Andy Shevchenko wrote:
> > > > > On Tue, May 12, 2026 at 6:11 PM Rodrigo Alencar
> > > > > <455.rodrigo.alencar@gmail.com> wrote:
> > > > > > On 26/05/12 05:43PM, Andy Shevchenko wrote:
> > > > > > > On Tue, May 12, 2026 at 03:12:24PM +0100, Rodrigo Alencar wrote:
> > > > > > > > On 26/05/12 04:48PM, Andy Shevchenko wrote:
> > > > > > > > > On Tue, May 12, 2026 at 02:21:14PM +0100, Rodrigo Alencar wrote:
> > > > > > > > > > On 26/05/12 04:12PM, Andy Shevchenko wrote:
> > > > > > > > > > > On Tue, May 12, 2026 at 12:39:53PM +0100, Jonathan Cameron wrote:
> > > > > > > > > > > > On Sun, 10 May 2026 13:42:20 +0100
> > > > > > > > > > > > Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org> wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > > Add helpers that parses decimal numbers into 64-bit number, i.e., decimal
> > > > > > > > > > > > > point numbers with pre-defined scale are parsed into a 64-bit value (fixed
> > > > > > > > > > > > > precision). After the decimal point, digits beyond the specified scale
> > > > > > > > > > > > > are ignored.

...

> > > > > > I think we are going in circles here and we could look at the code instead:
> > > > > > - integer parsing with _parse_integer()
> > > > > >         - overflow check and validation of the return value
> > > > > > - fractional parsing with _parse_integer_limit()
> > > > > >         - overflow check and validation of the return value
> > > > > 
> > > > > No, this is not fully true. That's what my whole point is about. The
> > > > > max_chars parameter limits the input check, then it skips an arbitrary
> > > > > number of digits and only *then* it checks for \n and \0. What will be
> > > > > the result of the
> > > > > 0.00000000000000000000000000000000423 in your case? Whatever scale you
> > > > > gave it will return 0 without checking on how many digits were
> > > > > supplied.
> > > > 
> > > > I suppose that is a valid input and 0 is the expected result there.
> > > > 
> > > > > All the same for 0.9999999999999999999999999999999000423. My
> > > > > point is that we should limit this by 19 digits.
> > > > 
> > > > why we need to limit by 19? Digits beyond the scale carry no value...
> > > 
> > > ...only if they are all 0:s.
> > 
> > I thought your concern was on input length.
> 
> One of, since I think you rose the topic of leading 0:s for integers and
> I agreed with that which makes sense to have mirrored in fractional part.
> 
> > > > just like leading zeros to the integer part (which is also accepted by
> > > > kstrtoull() when parsing with base 10). Not sure why this is invalid input.
> > > 
> > > See above. I agree on truncating trailing 0:s as it's done for leading ones
> > > in integer part, but if any of the digit behind 19th is not 0, it's an overflow
> > > condition (or bad input, depending how strict the rules are).
> > 
> > stating in the documentation that digits beyond the scale are ignored is not
> > enough?
> 
> It's in case we are not for kstrto*() family. My understanding that kstrto*()
> use strict rules on the input in overflow check.
> 
> > > > > On top of that, what about -0.9(19 times) ? the fraction should be u64
> > > > > in this case and it's fine. The sign applies to the combined value.
> > > > 
> > > > yes, range for signed values are verified later.
> > > 
> > > > > >         - extra scaling and truncation happening outside if needed.
> > > > > 
> > > > > Right, but the given input may be way too long and still needs more validation.
> > > > 
> > > > What is the problem with a long input of digits?
> > > > C compiler does not complain about this when parsing a float value,
> > > > python does not
> > > > complain about this when parsing floats or decimals either.
> > > 
> > > Because there is an exponent limit and for double it's something like 1e307
> > > IIRC, meaning, try 1024 digits to be sure.
> > > 
> > > Python most likely uses the library for big numbers, you can't compare it at all with this.
> > 
> > You would be fine if the truncation loop:
> > 
> > while (isdigit(*s)) /* truncate */
> > 	s++;
> > 
> > is bounded by (19-scale) iteration count? or it should keep iterating if those are zero?
> 
> Ideally both.
> 
> We don't care about the digits in the range of 19-scale and skip all 0:s after
> that.
> 
> 	/* truncate unrequired digits within type limit, i.e. 19 decimal digits */
> 	while (isdigit(*s) && "(s - pos_of_dot) is less than 19")
> 		s++;
> 	while (s == '0') /* truncate trailing 0:s, it's not a bad input nor overflow */
> 		s++;

We could have agreed on something like that since the beginning!
And I think that changing the logic to something like this would not change a
thing on the kind of inputs we expect, it will just complicate the code.
I suppose that kind of kstrto*() rules were never stated anywhere.

                           |> 20th digit 
Also, 0.00000000000000000001 still sounds like a valid decimal number to me, even
though it is going to be parsed as 0!

> 
> 	// Now if it's not \0 nor \n and
> 	//	a) still a digit consider either overflow or bad input,
> 	//	b) if not a digit, consider as bad input.
> 
> In a) I tend to be on par with the other k*() and consider that as overflow.
> 
> > is that the only concern? Again, the usage of _parse_integer_limit(s, 10, &_frac, scale)
> > avoids a 64-bit division when checking the rv.
> 
> I'm not against usage of _parse_integer_limit(), I'm for stricter rules on the input.
> With the above addressed, I have no more concerns.

Thanks! I will proceed with the requested adjustments.

...

-- 
Kind regards,

Rodrigo Alencar

^ permalink raw reply

* Re: [PATCH v2 12/14] userfaultfd: add UFFDIO_SET_MODE for runtime sync/async toggle
From: Mike Rapoport @ 2026-05-12 18:11 UTC (permalink / raw)
  To: Kiryl Shutsemau (Meta)
  Cc: akpm, peterx, david, ljs, surenb, vbabka, Liam.Howlett, ziy,
	corbet, skhan, seanjc, pbonzini, jthoughton, aarcange, sj,
	usama.arif, linux-mm, linux-kernel, linux-doc, linux-kselftest,
	kvm, kernel-team
In-Reply-To: <e8f142c530b715c6d45475230c4e35a1cfd8dbd4.1778254670.git.kas@kernel.org>

On Fri, May 08, 2026 at 04:55:24PM +0100, Kiryl Shutsemau (Meta) wrote:
> Add an ioctl to toggle async mode at runtime without re-registering
> the userfaultfd. This allows a VMM to switch between sync and async
> RWP modes on-the-fly -- for example, starting in async mode for
> working set scanning, then switching to sync mode to intercept faults
> during page eviction.
> 
> UFFDIO_SET_MODE takes an enable/disable bitmask of UFFD_FEATURE_*
> flags. Only UFFD_FEATURE_RWP_ASYNC is toggleable today; the ioctl
> rejects any other bit with -EINVAL. Enabling RWP_ASYNC also requires
> RWP to have been negotiated at UFFDIO_API time, mirroring the
> UFFDIO_API invariant.
> 
> Fault-path readers of ctx->features run under mmap_read_lock or a
> per-VMA lock; the RMW takes mmap_write_lock and calls
> vma_start_write() on every UFFD-armed VMA, so those readers are fully
> excluded. userfaultfd_show_fdinfo(), however, reads ctx->features
> without any lock, so the RMW is written as a single WRITE_ONCE and
> fdinfo reads it with READ_ONCE. That keeps the lockless observer from
> seeing a mid-RMW intermediate and removes the audit burden when new
> toggleable bits are added later.
> 
> When switching to async, pending sync waiters are woken so they retry
> and auto-resolve under the new mode.
> 
> Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
> Assisted-by: Claude:claude-opus-4-6

Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>

> ---
>  fs/userfaultfd.c                 | 150 +++++++++++++++++++++++++------
>  include/uapi/linux/userfaultfd.h |  14 +++
>  2 files changed, 136 insertions(+), 28 deletions(-)

-- 
Sincerely yours,
Mike.

^ permalink raw reply

* Re: [PATCH RFC v3 0/3] Add splash DRM client
From: Francesco Valla @ 2026-05-12 17:41 UTC (permalink / raw)
  To: Mario Limonciello
  Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
	Simona Vetter, Jonathan Corbet, Jocelyn Falempe,
	Javier Martinez Canillas, Shuah Khan, Sam Ravnborg, linux-kernel,
	dri-devel, linux-doc, linux-embedded
In-Reply-To: <5d7067de-97b7-4232-9cf6-e4b978696482@amd.com>

Hello Mario,

Thank you for taking a stab at this.

On Mon, May 11, 2026 at 08:59:14PM -0500, Mario Limonciello wrote:
> 
> 
> On 5/10/26 16:29, Francesco Valla wrote:
> > Hello,
> > 
> > this is the third (and hopefully last) RFC version for the DRM-based
> > splash screen.
> > 
> > Motivation behind the work can be found in v1 [0]; in a nutshell, the
> > splash DRM client can draw a splashscreen using:
> > 
> >    - the BMP image supplied by the EFI BGRT;
> >    - a BMP image loaded as firmware (either built-in or loaded from the
> >      filesystem);
> >    - a colored background.
> > 
> > This revision greatly simplifies the image seletion logic; now the EFI
> > BGRT is always used as first source if enabled, with a fallback to BMP
> > image loaded as firmware and then to a plain color.
> > 
> > Sanity checks on the EFI BGRT image have been borrowed from the efifb
> > driver. More complete splash providers (e.g.: Plymouth) have an
> > extensive management of platform-specific quirks, but I don't think it
> > would be reasonable to introduce such complexity here.
> > 
> > Additional notes:
> >    - Rotation is still not managed (and probably won't?).
> >    - Support for tiled screens is untested.
> >    - Plain color and BMP sources were tested on QEMU, Beagleplay and
> >      i.MX93 FRDM.
> >    - EFI BGRT support was tested using QEMU+OVMF.
> > 
> > Thank you in advance for any feedback.
> 
> Unfortunately I found that I couldn't compile with my normal Kconfig.
> 
> ERROR: modpost: "bgrt_tab" [drivers/gpu/drm/clients/drm_client_lib.ko]
> undefined!
> ERROR: modpost: "bgrt_image_size"
> [drivers/gpu/drm/clients/drm_client_lib.ko] undefined!
> make[2]: *** [scripts/Makefile.modpost:147: Module.symvers] Error 1
> make[1]: *** [/home/supermario/src/linux/Makefile:2091: modpost] Error 2
> make: *** [Makefile:248: __sub-make] Error 2
> 
> ❮ grep ^CONFIG_DRM .config
> CONFIG_DRM=y
> CONFIG_DRM_KMS_HELPER=m
> CONFIG_DRM_DRAW=y
> CONFIG_DRM_CLIENT=y
> CONFIG_DRM_CLIENT_LIB=m

Here lies the source of the issue, since I forgot to export the BGRT
table symbols. In my test setup I had the clients built-in and didn't
catch this. A simple patch (which will be included in v4) is attached.

> CONFIG_DRM_CLIENT_SELECTION=m
> CONFIG_DRM_CLIENT_SETUP=y
> CONFIG_DRM_FBDEV_EMULATION=y
> CONFIG_DRM_FBDEV_OVERALLOC=100
> CONFIG_DRM_CLIENT_SPLASH=y
> CONFIG_DRM_CLIENT_SPLASH_BACKGROUND_COLOR=0x000000
> CONFIG_DRM_CLIENT_SPLASH_SRC_BGRT=y
> CONFIG_DRM_CLIENT_SPLASH_BMP_SUPPORT=y
> CONFIG_DRM_CLIENT_DEFAULT_SPLASH=y
> CONFIG_DRM_CLIENT_DEFAULT="splash"
> CONFIG_DRM_LOAD_EDID_FIRMWARE=y
> CONFIG_DRM_DISPLAY_HELPER=m
> CONFIG_DRM_DISPLAY_DP_AUX_CHARDEV=y
> CONFIG_DRM_DISPLAY_DP_HELPER=y
> CONFIG_DRM_DISPLAY_DSC_HELPER=y
> CONFIG_DRM_DISPLAY_HDCP_HELPER=y
> CONFIG_DRM_DISPLAY_HDMI_CEC_NOTIFIER_HELPER=y
> CONFIG_DRM_DISPLAY_HDMI_HELPER=y
> CONFIG_DRM_TTM=m
> CONFIG_DRM_EXEC=m
> CONFIG_DRM_BUDDY=m
> CONFIG_DRM_TTM_HELPER=m
> CONFIG_DRM_GEM_SHMEM_HELPER=m
> CONFIG_DRM_SUBALLOC_HELPER=m
> CONFIG_DRM_SCHED=m
> CONFIG_DRM_PANEL_BACKLIGHT_QUIRKS=m
> CONFIG_DRM_PRIVACY_SCREEN=y
> CONFIG_DRM_AMDGPU=m
> CONFIG_DRM_AMDGPU_CIK=y
> CONFIG_DRM_AMDGPU_USERPTR=y
> CONFIG_DRM_AMD_ISP=y
> CONFIG_DRM_AMD_ACP=y
> CONFIG_DRM_AMD_DC=y
> CONFIG_DRM_AMD_DC_FP=y
> CONFIG_DRM_AMD_SECURE_DISPLAY=y
> CONFIG_DRM_BRIDGE=y
> CONFIG_DRM_PANEL_BRIDGE=y
> CONFIG_DRM_PANEL=y
> CONFIG_DRM_SYSFB_HELPER=m
> CONFIG_DRM_SIMPLEDRM=m
> CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
> CONFIG_DRM_ACCEL=y
> CONFIG_DRM_ACCEL_AMDXDNA=m
> CONFIG_DRM_ACCEL_HABANALABS=m
> CONFIG_DRM_ACCEL_IVPU=m
> CONFIG_DRM_ACCEL_QAIC=m
> ❮ grep BGRT .config
> CONFIG_ACPI_BGRT=y
> CONFIG_DRM_CLIENT_SPLASH_SRC_BGRT=y
>

Regards,
Francesco

---
 drivers/firmware/efi/efi-bgrt.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/firmware/efi/efi-bgrt.c b/drivers/firmware/efi/efi-bgrt.c
index 1da451582812..4ca06ed5d6f5 100644
--- a/drivers/firmware/efi/efi-bgrt.c
+++ b/drivers/firmware/efi/efi-bgrt.c
@@ -17,7 +17,10 @@
 #include <linux/efi-bgrt.h>
 
 struct acpi_table_bgrt bgrt_tab;
+EXPORT_SYMBOL(bgrt_tab);
+
 size_t bgrt_image_size;
+EXPORT_SYMBOL(bgrt_image_size);
 
 struct bmp_header {
        u16 id;
--


^ permalink raw reply related

* Re: [PATCH v2 11/14] userfaultfd: add UFFD_FEATURE_RWP_ASYNC for async fault resolution
From: Mike Rapoport @ 2026-05-12 18:05 UTC (permalink / raw)
  To: Kiryl Shutsemau (Meta)
  Cc: akpm, peterx, david, ljs, surenb, vbabka, Liam.Howlett, ziy,
	corbet, skhan, seanjc, pbonzini, jthoughton, aarcange, sj,
	usama.arif, linux-mm, linux-kernel, linux-doc, linux-kselftest,
	kvm, kernel-team
In-Reply-To: <65492c7b535080c7e85e90cb7ca962a52871e8b9.1778254670.git.kas@kernel.org>

On Fri, May 08, 2026 at 04:55:23PM +0100, Kiryl Shutsemau (Meta) wrote:
> Sync RWP delivers a message and blocks the faulting thread until the
> handler resolves the fault. For working-set tracking the VMM does not
> need the message: it just needs to know, at scan time, which pages
> were touched. Async RWP serves that use case — the kernel restores
> access in-place and the faulting thread continues without blocking.
> 
> The VMM reconstructs the access pattern after the fact via
> PAGEMAP_SCAN: pages whose uffd bit is still set (inverted
> PAGE_IS_ACCESSED) were not re-accessed since the last RWP cycle.
> 
> Worth calling out: async resolution upgrades writable private anon
> PTEs via pte_mkwrite() when can_change_pte_writable() allows, mirroring
> do_numa_page(). Without it, every re-access of an RWP'd writable page
> would COW-fault a second time.
> 
> UFFD_FEATURE_RWP_ASYNC requires UFFD_FEATURE_RWP.
> 
> Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
> Assisted-by: Claude:claude-opus-4-6

Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>

> ---
>  fs/userfaultfd.c                 | 19 ++++++++++++++++++-
>  include/linux/userfaultfd_k.h    |  6 ++++++
>  include/uapi/linux/userfaultfd.h | 11 ++++++++++-
>  mm/huge_memory.c                 | 25 ++++++++++++++++++++++++-
>  mm/hugetlb.c                     | 32 +++++++++++++++++++++++++++++++-
>  mm/memory.c                      | 27 +++++++++++++++++++++++++--
>  6 files changed, 114 insertions(+), 6 deletions(-)

-- 
Sincerely yours,
Mike.

^ permalink raw reply

* [PATCH] dm: fix dm-inlinecrypt docs warnings
From: Randy Dunlap @ 2026-05-12 18:04 UTC (permalink / raw)
  To: linux-kernel
  Cc: Randy Dunlap, Linlin Zhang, Alasdair Kergon, Mike Snitzer,
	Mikulas Patocka, Benjamin Marzinski, dm-devel, Jonathan Corbet,
	Shuah Khan, linux-doc

Add this file to the index and use a longer heading overline string
to eliminate warnings:

Documentation/admin-guide/device-mapper/dm-inlinecrypt.rst:1: WARNING: Title overline too short.
========
dm-inlinecrypt
========
Documentation/admin-guide/device-mapper/dm-inlinecrypt.rst: WARNING: document isn't included in any toctree [toc.not_included]

Fixes: b4a0774bd7fd ("dm: add documentation for dm-inlinecrypt target")
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
---
Cc: Linlin Zhang <linlin.zhang@oss.qualcomm.com>
Cc: Alasdair Kergon <agk@redhat.com>
Cc: Mike Snitzer <snitzer@kernel.org>
Cc: Mikulas Patocka <mpatocka@redhat.com>
Cc: Benjamin Marzinski <bmarzins@redhat.com>
Cc: dm-devel@lists.linux.dev
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Cc: linux-doc@vger.kernel.org

 Documentation/admin-guide/device-mapper/dm-inlinecrypt.rst |    4 ++--
 Documentation/admin-guide/device-mapper/index.rst          |    1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

--- linux-next-20260508.orig/Documentation/admin-guide/device-mapper/dm-inlinecrypt.rst
+++ linux-next-20260508/Documentation/admin-guide/device-mapper/dm-inlinecrypt.rst
@@ -1,6 +1,6 @@
-========
+==============
 dm-inlinecrypt
-========
+==============
 
 Device-Mapper's "inlinecrypt" target provides transparent encryption of block devices
 using the inline encryption hardware.
--- linux-next-20260508.orig/Documentation/admin-guide/device-mapper/index.rst
+++ linux-next-20260508/Documentation/admin-guide/device-mapper/index.rst
@@ -15,6 +15,7 @@ Device Mapper
     dm-flakey
     dm-ima
     dm-init
+    dm-inlinecrypt
     dm-integrity
     dm-io
     dm-log

^ permalink raw reply

* Re: [PATCH v6 1/4] mm/memory-failure: report MF_MSG_KERNEL for reserved pages
From: jane.chu @ 2026-05-12 17:58 UTC (permalink / raw)
  To: David Hildenbrand (Arm), Breno Leitao, Miaohe Lin,
	Naoya Horiguchi, Andrew Morton, Jonathan Corbet, Shuah Khan,
	Lorenzo Stoakes, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Shuah Khan, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Liam R. Howlett
  Cc: linux-mm, linux-kernel, linux-doc, linux-kselftest,
	linux-trace-kernel, kernel-team, Lance Yang
In-Reply-To: <9504c193-8c01-4d03-8f62-c50fd7fbdbc0@kernel.org>



On 5/12/2026 1:17 AM, David Hildenbrand (Arm) wrote:
> On 5/11/26 17:38, Breno Leitao wrote:
>> When get_hwpoison_page() returns a negative value, distinguish
>> reserved pages from other failure cases by reporting MF_MSG_KERNEL
>> instead of MF_MSG_GET_HWPOISON. Reserved pages belong to the kernel
>> and should be classified accordingly for proper handling.
>>
>> Sample PG_reserved before the get_hwpoison_page() call. In the
>> MF_COUNT_INCREASED path get_any_page() can drop the caller's
>> reference before returning -EIO, after which the underlying page may
>> have been freed and reallocated with page->flags reset; reading
>> PageReserved(p) at that point would observe stale or unrelated state.
>> The pre-call snapshot reflects what the page actually was at the
>> time of the failure event.
>>
>> Acked-by: Miaohe Lin <linmiaohe@huawei.com>
>> Reviewed-by: Lance Yang <lance.yang@linux.dev>
>> Signed-off-by: Breno Leitao <leitao@debian.org>
>> ---
>>   mm/memory-failure.c | 19 ++++++++++++++++++-
>>   1 file changed, 18 insertions(+), 1 deletion(-)
>>
>> diff --git a/mm/memory-failure.c b/mm/memory-failure.c
>> index 866c4428ac7ef..f112fb27a8ff6 100644
>> --- a/mm/memory-failure.c
>> +++ b/mm/memory-failure.c
>> @@ -2348,6 +2348,7 @@ int memory_failure(unsigned long pfn, int flags)
>>   	unsigned long page_flags;
>>   	bool retry = true;
>>   	int hugetlb = 0;
>> +	bool is_reserved;
>>   
>>   	if (!sysctl_memory_failure_recovery)
>>   		panic("Memory failure on page %lx", pfn);
>> @@ -2411,6 +2412,18 @@ int memory_failure(unsigned long pfn, int flags)
>>   	 * In fact it's dangerous to directly bump up page count from 0,
>>   	 * that may make page_ref_freeze()/page_ref_unfreeze() mismatch.
>>   	 */
>> +	/*
>> +	 * Pages with PG_reserved set are not currently managed by the
>> +	 * page allocator (memblock-reserved memory, driver reservations,
>> +	 * etc.), so classify them as kernel-owned for reporting.
>> +	 *
>> +	 * Sample the flag before get_hwpoison_page(): in the
>> +	 * MF_COUNT_INCREASED path, get_any_page() can drop the caller's
>> +	 * reference before returning -EIO, after which page->flags may
>> +	 * have been reset by the allocator.
>> +	 */
>> +	is_reserved = PageReserved(p);
>> +
>>   	res = get_hwpoison_page(p, flags);
>>   	if (!res) {
>>   		if (is_free_buddy_page(p)) {
>> @@ -2432,7 +2445,11 @@ int memory_failure(unsigned long pfn, int flags)
>>   		}
>>   		goto unlock_mutex;
>>   	} else if (res < 0) {
>> -		res = action_result(pfn, MF_MSG_GET_HWPOISON, MF_IGNORED);
>> +		if (is_reserved)
>> +			res = action_result(pfn, MF_MSG_KERNEL, MF_IGNORED);
>> +		else
>> +			res = action_result(pfn, MF_MSG_GET_HWPOISON,
>> +					    MF_IGNORED);
>>   		goto unlock_mutex;
>>   	}
>>   
>>
> 
> It's a bit odd that we need this handling when we already have handling for
> reserved pages in error_states[].
> 
> HWPoisonHandlable() would always essentially reject PG_reserved pages. So
> __get_hwpoison_page() ... would always fail? Making
> get_hwpoison_page()->get_any_page() always fail?
> 
> But then, we never call identify_page_state()? And never call me_kernel()?
> 
> This all looks very odd.
> 
> Why would you even want to call get_hwpoison_page() in the first place if you
> find PageReserved?
> 

Ah, good point!
It seems to me that all unhandable pages should head out to 
identify_page_state:

--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -2411,6 +2411,10 @@ int memory_failure(unsigned long pfn, int flags)
          * In fact it's dangerous to directly bump up page count from 0,
          * that may make page_ref_freeze()/page_ref_unfreeze() mismatch.
          */
+
+       if (!HWPoisonHandlable(page, flags)
+               goto identify_page_state;
+
         res = get_hwpoison_page(p, flags);
         if (!res) {
                 if (is_free_buddy_page(p)) {

thanks,
-jane





^ permalink raw reply

* Re: [PATCH 0/4] Add MSI Claw HID Configuration Driver
From: Derek John Clark @ 2026-05-12 17:54 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Benjamin Tissoires, Pierre-Loup A . Griffais, Denis Benato,
	Zhouwang Huang, linux-input, linux-doc, linux-kernel
In-Reply-To: <n533qs94-7o4r-p5r0-04p1-68q1398n5785@xreary.bet>

On Tue, May 12, 2026 at 9:13 AM Jiri Kosina <jikos@kernel.org> wrote:
>
> On Sun, 10 May 2026, Derek J. Clark wrote:
>
> > This series adds and HID Configuration driver for the MSI Claw line of
> > Handheld Gaming PC's. The MSI Claw HID interface provides multiple
> > features, such as the ability to switch between xinput, dinput, and a
> > desktop mode, RGB control, rumble intensity, and mapping of the rear "M"
> > keys. There are additional gamepad modes that are not included in this
> > driver as they appear to be used in assembly line testing or are
> > incomplete in the firmware. During my testing I found them to be unstable.
> >
> > The initial version of this driver was written by Denis Benato, which
> > contained the initial reverse-engineering and implementation for the
> > gamepad mode switching. This work was later expanded by Zhouwang Huang
> > to include more gamepad modes and additional features. Finally, I
> > refactored the entire driver, fixed multiple bugs, and refined the overall
> > format to conform to kernel driver best practices and style guide.
> >
> > Claude was used initially by Zhouwang Huang to quickly parse HID captures
> > during the reverse-engineering of some of the features. Since Claude had
> > already been used, as a test of its capabilities I had it implement the
> > rumble intensity attribute after I had already rewritten most of the
> > driver, which I then manually edited to fix some mistakes. I also used
> > Claude to review the driver and these patches for any mistakes and bugs.
> >
> > Assisted-by: Claude:claude-sonnet-4-6
> > Co-developed-by: Denis Benato <denis.benato@linux.dev>
> > Signed-off-by: Denis Benato <denis.benato@linux.dev>
> > Co-developed-by: Zhouwang Huang <honjow311@gmail.com>
> > Signed-off-by: Zhouwang Huang <honjow311@gmail.com>
> > Signed-off-by: Derek J. Clark <derekjohn.clark@gmail.com>
> >
> > Derek J. Clark (4):
> >   HID: hid-msi-claw: Add MSI Claw configuration driver
> >   HID: hid-msi-claw: Add M-key mapping attributes
> >   HID: hid-msi-claw: Add RGB control interface
> >   HID: hid-msi-claw: Add Rumble Intensity Attributes
>
> The driver looks reasonable, I'd just like to propose that we name it just
> hid-msi to follow the usual HID subsystem driver naming standards, so that
> it can later be extended with supporting other MSI devices.
>

Hi Jiri,
Sounds good. I'll do that when I fix the issues flagged by the bot in
v2 and I'll try to have it out some time this week.

Thanks,
Derek

Thanks
> Thanks,
>
> --
> Jiri Kosina
> SUSE Labs
>

^ permalink raw reply

* Re: [PATCH v12 06/11] iio: test: iio-test-format: add test case for decimal format
From: Andy Shevchenko @ 2026-05-12 17:51 UTC (permalink / raw)
  To: Rodrigo Alencar
  Cc: rodrigo.alencar, linux-kernel, linux-iio, devicetree, linux-doc,
	Jonathan Cameron, David Lechner, Andy Shevchenko,
	Lars-Peter Clausen, Michael Hennerich, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jonathan Corbet, Andrew Morton,
	Petr Mladek, Steven Rostedt, Rasmus Villemoes, Sergey Senozhatsky,
	Shuah Khan
In-Reply-To: <zugkmatjsacla7l7nguekmclfdkzsshr3gs434a3liccgokxb4@xg77y5tkts5c>

On Tue, May 12, 2026 at 06:02:22PM +0100, Rodrigo Alencar wrote:
> On 26/05/12 05:36PM, Andy Shevchenko wrote:
> > On Sun, May 10, 2026 at 01:42:24PM +0100, Rodrigo Alencar via B4 Relay wrote:

...

> > > +	iio_val_s64_array_populate(24, values);
> > 
> > You want to test this first...
> > I think the previous patch needs new test cases.
> 
> This is no complex stuff.. those functions are straightforward and
> goes into accordance with what the format function does... which is
> the opposite, before populating the buffer. The assertion on the buffer
> content accounts for that behavior.

You never know what BE32 / BE64 architectures will give you...
(but okay, it's simple enough to check the implementation),

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Re: [PATCH v12 05/11] iio: core: add decimal value formatting into 64-bit value
From: Andy Shevchenko @ 2026-05-12 17:49 UTC (permalink / raw)
  To: Rodrigo Alencar
  Cc: rodrigo.alencar, linux-kernel, linux-iio, devicetree, linux-doc,
	Jonathan Cameron, David Lechner, Andy Shevchenko,
	Lars-Peter Clausen, Michael Hennerich, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jonathan Corbet, Andrew Morton,
	Petr Mladek, Steven Rostedt, Rasmus Villemoes, Sergey Senozhatsky,
	Shuah Khan
In-Reply-To: <ql7smsqza7liupm7fhdts73cxsltrpxsqofu5ovzpxpwvcscuv@qigi3dwukk7k>

On Tue, May 12, 2026 at 05:09:32PM +0100, Rodrigo Alencar wrote:
> On 26/05/12 05:35PM, Andy Shevchenko wrote:
> > On Sun, May 10, 2026 at 01:42:23PM +0100, Rodrigo Alencar via B4 Relay wrote:
> > 
> > > Create new format types for iio values (IIO_VAL_DECIMAL64_*), which
> > > defines the representation of fixed decimal point values into a single
> > > 64-bit number. This new format increases the range of represented values,
> > > allowing for integer parts greater than 2^32, as bits are not "wasted"
> > > in the fractional part, which can be seen in IIO_VAL_INT_PLUS_MICRO and
> > > IIO_VAL_INT_PLUS_NANO. Helpers are created to compose and decompose 64-bit
> > > decimals into integer values used in IIO formatting interfaces, which
> > > creates consistency and avoid error-prone manual assignments when using
> > > wordpart macros. When doing the parsing, kstrtodec64() is used with the
> > > scale defined by the specific decimal format type.

...

> > > +		tmp2 = div64_s64_rem(iio_val_s64_from_array(vals),
> > > +				     int_pow(10, scale), &frac);
> > > +		if (tmp2 == 0 && frac < 0)
> > > +			return sysfs_emit_at(buf, offset, "-0.%0*lld", scale,
> > > +					     abs(frac));
> > > +		else
> > > +			return sysfs_emit_at(buf, offset, "%lld.%0*lld", tmp2,
> > > +					     scale, abs(frac));
> > > +	}
> > 
> > What about
> > 
> > 		/* Print a leading '-' for negative fractions */
> > 		if (tmp2 == 0 && frac < 0)
> > 			offset += sysfs_emit_at(buf, offset, "-");
> > 
> > 		return sysfs_emit_at(buf, offset, "%lld.%0*lld", tmp2, scale, abs(frac));
> > 
> > Also note this won't work with the frac that are == S64_MIN. It's UB (undefined
> > behaviour), see the comment at abs() implementation. Maybe a time to add abs()
> > corner case tests...
> 
> frac cannot be S64_MIN, it is always and remainder of a power of 10 modulus.

Okay, but what about input of -0.9999999999999999999 ? Will it fit the signed
frac type?

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Re: [PATCH v12 02/11] lib: kstrtox: add kstrtoudec64() and kstrtodec64()
From: Andy Shevchenko @ 2026-05-12 17:46 UTC (permalink / raw)
  To: Rodrigo Alencar
  Cc: Andy Shevchenko, Jonathan Cameron, Rodrigo Alencar via B4 Relay,
	rodrigo.alencar, linux-kernel, linux-iio, devicetree, linux-doc,
	David Lechner, Andy Shevchenko, Lars-Peter Clausen,
	Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jonathan Corbet, Andrew Morton, Petr Mladek, Steven Rostedt,
	Rasmus Villemoes, Sergey Senozhatsky, Shuah Khan, David Laight
In-Reply-To: <ru2h3ip7qf6j54dlrij54nwp45uyq6m2e6zspt6v6eynpsagqq@eo5v3yparuhh>

On Tue, May 12, 2026 at 06:26:12PM +0100, Rodrigo Alencar wrote:
> On 26/05/12 08:13PM, Andy Shevchenko wrote:
> > On Tue, May 12, 2026 at 05:35:59PM +0100, Rodrigo Alencar wrote:
> > > On 26/05/12 06:21PM, Andy Shevchenko wrote:
> > > > On Tue, May 12, 2026 at 6:11 PM Rodrigo Alencar
> > > > <455.rodrigo.alencar@gmail.com> wrote:
> > > > > On 26/05/12 05:43PM, Andy Shevchenko wrote:
> > > > > > On Tue, May 12, 2026 at 03:12:24PM +0100, Rodrigo Alencar wrote:
> > > > > > > On 26/05/12 04:48PM, Andy Shevchenko wrote:
> > > > > > > > On Tue, May 12, 2026 at 02:21:14PM +0100, Rodrigo Alencar wrote:
> > > > > > > > > On 26/05/12 04:12PM, Andy Shevchenko wrote:
> > > > > > > > > > On Tue, May 12, 2026 at 12:39:53PM +0100, Jonathan Cameron wrote:
> > > > > > > > > > > On Sun, 10 May 2026 13:42:20 +0100
> > > > > > > > > > > Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org> wrote:
> > > > > > > > > > >
> > > > > > > > > > > > Add helpers that parses decimal numbers into 64-bit number, i.e., decimal
> > > > > > > > > > > > point numbers with pre-defined scale are parsed into a 64-bit value (fixed
> > > > > > > > > > > > precision). After the decimal point, digits beyond the specified scale
> > > > > > > > > > > > are ignored.
> > > > > > > > > > >
> > > > > > > > > > > Whilst Rodrigo has already replied to say there will be another version
> > > > > > > > > > > I'd like to request final feedback from those who were involved in the parser
> > > > > > > > > > > discussions.
> > > > > > > > > > >
> > > > > > > > > > > They got very involved and I'm far from an expert in the right way to do
> > > > > > > > > > > this stuff.
> > > > > > > > > > >
> > > > > > > > > > > I don't think David Laight was +CC so I've added that.
> > > > > > > > > > > David, Andy - I think you two were most involved in that discussion:
> > > > > > > > > > > Any objections to the end result?
> > > > > > > > > >
> > > > > > > > > > I already said a few times about the naming. I do not like the kstrto*()
> > > > > > > > > > be semantically different on how they treat the input. Second point is
> > > > > > > > > > to avoid code duplication, but this one is less of a concern since the
> > > > > > > > > > new code is in the library close to the other potentially duplicate code
> > > > > > > > > > piece and hence can be addressed later.
> > > > > > > > >
> > > > > > > > > I suppose I reached into kstrtodec64() and kstrtoudec64() because it aligns
> > > > > > > > > with your expectations for kstrto*() semantics, no? Those include:
> > > > > > > > >  - overflow check;
> > > > > > > > >  - extensive input validation;
> > > > > > > > >  - optional '\n' in the end;
> > > > > > > > >  - mandatory nul-termination.
> > > > > > > > >
> > > > > > > > > am I missing anything?
> > > > > > > >
> > > > > > > > When we add scale we basically make that not true. Moreover the code in this
> > > > > > > > patch makes scale == number_of_characters which I think a bit fragile, however
> > > > > > > > it's about the fractional part when the amount of digits is equal to scale.
> > > > > > >
> > > > > > > That is not really the case. It is being set as a limit, so it does check for
> > > > > > > truncation and zero-padding.
> > > > > >
> > > > > > I do not see it happens in _parse_integer_limit(). It doesn't try to parse more
> > > > > > characters than it's requested in max_chars. It doesn't check if there are more
> > > > > > character nor their converted values.
> > > > > >
> > > > > > > > To make this work as expected we need to add an additional call like
> > > > > > > > kstrtoull() (and perhaps drop that \n and NUL-terminator checks) and see
> > > > > > > > if that overflows or not. Since it's a fractional part it must have less
> > > > > > > > than 20 (decimal) digits there, so we check the rv (or how many digits
> > > > > > > > were parsed successfully) and compare to 20. If it's more, we got too many
> > > > > > > > decimal digits.
> > > > > > >
> > > > > > > For overflow it checks the KSTRTOX_OVERFLOW flag and leverages check_mul_overflow()
> > > > > > > and check_add_overflow() when combining fractional and integer parts. The amount
> > > > > > > of characters is not really important there. The scale cannot be bigger than 19 and
> > > > > > > that makes sure that int_pow() does not overflow. The code uses _parse_integer_limit()
> > > > > > > due to the nature of input and to avoid 64-bit division, kstrtoull() at any point
> > > > > > > (parsing integer or fractional parts) does not make much sense.
> > > > > >
> > > > > > Under 'like kstrotoull()' I meant something that repeats needed functionality.
> > > > > > I believe it's parse_integer() (without limit).
> > > > >
> > > > > I think we are going in circles here and we could look at the code instead:
> > > > > - integer parsing with _parse_integer()
> > > > >         - overflow check and validation of the return value
> > > > > - fractional parsing with _parse_integer_limit()
> > > > >         - overflow check and validation of the return value
> > > > 
> > > > No, this is not fully true. That's what my whole point is about. The
> > > > max_chars parameter limits the input check, then it skips an arbitrary
> > > > number of digits and only *then* it checks for \n and \0. What will be
> > > > the result of the
> > > > 0.00000000000000000000000000000000423 in your case? Whatever scale you
> > > > gave it will return 0 without checking on how many digits were
> > > > supplied.
> > > 
> > > I suppose that is a valid input and 0 is the expected result there.
> > > 
> > > > All the same for 0.9999999999999999999999999999999000423. My
> > > > point is that we should limit this by 19 digits.
> > > 
> > > why we need to limit by 19? Digits beyond the scale carry no value...
> > 
> > ...only if they are all 0:s.
> 
> I thought your concern was on input length.

One of, since I think you rose the topic of leading 0:s for integers and
I agreed with that which makes sense to have mirrored in fractional part.

> > > just like leading zeros to the integer part (which is also accepted by
> > > kstrtoull() when parsing with base 10). Not sure why this is invalid input.
> > 
> > See above. I agree on truncating trailing 0:s as it's done for leading ones
> > in integer part, but if any of the digit behind 19th is not 0, it's an overflow
> > condition (or bad input, depending how strict the rules are).
> 
> stating in the documentation that digits beyond the scale are ignored is not
> enough?

It's in case we are not for kstrto*() family. My understanding that kstrto*()
use strict rules on the input in overflow check.

> > > > On top of that, what about -0.9(19 times) ? the fraction should be u64
> > > > in this case and it's fine. The sign applies to the combined value.
> > > 
> > > yes, range for signed values are verified later.
> > 
> > > > >         - extra scaling and truncation happening outside if needed.
> > > > 
> > > > Right, but the given input may be way too long and still needs more validation.
> > > 
> > > What is the problem with a long input of digits?
> > > C compiler does not complain about this when parsing a float value,
> > > python does not
> > > complain about this when parsing floats or decimals either.
> > 
> > Because there is an exponent limit and for double it's something like 1e307
> > IIRC, meaning, try 1024 digits to be sure.
> > 
> > Python most likely uses the library for big numbers, you can't compare it at all with this.
> 
> You would be fine if the truncation loop:
> 
> while (isdigit(*s)) /* truncate */
> 	s++;
> 
> is bounded by (19-scale) iteration count? or it should keep iterating if those are zero?

Ideally both.

We don't care about the digits in the range of 19-scale and skip all 0:s after
that.

	/* truncate unrequired digits within type limit, i.e. 19 decimal digits */
	while (isdigit(*s) && "(s - pos_of_dot) is less than 19")
		s++;
	while (s == '0') /* truncate trailing 0:s, it's not a bad input nor overflow */
		s++;

	// Now if it's not \0 nor \n and
	//	a) still a digit consider either overflow or bad input,
	//	b) if not a digit, consider as bad input.

In a) I tend to be on par with the other k*() and consider that as overflow.

> is that the only concern? Again, the usage of _parse_integer_limit(s, 10, &_frac, scale)
> avoids a 64-bit division when checking the rv.

I'm not against usage of _parse_integer_limit(), I'm for stricter rules on the input.
With the above addressed, I have no more concerns.

> > > > > - check for input termination
> > > > > - combination of integer and fractional parts with check_mul_overflow() and check_add_overflow()
> > > > >
> > > > > > > > Maybe I'm missing these checks already performed?
> > > > > > > >
> > > > > > > > > > Having the test cases is a big benefit, and that part I like the most.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply

* Re: [PATCH v2 10/14] mm/pagemap: add PAGE_IS_ACCESSED for RWP tracking
From: Mike Rapoport @ 2026-05-12 17:41 UTC (permalink / raw)
  To: Kiryl Shutsemau (Meta)
  Cc: akpm, peterx, david, ljs, surenb, vbabka, Liam.Howlett, ziy,
	corbet, skhan, seanjc, pbonzini, jthoughton, aarcange, sj,
	usama.arif, linux-mm, linux-kernel, linux-doc, linux-kselftest,
	kvm, kernel-team
In-Reply-To: <c076bf8d482e80512b0b1db0e107ef0c822c5ddf.1778254670.git.kas@kernel.org>

On Fri, May 08, 2026 at 04:55:22PM +0100, Kiryl Shutsemau (Meta) wrote:
> PAGEMAP_SCAN already reports PAGE_IS_WRITTEN from the inverted uffd
> PTE bit, targeting the UFFDIO_WRITEPROTECT workflow. UFFDIO_RWPROTECT
> reuses the same PTE bit as a marker for read-write protection, but
> "has been written" and "has been accessed" are distinct semantic
> signals — they happen to share one PTE bit today only because the two
> implementations share infrastructure.
> 
> Give RWP its own pagemap category so the UAPI does not conflate them:
> 
>   PAGE_IS_WRITTEN   reported on VM_UFFD_WP VMAs,  !pte_uffd(pte)
>   PAGE_IS_ACCESSED  reported on VM_UFFD_RWP VMAs, !pte_uffd(pte)
> 
> Both still read the same PTE bit today, but each is scoped to the VMA
> whose registered mode makes the bit meaningful. If a future
> implementation moves RWP to a separate PTE bit, only PAGE_IS_ACCESSED
> switches over.
> 
> This is a UAPI narrowing. Outside VM_UFFD_WP VMAs the uffd bit is
> always clear, so PAGEMAP_SCAN used to flag PAGE_IS_WRITTEN on every
> present PTE there — a meaningless duplicate of PAGE_IS_PRESENT. Now
> PAGE_IS_WRITTEN fires only inside VM_UFFD_WP VMAs.
> 
> pagemap_hugetlb_category() now takes the vma like its PTE/PMD peers.
> 
> Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
> Assisted-by: Claude:claude-opus-4-6

Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>

> ---
>  Documentation/admin-guide/mm/pagemap.rst | 13 ++++-
>  fs/proc/task_mmu.c                       | 73 ++++++++++++++++++------
>  include/uapi/linux/fs.h                  |  1 +
>  tools/include/uapi/linux/fs.h            |  1 +
>  4 files changed, 67 insertions(+), 21 deletions(-)

-- 
Sincerely yours,
Mike.

^ permalink raw reply

* htmldocs: Documentation/driver-api/vfio_pci_liveupdate:7: ./drivers/vfio/pci/vfio_pci_liveupdate.c:78: WARNING: unknown document: '/PCI/liveupdate' [ref.doc]
From: kernel test robot @ 2026-05-12 17:28 UTC (permalink / raw)
  To: David Matlack; +Cc: oe-kbuild-all, 0day robot, Vipin Sharma, linux-doc

tree:   https://github.com/intel-lab-lkp/linux/commits/Vipin-Sharma/vfio-pci-Register-a-file-handler-with-Live-Update-Orchestrator/20260512-152829
head:   ebd50d810440364055692a3ed1d967cd7149d0dc
commit: 4ab988bdf43079ff3eb58904f591ec464f289db5 docs: liveupdate: Add documentation for VFIO PCI
date:   10 hours ago
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
docutils: docutils (Docutils 0.21.2, Python 3.13.5, on linux)
reproduce: (https://download.01.org/0day-ci/archive/20260512/202605121946.GDFPWf9X-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605121946.GDFPWf9X-lkp@intel.com/

All warnings (new ones prefixed by >>):

   Documentation/userspace-api/landlock:550: ./include/uapi/linux/landlock.h:45: ERROR: Unknown target name: "network flags". [docutils]
   Documentation/userspace-api/landlock:550: ./include/uapi/linux/landlock.h:50: ERROR: Unknown target name: "scope flags". [docutils]
   Documentation/userspace-api/landlock:550: ./include/uapi/linux/landlock.h:24: ERROR: Unknown target name: "filesystem flags". [docutils]
   Documentation/userspace-api/landlock:559: ./include/uapi/linux/landlock.h:168: ERROR: Unknown target name: "filesystem flags". [docutils]
   Documentation/userspace-api/landlock:559: ./include/uapi/linux/landlock.h:191: ERROR: Unknown target name: "network flags". [docutils]
>> Documentation/driver-api/vfio_pci_liveupdate:7: ./drivers/vfio/pci/vfio_pci_liveupdate.c:78: WARNING: unknown document: '/PCI/liveupdate' [ref.doc]
   Documentation/networking/skbuff:36: ./include/linux/skbuff.h:181: WARNING: Failed to create a cross reference. A title or caption not found: 'crc' [ref.ref]

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH v2 09/14] mm/userfaultfd: add RWP fault delivery and expose UFFDIO_REGISTER_MODE_RWP
From: Mike Rapoport @ 2026-05-12 17:29 UTC (permalink / raw)
  To: Kiryl Shutsemau (Meta)
  Cc: akpm, peterx, david, ljs, surenb, vbabka, Liam.Howlett, ziy,
	corbet, skhan, seanjc, pbonzini, jthoughton, aarcange, sj,
	usama.arif, linux-mm, linux-kernel, linux-doc, linux-kselftest,
	kvm, kernel-team
In-Reply-To: <454b3381cb7ead65291b2d7e24c0bff62e55c41b.1778254670.git.kas@kernel.org>

On Fri, May 08, 2026 at 04:55:21PM +0100, Kiryl Shutsemau (Meta) wrote:
> Wire the fault side of read-write protection tracking and turn the
> userspace interface on.
> 
> An RWP-protected PTE is PAGE_NONE with the uffd bit set. The
> PROT_NONE triggers a fault on any access; the uffd bit distinguishes
> it from plain mprotect(PROT_NONE) or NUMA hinting.
> 
> Fault dispatch, per level:
> 
>   PTE     handle_pte_fault()    -> do_uffd_rwp()
>   PMD     __handle_mm_fault()   -> do_huge_pmd_uffd_rwp()
>   hugetlb hugetlb_fault()       -> hugetlb_handle_userfault()
> 
> The RWP branches gate on userfaultfd_pte_rwp() / userfaultfd_huge_pmd_rwp()
> (VM_UFFD_RWP plus the uffd bit) and fall through to do_numa_page() /
> do_huge_pmd_numa_page() otherwise. Each delivers a
> UFFD_PAGEFAULT_FLAG_RWP message through handle_userfault(); the handler
> resolves it with UFFDIO_RWPROTECT clearing MODE_RWP.
> 
> userfaultfd_must_wait() and userfaultfd_huge_must_wait() add matching
> protnone+uffd waiters so sync-mode fault handlers block correctly.
> 
> Expose the UAPI:
> 
>   UFFDIO_REGISTER_MODE_RWP   -> UFFD_API_REGISTER_MODES
>   UFFD_FEATURE_RWP           -> UFFD_API_FEATURES
>   _UFFDIO_RWPROTECT          -> UFFD_API_RANGE_IOCTLS
>                                 UFFD_API_RANGE_IOCTLS_BASIC
> 
> UFFD_FEATURE_RWP is masked out at UFFDIO_API time when PROT_NONE is
> not available or VM_UFFD_RWP aliases VM_NONE (32-bit), so userspace
> never sees an advertised-but-broken feature.
> 
> Works on anonymous, shmem, and hugetlb memory.
> 
> Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
> Assisted-by: Claude:claude-opus-4-6

A small nit below, other than that

Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>

> @@ -347,6 +359,14 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
>  	 */
>  	if (!pte_write(ptent) && (reason & VM_UFFD_WP))
>  		goto out;
> +	/*
> +	 * PTE is still RW-protected (protnone with uffd bit), wait for
> +	 * userspace to resolve. Plain PROT_NONE without the marker is not
> +	 * an RWP fault.
> +	 */
> +	if (pte_protnone(ptent) && pte_uffd(ptent) &&
> +	    (reason & VM_UFFD_RWP))

Nit: this fits even in 80-chars line

> +		goto out;
>  
>  	ret = false;
>  out:

-- 
Sincerely yours,
Mike.

^ permalink raw reply

* Re: [PATCH v12 02/11] lib: kstrtox: add kstrtoudec64() and kstrtodec64()
From: Rodrigo Alencar @ 2026-05-12 17:26 UTC (permalink / raw)
  To: Andy Shevchenko, Rodrigo Alencar
  Cc: Andy Shevchenko, Jonathan Cameron, Rodrigo Alencar via B4 Relay,
	rodrigo.alencar, linux-kernel, linux-iio, devicetree, linux-doc,
	David Lechner, Andy Shevchenko, Lars-Peter Clausen,
	Michael Hennerich, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jonathan Corbet, Andrew Morton, Petr Mladek, Steven Rostedt,
	Rasmus Villemoes, Sergey Senozhatsky, Shuah Khan, David Laight
In-Reply-To: <agNfqiZpGZAM-x_H@ashevche-desk.local>

On 26/05/12 08:13PM, Andy Shevchenko wrote:
> On Tue, May 12, 2026 at 05:35:59PM +0100, Rodrigo Alencar wrote:
> > On 26/05/12 06:21PM, Andy Shevchenko wrote:
> > > On Tue, May 12, 2026 at 6:11 PM Rodrigo Alencar
> > > <455.rodrigo.alencar@gmail.com> wrote:
> > > > On 26/05/12 05:43PM, Andy Shevchenko wrote:
> > > > > On Tue, May 12, 2026 at 03:12:24PM +0100, Rodrigo Alencar wrote:
> > > > > > On 26/05/12 04:48PM, Andy Shevchenko wrote:
> > > > > > > On Tue, May 12, 2026 at 02:21:14PM +0100, Rodrigo Alencar wrote:
> > > > > > > > On 26/05/12 04:12PM, Andy Shevchenko wrote:
> > > > > > > > > On Tue, May 12, 2026 at 12:39:53PM +0100, Jonathan Cameron wrote:
> > > > > > > > > > On Sun, 10 May 2026 13:42:20 +0100
> > > > > > > > > > Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > > > Add helpers that parses decimal numbers into 64-bit number, i.e., decimal
> > > > > > > > > > > point numbers with pre-defined scale are parsed into a 64-bit value (fixed
> > > > > > > > > > > precision). After the decimal point, digits beyond the specified scale
> > > > > > > > > > > are ignored.
> > > > > > > > > >
> > > > > > > > > > Whilst Rodrigo has already replied to say there will be another version
> > > > > > > > > > I'd like to request final feedback from those who were involved in the parser
> > > > > > > > > > discussions.
> > > > > > > > > >
> > > > > > > > > > They got very involved and I'm far from an expert in the right way to do
> > > > > > > > > > this stuff.
> > > > > > > > > >
> > > > > > > > > > I don't think David Laight was +CC so I've added that.
> > > > > > > > > > David, Andy - I think you two were most involved in that discussion:
> > > > > > > > > > Any objections to the end result?
> > > > > > > > >
> > > > > > > > > I already said a few times about the naming. I do not like the kstrto*()
> > > > > > > > > be semantically different on how they treat the input. Second point is
> > > > > > > > > to avoid code duplication, but this one is less of a concern since the
> > > > > > > > > new code is in the library close to the other potentially duplicate code
> > > > > > > > > piece and hence can be addressed later.
> > > > > > > >
> > > > > > > > I suppose I reached into kstrtodec64() and kstrtoudec64() because it aligns
> > > > > > > > with your expectations for kstrto*() semantics, no? Those include:
> > > > > > > >  - overflow check;
> > > > > > > >  - extensive input validation;
> > > > > > > >  - optional '\n' in the end;
> > > > > > > >  - mandatory nul-termination.
> > > > > > > >
> > > > > > > > am I missing anything?
> > > > > > >
> > > > > > > When we add scale we basically make that not true. Moreover the code in this
> > > > > > > patch makes scale == number_of_characters which I think a bit fragile, however
> > > > > > > it's about the fractional part when the amount of digits is equal to scale.
> > > > > >
> > > > > > That is not really the case. It is being set as a limit, so it does check for
> > > > > > truncation and zero-padding.
> > > > >
> > > > > I do not see it happens in _parse_integer_limit(). It doesn't try to parse more
> > > > > characters than it's requested in max_chars. It doesn't check if there are more
> > > > > character nor their converted values.
> > > > >
> > > > > > > To make this work as expected we need to add an additional call like
> > > > > > > kstrtoull() (and perhaps drop that \n and NUL-terminator checks) and see
> > > > > > > if that overflows or not. Since it's a fractional part it must have less
> > > > > > > than 20 (decimal) digits there, so we check the rv (or how many digits
> > > > > > > were parsed successfully) and compare to 20. If it's more, we got too many
> > > > > > > decimal digits.
> > > > > >
> > > > > > For overflow it checks the KSTRTOX_OVERFLOW flag and leverages check_mul_overflow()
> > > > > > and check_add_overflow() when combining fractional and integer parts. The amount
> > > > > > of characters is not really important there. The scale cannot be bigger than 19 and
> > > > > > that makes sure that int_pow() does not overflow. The code uses _parse_integer_limit()
> > > > > > due to the nature of input and to avoid 64-bit division, kstrtoull() at any point
> > > > > > (parsing integer or fractional parts) does not make much sense.
> > > > >
> > > > > Under 'like kstrotoull()' I meant something that repeats needed functionality.
> > > > > I believe it's parse_integer() (without limit).
> > > >
> > > > I think we are going in circles here and we could look at the code instead:
> > > > - integer parsing with _parse_integer()
> > > >         - overflow check and validation of the return value
> > > > - fractional parsing with _parse_integer_limit()
> > > >         - overflow check and validation of the return value
> > > 
> > > No, this is not fully true. That's what my whole point is about. The
> > > max_chars parameter limits the input check, then it skips an arbitrary
> > > number of digits and only *then* it checks for \n and \0. What will be
> > > the result of the
> > > 0.00000000000000000000000000000000423 in your case? Whatever scale you
> > > gave it will return 0 without checking on how many digits were
> > > supplied.
> > 
> > I suppose that is a valid input and 0 is the expected result there.
> > 
> > > All the same for 0.9999999999999999999999999999999000423. My
> > > point is that we should limit this by 19 digits.
> > 
> > why we need to limit by 19? Digits beyond the scale carry no value...
> 
> ...only if they are all 0:s.

I thought your concern was on input length.
 
> > just like leading zeros to the integer part (which is also accepted by
> > kstrtoull() when parsing with base 10). Not sure why this is invalid input.
> 
> See above. I agree on truncating trailing 0:s as it's done for leading ones
> in integer part, but if any of the digit behind 19th is not 0, it's an overflow
> condition (or bad input, depending how strict the rules are).

stating in the documentation that digits beyond the scale are ignored is not
enough?

> > > On top of that, what about -0.9(19 times) ? the fraction should be u64
> > > in this case and it's fine. The sign applies to the combined value.
> > 
> > yes, range for signed values are verified later.
> 
> > > >         - extra scaling and truncation happening outside if needed.
> > > 
> > > Right, but the given input may be way too long and still needs more validation.
> > 
> > What is the problem with a long input of digits?
> > C compiler does not complain about this when parsing a float value,
> > python does not
> > complain about this when parsing floats or decimals either.
> 
> Because there is an exponent limit and for double it's something like 1e307
> IIRC, meaning, try 1024 digits to be sure.
> 
> Python most likely uses the library for big numbers, you can't compare it at all with this.

You would be fine if the truncation loop:

while (isdigit(*s)) /* truncate */
	s++;

is bounded by (19-scale) iteration count? or it should keep iterating if those are zero?

is that the only concern? Again, the usage of _parse_integer_limit(s, 10, &_frac, scale)
avoids a 64-bit division when checking the rv.

> > > > - check for input termination
> > > > - combination of integer and fractional parts with check_mul_overflow() and check_add_overflow()
> > > >
> > > > > > > Maybe I'm missing these checks already performed?
> > > > > > >
> > > > > > > > > Having the test cases is a big benefit, and that part I like the most.
> 
> -- 
> With Best Regards,
> Andy Shevchenko
> 
> 

-- 
Kind regards,

Rodrigo Alencar

^ permalink raw reply

* Re: [kees:for-next/hardening 1/1] htmldocs: Documentation/driver-api/basics:127: ./include/linux/stddef.h:110: WARNING: Definition list ends without a blank line; unexpected unindent. [docutils]
From: Gustavo A. R. Silva @ 2026-05-12 17:24 UTC (permalink / raw)
  To: Kees Cook, Gustavo A. R. Silva
  Cc: kernel test robot, oe-kbuild-all, linux-doc
In-Reply-To: <202605120755.4A2AC441EB@keescook>


> Oh, hrm, there are a lot of errors in stddef.h for the "htmldocs" make
> target. Gustavo, can you see what's needed to fix these?

Sure thing. I saw that yesterday.

-Gustavo

^ permalink raw reply

* Re: [PATCH v3 3/3] Documentation: security-bugs: clarify requirements for AI-assisted reports
From: Jonathan Corbet @ 2026-05-12 17:21 UTC (permalink / raw)
  To: Willy Tarreau, greg
  Cc: Leon Romanovsky, skhan, security, workflows, linux-doc,
	linux-kernel, Willy Tarreau, Greg KH
In-Reply-To: <20260509094755.2838-4-w@1wt.eu>

Willy Tarreau <w@1wt.eu> writes:

> AI tools are increasingly used to assist in bug discovery. While these
> tools can identify valid issues, reports that are submitted without
> manual verification often lack context, contain speculative impact
> assessments, or include unnecessary formatting. Such reports increase
> triage effort, waste maintainers' time and may be ignored.
>
> Reports where the reporter has verified the issue and the proposed fix
> typically meet quality standards. This documentation outlines specific
> requirements for length, formatting, and impact evaluation to reduce
> the effort needed to deal with these reports.
>
> Cc: Greg KH <gregkh@linuxfoundation.org>
> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Reviewed-by: Leon Romanovsky <leon@kernel.org>
> Signed-off-by: Willy Tarreau <w@1wt.eu>
> ---
>  Documentation/process/security-bugs.rst | 57 +++++++++++++++++++++++++
>  1 file changed, 57 insertions(+)

One nit:

> +  * **Impact Evaluation**: Many AI-generated reports lack an understanding of
> +    the kernel's threat model and go to great lengths inventing theoretical
> +    consequences.

If only we had a shiny new document describing that threat model that we
could reference here... :)

Thanks,

jon

^ permalink raw reply

* Re: [PATCH v3 2/3] Documentation: security-bugs: explain what is and is not a security bug
From: Jonathan Corbet @ 2026-05-12 17:20 UTC (permalink / raw)
  To: Willy Tarreau, greg
  Cc: Leon Romanovsky, skhan, security, workflows, linux-doc,
	linux-kernel, Willy Tarreau, Greg KH
In-Reply-To: <20260509094755.2838-3-w@1wt.eu>

Willy Tarreau <w@1wt.eu> writes:

> The use of automated tools to find bugs in random locations of the kernel
> induces a raise of security reports even if most of them should just be
> reported as regular bugs. This patch is an attempt at drawing a line
> between what qualifies as a security bug and what does not, hoping to
> improve the situation and ease decision on the reporter's side.
>
> It defers the enumeration to a new file, threat-model.rst, that tries
> to enumerate various classes of issues that are and are not security
> bugs. This should permit to more easily update this file for various
> subsystem-specific rules without having to revisit the security bug
> reporting guide.

One thing here:

[...]

> +* **Capability-based protection**:
> +
> +  * users not having the ``CAP_SYS_ADMIN`` capability may not alter the
> +    kernel's configuration, memory nor state, change other users' view of the
> +    file system layout, grant any user capabilities they do not have, nor
> +    affect the system's availability (shutdown, reboot, panic, hang, or making
> +    the system unresponsive via unbounded resource exhaustion).

That is pretty demonstrably not true, and will likely elicit challenges
at some point.  There are a lot of "make me root" capabilities that
enable users to do all of those things; consider CAP_DAC_OVERRIDE as an
obvious example.  I think that just about all of the capabilities will
enable at least one of those things - that's why the capabilities exist
in the first place.  So I think this needs to be written far more
generally.

As a lower-priority thing, lockdown mode is meant to at least try to
provide some stronger guarantees, and lockdown circumvention seems to be
normally be viewed as a security bug.  Worth a mention?

Thanks,

jon

^ permalink raw reply

* Re: [PATCH v2 08/14] userfaultfd: add UFFDIO_REGISTER_MODE_RWP and UFFDIO_RWPROTECT plumbing
From: Mike Rapoport @ 2026-05-12 17:20 UTC (permalink / raw)
  To: Kiryl Shutsemau (Meta)
  Cc: akpm, peterx, david, ljs, surenb, vbabka, Liam.Howlett, ziy,
	corbet, skhan, seanjc, pbonzini, jthoughton, aarcange, sj,
	usama.arif, linux-mm, linux-kernel, linux-doc, linux-kselftest,
	kvm, kernel-team
In-Reply-To: <1ad0cb61a7b5a33a5375baadbd0720ba2ba43d2f.1778254670.git.kas@kernel.org>

On Fri, May 08, 2026 at 04:55:20PM +0100, Kiryl Shutsemau (Meta) wrote:
> Add the userspace interface for read-write protection tracking:
> 
>   - UFFDIO_REGISTER_MODE_RWP      register a range for RWP tracking
>   - UFFD_FEATURE_RWP              capability bit
>   - UFFDIO_RWPROTECT              install / remove RWP on a range
> 
> Registration sets VM_UFFD_RWP on the VMA. Combining MODE_WP with
> MODE_RWP is rejected because both modes claim the uffd PTE bit.
> 
> UFFDIO_RWPROTECT is the bidirectional counterpart of
> UFFDIO_WRITEPROTECT:
> 
>   - MODE_RWP              change_protection() with MM_CP_UFFD_RWP
>                           installs PAGE_NONE and sets the uffd bit on
>                           present PTEs
>   - !MODE_RWP             change_protection() with MM_CP_UFFD_RWP_RESOLVE
>                           restores vma->vm_page_prot and clears the bit
> 
> userfaultfd_clear_vma() runs the same resolve pass on unregister so
> RWP state cannot outlive the uffd.
> 
> Re-registering a range must not drop a mode that installs per-PTE
> markers (WP or RWP); doing so returns -EBUSY. This also closes a
> pre-existing window where re-registering without MODE_WP would strand
> uffd-wp markers: before, those caused extra write-faults but were
> otherwise benign; with RWP preservation in place, a subsequent
> mprotect() on a VM_UFFD_RWP VMA would silently promote the stale
> markers to RWP.
> 
> The feature is not yet advertised. UFFDIO_REGISTER_MODE_RWP,
> UFFD_FEATURE_RWP, and _UFFDIO_RWPROTECT are intentionally absent from
> UFFD_API_REGISTER_MODES, UFFD_API_FEATURES, and UFFD_API_RANGE_IOCTLS,
> so UFFDIO_API masks them out and the register-mode validator rejects
> the bit. The follow-up patch adds fault dispatch and exposes the UAPI.
> 
> Signed-off-by: Kiryl Shutsemau <kas@kernel.org>
> Assisted-by: Claude:claude-opus-4-6

Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>

with a comment below

> ---
>  Documentation/admin-guide/mm/userfaultfd.rst | 10 ++
>  fs/userfaultfd.c                             | 84 +++++++++++++++++
>  include/linux/userfaultfd_k.h                |  2 +
>  include/uapi/linux/userfaultfd.h             | 19 ++++
>  mm/userfaultfd.c                             | 97 +++++++++++++++++++-
>  5 files changed, 209 insertions(+), 3 deletions(-)
> 
> +	/*
> +	 * Pre-scan the range: validate every spanned VMA before applying
> +	 * any change_protection() so a partial failure cannot leave the
> +	 * process with only a prefix of the range re-protected.
> +	 */
> +	err = -ENOENT;
> +	for_each_vma_range(vmi, dst_vma, end) {
> +		if (!userfaultfd_rwp(dst_vma))
> +			return -ENOENT;
> +
> +		if (is_vm_hugetlb_page(dst_vma)) {
> +			unsigned long page_mask;
> +
> +			page_mask = vma_kernel_pagesize(dst_vma) - 1;
> +			if ((start & page_mask) || (len & page_mask))
> +				return -EINVAL;
> +		}
> +		err = 0;
> +	}
> +	if (err)
> +		return err;

It's an interesting way to say "no VMA found in range" :)
I think bool found and
	
	if (!found)
		return -ENOENT;

looks more readable.

-- 
Sincerely yours,
Mike.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox