Notify the PCI subsystem about devices vfio-pci is preserving across Live Update by registering the vfio-pci liveupdate file handler with the PCI subsystem's FLB handler. Notably this will ensure that devices preserved through vfio-pci do not go through auto-probing in the next kernel (i.e. preventing them from being bound to a different driver). This also enables VFIO to detect that a device was preserved before userspace first retrieves the file from it, which will be used in subsequent commits. Signed-off-by: David Matlack --- drivers/vfio/pci/vfio_pci_liveupdate.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/pci/vfio_pci_liveupdate.c b/drivers/vfio/pci/vfio_pci_liveupdate.c index b7451007fca4..7669c65bde17 100644 --- a/drivers/vfio/pci/vfio_pci_liveupdate.c +++ b/drivers/vfio/pci/vfio_pci_liveupdate.c @@ -64,6 +64,7 @@ static int vfio_pci_liveupdate_preserve(struct liveupdate_file_op_args *args) if (err) goto error; + pci_liveupdate_outgoing_preserve(pdev); args->serialized_data = virt_to_phys(ser); return 0; @@ -75,8 +76,10 @@ static int vfio_pci_liveupdate_preserve(struct liveupdate_file_op_args *args) static void vfio_pci_liveupdate_unpreserve(struct liveupdate_file_op_args *args) { struct vfio_pci_core_device_ser *ser = phys_to_virt(args->serialized_data); + struct vfio_device *device = vfio_device_from_file(args->file); struct folio *folio = virt_to_folio(ser); + pci_liveupdate_outgoing_unpreserve(to_pci_dev(device->dev)); kho_unpreserve_folio(folio); folio_put(folio); } @@ -199,8 +202,11 @@ static bool vfio_pci_liveupdate_can_finish(struct liveupdate_file_op_args *args) static void vfio_pci_liveupdate_finish(struct liveupdate_file_op_args *args) { + struct vfio_device *device = vfio_device_from_file(args->file); struct folio *folio; + pci_liveupdate_incoming_finish(to_pci_dev(device->dev)); + folio = virt_to_folio(phys_to_virt(args->serialized_data)); folio_put(folio); } @@ -223,10 +229,24 @@ static struct liveupdate_file_handler vfio_pci_liveupdate_fh = { int __init vfio_pci_liveupdate_init(void) { + int ret; + if (!liveupdate_enabled()) return 0; - return liveupdate_register_file_handler(&vfio_pci_liveupdate_fh); + ret = liveupdate_register_file_handler(&vfio_pci_liveupdate_fh); + if (ret) + return ret; + + ret = pci_liveupdate_register_fh(&vfio_pci_liveupdate_fh); + if (ret) + goto error; + + return 0; + +error: + liveupdate_unregister_file_handler(&vfio_pci_liveupdate_fh); + return ret; } void vfio_pci_liveupdate_cleanup(void) @@ -234,5 +254,6 @@ void vfio_pci_liveupdate_cleanup(void) if (!liveupdate_enabled()) return; + WARN_ON_ONCE(pci_liveupdate_unregister_fh(&vfio_pci_liveupdate_fh)); liveupdate_unregister_file_handler(&vfio_pci_liveupdate_fh); } -- 2.52.0.487.g5c8c507ade-goog