Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2227521/?format=api
{ "id": 2227521, "url": "http://patchwork.ozlabs.org/api/patches/2227521/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260423212316.3431746-4-dmatlack@google.com/", "project": { "id": 28, "url": "http://patchwork.ozlabs.org/api/projects/28/?format=api", "name": "Linux PCI development", "link_name": "linux-pci", "list_id": "linux-pci.vger.kernel.org", "list_email": "linux-pci@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260423212316.3431746-4-dmatlack@google.com>", "list_archive_url": null, "date": "2026-04-23T21:23:07", "name": "[v4,03/11] PCI: liveupdate: Track incoming preserved PCI devices", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "6da359501ace55ef51674f5d8635cfabdc0fa173", "submitter": { "id": 69449, "url": "http://patchwork.ozlabs.org/api/people/69449/?format=api", "name": "David Matlack", "email": "dmatlack@google.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260423212316.3431746-4-dmatlack@google.com/mbox/", "series": [ { "id": 501248, "url": "http://patchwork.ozlabs.org/api/series/501248/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/list/?series=501248", "date": "2026-04-23T21:23:04", "name": "PCI: liveupdate: PCI core support for Live Update", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/501248/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2227521/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2227521/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <linux-pci+bounces-53070-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-pci@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256\n header.s=20251104 header.b=k55Wmyda;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-pci+bounces-53070-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=google.com header.i=@google.com\n header.b=\"k55Wmyda\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=209.85.210.202", "smtp.subspace.kernel.org;\n dmarc=pass (p=reject dis=none) header.from=google.com", "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com" ], "Received": [ "from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g1pxg6P8Hz1y2d\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 24 Apr 2026 07:24:07 +1000 (AEST)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id B136D302C761\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 23 Apr 2026 21:23:52 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 767FE3C061F;\n\tThu, 23 Apr 2026 21:23:32 +0000 (UTC)", "from mail-pf1-f202.google.com (mail-pf1-f202.google.com\n [209.85.210.202])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 093393BF677\n\tfor <linux-pci@vger.kernel.org>; Thu, 23 Apr 2026 21:23:26 +0000 (UTC)", "by mail-pf1-f202.google.com with SMTP id\n d2e1a72fcca58-82f8bbb4045so4388342b3a.2\n for <linux-pci@vger.kernel.org>; Thu, 23 Apr 2026 14:23:26 -0700 (PDT)" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776979411; cv=none;\n b=X9iMTtnmiqND/cHtmiQA+3+rzAUguhBRN+sIYCxTfrkQVxvH98PQWcPkUBpzYoJxxYp0N7/KBsIL+nyoKHvpt+hopFQsw0C1UsZeV7PamxpfdDNjHSaX8kxPGbmt8bvJ2tgiQWtYtFFxuf5/O1OG4eMjUqLSeFF91XUuv+QTHDo=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776979411; c=relaxed/simple;\n\tbh=70RKSMZjgbP0ktOPb9PAca2L/0fqqjCC+IMmxSG4xU0=;\n\th=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From:\n\t To:Cc:Content-Type;\n b=BsG6/ocvuLf/wg+OTW0AuFGz9UX9OZGMPtcmGyamI0FA5uGIWF2bCSvt0LJElsVUbAegP0YH1rYu4VI38cSwlzU0EwEllAttEfWYtLijC4/Q+Eiz4gZ7WgApOgQl1c+X1WjrOadyj+dsEhZ9oxtLlCi5E4oycxWoosufywkJBig=", "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=reject dis=none) header.from=google.com;\n spf=pass smtp.mailfrom=flex--dmatlack.bounces.google.com;\n dkim=pass (2048-bit key) header.d=google.com header.i=@google.com\n header.b=k55Wmyda; arc=none smtp.client-ip=209.85.210.202", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=google.com; s=20251104; t=1776979405; x=1777584205;\n darn=vger.kernel.org;\n h=cc:to:from:subject:message-id:references:mime-version:in-reply-to\n :date:from:to:cc:subject:date:message-id:reply-to;\n bh=ZmpZCS6mKPYD/A8Ingq/lQA2gApCpbjA3a6IaVe9Pqc=;\n b=k55WmydafbrWSfuPS88BcRtlnZgnNe4/EFqlmRjFkprYzxrbJTyws+sdBdnQxdjEu/\n RgIUMXa07dOsuGKnGLfuH/vPKEXWcOSouydoDZcWGh4AiAghOmjPhE5dXtWJwzvvIUEU\n PqB5Gyy9szf7gOuDKAxXS9EHxv6hcQnTGm8niDcxxhcdQAqM3SFAr+2LgydV4O3hOCWf\n eoULVmYRFChvKSYJR6feJMB9qg8K7DFXIgQlcUk53XWMAkJHhp3B0585X+05rwuXiBc5\n xv744R30TiGSxEKAiNlNWD0Opt9+s/X/OVYHJs/rkhxxPIi+SWn9r/PRCyJc/aTR8gOB\n 73PA==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1776979405; x=1777584205;\n h=cc:to:from:subject:message-id:references:mime-version:in-reply-to\n :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n bh=ZmpZCS6mKPYD/A8Ingq/lQA2gApCpbjA3a6IaVe9Pqc=;\n b=A8XJMRRk+Pbmey67cwMvjifj/JNkmeG981VfIwGvQK2aDqq+xoPseR8VoAP1syVR+n\n JAZGDgvOZtnpz+xpESxP+LmjGAW9RDEIBk5hjQ+lkyg8Y1UA7i8UCaQmHtjH8pSGLdqT\n 93fWhm0MXGgyPjokMn0PnLR4Y8sYm5GAPXmkAkNrzGFWN4ZjhXOVI8RbpXWa2NcQwVTe\n xw3XWdWQN/J7Hdpn9Vv37H35WJTVGA4z5OVOLZ8Ni9WlRQh/YlWmiHfy8078kIxEvUFd\n IXNlWJUaOsXlCs8ilxp9OTU7GSEZC2HkAg8QSlY3CsTOm9i1sS+SnTgwfx7I5RiTlkLd\n GX1w==", "X-Forwarded-Encrypted": "i=1;\n AFNElJ9XFanJXwdfaN71sOkllds/yIV+QiSZ8Wg+ev3UNYEY0San0wpr6o2UWQ+e77gaKvjWNyAXAQhvhSk=@vger.kernel.org", "X-Gm-Message-State": "AOJu0YxyN2UxHghYaWDj1qMLkRhTWW1gMZYlPPtHB4xoP+N1fTN3OVLY\n\tBSQyUpbJ8fvQa4Qr9Pq5r8tI8DH5zhmgBLpfHiLJ9hC2oCvLgg/lxX8ryBIWBg5f82Yd58MZuHc\n\tTByx/Yo9q7gj7uA==", "X-Received": "from pfav10.prod.google.com ([2002:a05:6a00:ab0a:b0:82f:805:b62a])\n (user=dmatlack job=prod-delivery.src-stubby-dispatcher) by\n 2002:a05:6a00:1993:b0:82c:2241:ab71 with SMTP id\n d2e1a72fcca58-82f8c9718c5mr31412431b3a.42.1776979405031;\n Thu, 23 Apr 2026 14:23:25 -0700 (PDT)", "Date": "Thu, 23 Apr 2026 21:23:07 +0000", "In-Reply-To": "<20260423212316.3431746-1-dmatlack@google.com>", "Precedence": "bulk", "X-Mailing-List": "linux-pci@vger.kernel.org", "List-Id": "<linux-pci.vger.kernel.org>", "List-Subscribe": "<mailto:linux-pci+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-pci+unsubscribe@vger.kernel.org>", "Mime-Version": "1.0", "References": "<20260423212316.3431746-1-dmatlack@google.com>", "X-Mailer": "git-send-email 2.54.0.rc2.544.gc7ae2d5bb8-goog", "Message-ID": "<20260423212316.3431746-4-dmatlack@google.com>", "Subject": "[PATCH v4 03/11] PCI: liveupdate: Track incoming preserved PCI\n devices", "From": "David Matlack <dmatlack@google.com>", "To": "iommu@lists.linux.dev, kexec@lists.infradead.org,\n\tlinux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org,\n\tlinux-pci@vger.kernel.org", "Cc": "Adithya Jayachandran <ajayachandra@nvidia.com>,\n Alexander Graf <graf@amazon.com>,\n\tAlex Williamson <alex@shazbot.org>, Bjorn Helgaas <bhelgaas@google.com>,\n Chris Li <chrisl@kernel.org>,\n\tDavid Matlack <dmatlack@google.com>, David Rientjes <rientjes@google.com>,\n\tJacob Pan <jacob.pan@linux.microsoft.com>, Jason Gunthorpe <jgg@nvidia.com>,\n\tJoerg Roedel <joro@8bytes.org>, Jonathan Corbet <corbet@lwn.net>,\n Josh Hilke <jrhilke@google.com>,\n\tLeon Romanovsky <leonro@nvidia.com>, Lukas Wunner <lukas@wunner.de>,\n Mike Rapoport <rppt@kernel.org>,\n\tParav Pandit <parav@nvidia.com>, Pasha Tatashin <pasha.tatashin@soleen.com>,\n\tPranjal Shrivastava <praan@google.com>, Pratyush Yadav <pratyush@kernel.org>,\n\tRobin Murphy <robin.murphy@arm.com>, Saeed Mahameed <saeedm@nvidia.com>,\n\tSamiullah Khawaja <skhawaja@google.com>,\n Shuah Khan <skhan@linuxfoundation.org>,\n\tWill Deacon <will@kernel.org>, William Tu <witu@nvidia.com>,\n Yi Liu <yi.l.liu@intel.com>", "Content-Type": "text/plain; charset=\"UTF-8\"" }, "content": "During PCI enumeration, the previous kernel might have passed state about\ndevices that were preserved across kexec. The PCI core needs to fetch\nthis state to identify which devices are \"incoming\" and require special\nhandling.\n\nAdd pci_liveupdate_setup_device() which is called during device setup\nto fetch the serialized state (struct pci_ser) from the Live Update\nOrchestrator. The first time this happens, pci_flb_retrieve() will run\nand convert the array of pci_dev_ser structs into an xarray so that it\ncan be looked up efficiently.\n\nIf a device is found in the xarray, the PCI core stores a pointer to its\nstate in dev->liveupdate_incoming and holds a reference to the incoming\nFLB until pci_liveupdate_finish() is called by the driver.\n\nThis ensures proper lifecycle management for incoming preserved devices\nand allows the PCI core and drivers to apply specific Live Update\nlogic to them in subsequent commits.\n\nSigned-off-by: David Matlack <dmatlack@google.com>\n---\n drivers/pci/liveupdate.c | 189 ++++++++++++++++++++++++++++++++++++++-\n drivers/pci/pci.h | 13 +++\n drivers/pci/probe.c | 4 +\n include/linux/pci.h | 16 ++++\n 4 files changed, 218 insertions(+), 4 deletions(-)", "diff": "diff --git a/drivers/pci/liveupdate.c b/drivers/pci/liveupdate.c\nindex 2dd8daa2f17c..e616cecc37c8 100644\n--- a/drivers/pci/liveupdate.c\n+++ b/drivers/pci/liveupdate.c\n@@ -56,6 +56,20 @@\n * This allows the PCI core to keep it's FLB data (struct pci_ser) up to date\n * with the list of **outgoing** preserved devices for the next kernel.\n *\n+ * After kexec, whenever a device is enumerated, the PCI core will check if it\n+ * is an **incoming** preserved device (i.e. preserved by the previous kernel)\n+ * by checking the incoming FLB data (struct pci_ser).\n+ *\n+ * Drivers must notify the PCI core when an **incoming** device is done\n+ * participating in the incoming Live Update with the following API:\n+ *\n+ * * ``pci_liveupdate_finish(pci_dev)``\n+ *\n+ * The PCI core does not enforce any ordering of ``pci_liveupdate_finish()`` and\n+ * ``pci_liveupdate_preserve()``. i.e. A PCI device can be **outgoing**\n+ * (preserved for next kernel) and **incoming** (preserved by previous kernel)\n+ * at the same time.\n+ *\n * Restrictions\n * ============\n *\n@@ -67,7 +81,6 @@\n \n #define pr_fmt(fmt) \"PCI: liveupdate: \" fmt\n \n-#include <linux/bsearch.h>\n #include <linux/io.h>\n #include <linux/kexec_handover.h>\n #include <linux/kho/abi/pci.h>\n@@ -75,10 +88,24 @@\n #include <linux/mutex.h>\n #include <linux/mm.h>\n #include <linux/pci.h>\n-#include <linux/sort.h>\n+\n+#include \"pci.h\"\n \n static DEFINE_MUTEX(pci_flb_outgoing_lock);\n \n+struct pci_flb_incoming {\n+\t/* The pci_ser struct passed by the previous kernel. */\n+\tstruct pci_ser *ser;\n+\n+\t/* xarray used to quickly find a device in ser->devices[] */\n+\tstruct xarray xa;\n+};\n+\n+static unsigned long pci_ser_xa_key(unsigned long domain, unsigned long bdf)\n+{\n+\treturn domain << 16 | bdf;\n+}\n+\n static int pci_flb_preserve(struct liveupdate_flb_op_args *args)\n {\n \tstruct pci_dev *dev = NULL;\n@@ -124,13 +151,44 @@ static void pci_flb_unpreserve(struct liveupdate_flb_op_args *args)\n \n static int pci_flb_retrieve(struct liveupdate_flb_op_args *args)\n {\n-\targs->obj = phys_to_virt(args->data);\n+\tstruct pci_flb_incoming *incoming;\n+\tint i, ret;\n+\n+\tincoming = kmalloc(sizeof(*incoming), GFP_KERNEL);\n+\tif (!incoming)\n+\t\treturn -ENOMEM;\n+\n+\tincoming->ser = phys_to_virt(args->data);\n+\n+\txa_init(&incoming->xa);\n+\n+\tfor (i = 0; i < incoming->ser->max_nr_devices; i++) {\n+\t\tstruct pci_dev_ser *dev_ser = &incoming->ser->devices[i];\n+\t\tunsigned long key;\n+\n+\t\tif (!dev_ser->refcount)\n+\t\t\tcontinue;\n+\n+\t\tkey = pci_ser_xa_key(dev_ser->domain, dev_ser->bdf);\n+\t\tret = xa_err(xa_store(&incoming->xa, key, dev_ser, GFP_KERNEL));\n+\t\tif (ret) {\n+\t\t\txa_destroy(&incoming->xa);\n+\t\t\tkfree(incoming);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\targs->obj = incoming;\n \treturn 0;\n }\n \n static void pci_flb_finish(struct liveupdate_flb_op_args *args)\n {\n-\tkho_restore_free(args->obj);\n+\tstruct pci_flb_incoming *incoming = args->obj;\n+\n+\txa_destroy(&incoming->xa);\n+\tkho_restore_free(incoming->ser);\n+\tkfree(incoming);\n }\n \n static struct liveupdate_flb_ops pci_liveupdate_flb_ops = {\n@@ -225,6 +283,129 @@ void pci_liveupdate_unpreserve(struct pci_dev *dev)\n }\n EXPORT_SYMBOL_GPL(pci_liveupdate_unpreserve);\n \n+static struct xarray *pci_liveupdate_flb_get_incoming(void)\n+{\n+\tstruct pci_flb_incoming *incoming;\n+\tint ret;\n+\n+\tret = liveupdate_flb_get_incoming(&pci_liveupdate_flb, (void **)&incoming);\n+\n+\t/* Live Update is not enabled. */\n+\tif (ret == -EOPNOTSUPP)\n+\t\treturn NULL;\n+\n+\t/* Live Update is enabled, but there is no incoming FLB data. */\n+\tif (ret == -ENODATA)\n+\t\treturn NULL;\n+\n+\t/*\n+\t * Live Update is enabled and there is incoming FLB data, but none of it\n+\t * matches pci_liveupdate_flb.compatible.\n+\t *\n+\t * This could mean that no PCI FLB data was passed by the previous\n+\t * kernel, but it could also mean the previous kernel used a different\n+\t * compatibility string (i.e. a different ABI).\n+\t */\n+\tif (ret == -ENOENT) {\n+\t\tpr_info_once(\"No incoming FLB matched %s\\n\", pci_liveupdate_flb.compatible);\n+\t\treturn NULL;\n+\t}\n+\n+\t/*\n+\t * There is incoming FLB data that matches pci_liveupdate_flb.compatible\n+\t * but it cannot be retrieved.\n+\t */\n+\tif (ret) {\n+\t\tWARN_ONCE(ret, \"Failed to retrieve incoming FLB data\\n\");\n+\t\treturn NULL;\n+\t}\n+\n+\treturn &incoming->xa;\n+}\n+\n+static void pci_liveupdate_flb_put_incoming(void)\n+{\n+\tliveupdate_flb_put_incoming(&pci_liveupdate_flb);\n+}\n+\n+void pci_liveupdate_setup_device(struct pci_dev *dev)\n+{\n+\tstruct pci_dev_ser *dev_ser;\n+\tstruct xarray *xa;\n+\tunsigned long key;\n+\n+\txa = pci_liveupdate_flb_get_incoming();\n+\tif (!xa)\n+\t\treturn;\n+\n+\tkey = pci_ser_xa_key(pci_domain_nr(dev->bus), pci_dev_id(dev));\n+\tdev_ser = xa_load(xa, key);\n+\n+\t/* This device was not preserved across Live Update */\n+\tif (!dev_ser) {\n+\t\tpci_liveupdate_flb_put_incoming();\n+\t\treturn;\n+\t}\n+\n+\t/*\n+\t * This device was preserved, but has already been probed and gone\n+\t * through pci_liveupdate_finish(). This can happen if PCI core probes\n+\t * the same device multiple times, e.g. due to hotplug.\n+\t */\n+\tif (!dev_ser->refcount) {\n+\t\tpci_liveupdate_flb_put_incoming();\n+\t\treturn;\n+\t}\n+\n+\tpci_info(dev, \"Device was preserved by previous kernel across Live Update\\n\");\n+\n+\t/*\n+\t * Hold the ref on the incoming FLB until pci_liveupdate_finish() so\n+\t * that dev_ser does not get freed while it is in use.\n+\t */\n+\tdev->liveupdate_incoming = dev_ser;\n+}\n+\n+void pci_liveupdate_cleanup_device(struct pci_dev *dev)\n+{\n+\t/*\n+\t * Drop the FLB reference acquired in pci_liveupdate_setup_device() if\n+\t * the device is being cleaned up before pci_liveupdate_finish(), e.g.\n+\t * due to allocation failure during setup.\n+\t *\n+\t * Do not drop dev->liveupdate_incoming->refcount since this device has\n+\t * not gone through pci_liveupdate_finish() and thus is still an\n+\t * incoming preserved device.\n+\t *\n+\t * Note: This cannot race with pci_liveupdate_finish() since it is only\n+\t * called in cleanup paths when there are no users of the pci_dev.\n+\t */\n+\tif (dev->liveupdate_incoming)\n+\t\tpci_liveupdate_flb_put_incoming();\n+}\n+\n+void pci_liveupdate_finish(struct pci_dev *dev)\n+{\n+\tif (!dev->liveupdate_incoming) {\n+\t\tpci_warn(dev, \"Cannot finish preserving an unpreserved device\\n\");\n+\t\treturn;\n+\t}\n+\n+\tpci_info(dev, \"Device is finished participating in Live Update\\n\");\n+\n+\t/*\n+\t * Drop the refcount so this device does not get treated as an incoming\n+\t * device again, e.g. in case pci_liveupdate_setup_device() gets called\n+\t * again becase the device is hot-plugged.\n+\t */\n+\tdev->liveupdate_incoming->refcount = 0;\n+\tdev->liveupdate_incoming = NULL;\n+\n+\t/* Drop this device's reference on the incoming FLB. */\n+\tpci_liveupdate_flb_put_incoming();\n+}\n+EXPORT_SYMBOL_GPL(pci_liveupdate_finish);\n+\n int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh)\n {\n \tpr_debug(\"Registering file handler \\\"%s\\\"\\n\", fh->compatible);\ndiff --git a/drivers/pci/pci.h b/drivers/pci/pci.h\nindex 4a14f88e543a..09bab39738d7 100644\n--- a/drivers/pci/pci.h\n+++ b/drivers/pci/pci.h\n@@ -1439,4 +1439,17 @@ static inline int pci_msix_write_tph_tag(struct pci_dev *pdev, unsigned int inde\n \t(PCI_CONF1_ADDRESS(bus, dev, func, reg) | \\\n \t PCI_CONF1_EXT_REG(reg))\n \n+#ifdef CONFIG_PCI_LIVEUPDATE\n+void pci_liveupdate_setup_device(struct pci_dev *dev);\n+void pci_liveupdate_cleanup_device(struct pci_dev *dev);\n+#else\n+static inline void pci_liveupdate_setup_device(struct pci_dev *dev)\n+{\n+}\n+\n+static inline void pci_liveupdate_cleanup_device(struct pci_dev *dev)\n+{\n+}\n+#endif\n+\n #endif /* DRIVERS_PCI_H */\ndiff --git a/drivers/pci/probe.c b/drivers/pci/probe.c\nindex b63cd0c310bc..938a28e4a7a0 100644\n--- a/drivers/pci/probe.c\n+++ b/drivers/pci/probe.c\n@@ -2069,6 +2069,8 @@ int pci_setup_device(struct pci_dev *dev)\n \tif (pci_early_dump)\n \t\tearly_dump_pci_device(dev);\n \n+\tpci_liveupdate_setup_device(dev);\n+\n \t/* Need to have dev->class ready */\n \tdev->cfg_size = pci_cfg_space_size(dev);\n \n@@ -2192,6 +2194,7 @@ int pci_setup_device(struct pci_dev *dev)\n \tdefault:\t\t\t\t /* unknown header */\n \t\tpci_err(dev, \"unknown header type %02x, ignoring device\\n\",\n \t\t\tdev->hdr_type);\n+\t\tpci_liveupdate_cleanup_device(dev);\n \t\tpci_release_of_node(dev);\n \t\treturn -EIO;\n \n@@ -2490,6 +2493,7 @@ static void pci_release_dev(struct device *dev)\n \n \tpci_dev = to_pci_dev(dev);\n \tpci_release_capabilities(pci_dev);\n+\tpci_liveupdate_cleanup_device(pci_dev);\n \tpci_release_of_node(pci_dev);\n \tpcibios_release_device(pci_dev);\n \tpci_bus_put(pci_dev->bus);\ndiff --git a/include/linux/pci.h b/include/linux/pci.h\nindex eb94cbd8ab9d..dd6b26ca9462 100644\n--- a/include/linux/pci.h\n+++ b/include/linux/pci.h\n@@ -597,6 +597,7 @@ struct pci_dev {\n #endif\n #ifdef CONFIG_PCI_LIVEUPDATE\n \tstruct pci_dev_ser *liveupdate_outgoing; /* State preserved for next kernel */\n+\tstruct pci_dev_ser *liveupdate_incoming; /* State preserved by previous kernel */\n #endif\n };\n \n@@ -2887,11 +2888,17 @@ void pci_liveupdate_unregister_flb(struct liveupdate_file_handler *fh);\n \n int pci_liveupdate_preserve(struct pci_dev *dev);\n void pci_liveupdate_unpreserve(struct pci_dev *dev);\n+void pci_liveupdate_finish(struct pci_dev *dev);\n \n static inline struct pci_dev_ser *pci_liveupdate_outgoing(struct pci_dev *dev)\n {\n \treturn dev->liveupdate_outgoing;\n }\n+\n+static inline struct pci_dev_ser *pci_liveupdate_incoming(struct pci_dev *dev)\n+{\n+\treturn dev->liveupdate_incoming;\n+}\n #else\n static inline int pci_liveupdate_register_flb(struct liveupdate_file_handler *fh)\n {\n@@ -2911,10 +2918,19 @@ static inline void pci_liveupdate_unpreserve(struct pci_dev *dev)\n {\n }\n \n+static inline void pci_liveupdate_finish(struct pci_dev *dev)\n+{\n+}\n+\n static inline struct pci_dev_ser *pci_liveupdate_outgoing(struct pci_dev *dev)\n {\n \treturn NULL;\n }\n+\n+static inline struct pci_dev_ser *pci_liveupdate_incoming(struct pci_dev *dev)\n+{\n+\treturn NULL;\n+}\n #endif\n \n #endif /* LINUX_PCI_H */\n", "prefixes": [ "v4", "03/11" ] }