summaryrefslogtreecommitdiff
path: root/Documentation/core-api
diff options
context:
space:
mode:
authorDavid Matlack <dmatlack@google.com>2026-09-18 20:06:27 +0000
committerPasha Tatashin <pasha.tatashin@soleen.com>2026-09-28 15:37:50 +0000
commitb9affdf3de08c9e5fd8dca0c0bc9c54041362a10 (patch)
tree11cf998f0a411d6b8e619baaa64b4497babe69db /Documentation/core-api
parentcee9395acd8043be0644b25c34bfa86623f2b935 (diff)
downloadlinux-next-b9affdf3de08c9e5fd8dca0c0bc9c54041362a10.tar.gz
linux-next-b9affdf3de08c9e5fd8dca0c0bc9c54041362a10.zip
PCI: liveupdate: Set up FLB handler for the PCI core
Set up a File-Lifecycle-Bound (FLB) handler so that the PCI core can preserve its own state across a Live Update kexec. Preserving a PCI device across kexec requires preserving two independent sets of state: - Driver state, e.g. everything vfio-pci needs so that userspace can keep using the device in the new kernel. The driver preserves this itself and the PCI core is not involved. - PCI core state, e.g. which devices are preserved, so that the new kernel knows not to disturb them while they are still running and doing DMA. That is what this commit adds, serialized into struct pci_ser. Userspace, not the kernel, decides which devices are preserved, and it does so through the Live Update Orchestrator's (LUO) support for file preservation: a driver exposes a file that represents a single PCI device, and userspace preserves that device with ioctl(LIVEUPDATE_SESSION_PRESERVE_FD) on that file. Binding preservation to a file gives it proper lifecycle management, e.g. the preservation is undone if userspace cancels it or goes away. How a driver exposes that file is up to the driver and invisible to the PCI core (vfio-pci variant drivers, the first intended use-case, use their per-device cdev). LUO only knows that a file was preserved; it does not know that it represents a PCI device, or which one. Bridging that gap, drivers register their liveupdate_file_handler with the PCI core: pci_liveupdate_register_flb(driver_file_handler); pci_liveupdate_unregister_flb(driver_file_handler); LUO then refcounts the PCI core's FLB against the files preserved by that handler, and that refcount drives the lifetime of struct pci_ser: - On the first preserved file, luo_flb_file_preserve_one() calls pci_flb_preserve(), which allocates struct pci_ser and preserves it with KHO. - On the last unpreserved file (i.e. preservation cancelled), liveupdate_flb_put_outgoing() calls pci_flb_unpreserve(), which unpreserves and frees struct pci_ser. - In the next kernel, pci_flb_retrieve() hands the PCI core the struct pci_ser built by the previous kernel, whenever the PCI core asks for it (e.g. during enumeration), and pci_flb_finish() frees it once the PCI core is done with it. So the flow for preserving a device, once a driver has registered, looks like this: ioctl(LIVEUPDATE_SESSION_PRESERVE_FD) luo_session_preserve_fd() luo_preserve_file() luo_flb_file_preserve() luo_flb_file_preserve_one() # only on the first preserved file pci_flb_preserve() # alloc + KHO-preserve pci_ser fh->ops->preserve() # driver callback, e.g. vfio-pci Note that struct pci_ser is deliberately not allocated when a driver calls pci_liveupdate_register_flb(). A driver can be loaded for the lifetime of the machine without ever preserving a device, and there is no reason to allocate memory and hand it to the next kernel in that case. Letting LUO own the lifetime also means the PCI core does not have to duplicate LUO's refcounting and unwind logic for preservation failures, session aborts and fd close, and the incoming side (retrieve/finish) comes from the same object rather than requiring a separate KHO FDT entry owned by the PCI core. Note: This commit only allocates struct pci_ser and preserves it across Live Update. A subsequent commit adds pci_liveupdate_preserve(), the API drivers call from their fh->ops->preserve() callback 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. Reviewed-by: Pranjal Shrivastava <praan@google.com> Reviewed-by: Samiullah Khawaja <skhawaja@google.com> Signed-off-by: David Matlack <dmatlack@google.com> Reviewed-by: Bjorn Helgaas <bhelgaas@google.com> Link: https://patch.msgid.link/20260918200640.887030-2-dmatlack@google.com Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Diffstat (limited to 'Documentation/core-api')
-rw-r--r--Documentation/core-api/liveupdate.rst4
1 files changed, 4 insertions, 0 deletions
diff --git a/Documentation/core-api/liveupdate.rst b/Documentation/core-api/liveupdate.rst
index 5a292d0f3706..b3c689e633c1 100644
--- a/Documentation/core-api/liveupdate.rst
+++ b/Documentation/core-api/liveupdate.rst
@@ -1,5 +1,7 @@
.. SPDX-License-Identifier: GPL-2.0
+.. _luo:
+
========================
Live Update Orchestrator
========================
@@ -18,6 +20,8 @@ LUO Preserving File Descriptors
.. kernel-doc:: kernel/liveupdate/luo_file.c
:doc: LUO File Descriptors
+.. _flb:
+
LUO File Lifecycle Bound Global Data
====================================
.. kernel-doc:: kernel/liveupdate/luo_flb.c