qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kurz <groug@kaod.org>
To: qemu-devel@nongnu.org
Cc: Igor Mammedov <imammedo@redhat.com>,
	qemu-ppc@nongnu.org, Greg Kurz <groug@kaod.org>,
	David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH for-6.0 1/9] spapr: Do PCI device hotplug sanity checks at pre-plug only
Date: Sat, 21 Nov 2020 00:42:00 +0100	[thread overview]
Message-ID: <20201120234208.683521-2-groug@kaod.org> (raw)
In-Reply-To: <20201120234208.683521-1-groug@kaod.org>

The PHB acts as the hotplug handler for PCI devices. It does some
sanity checks on DR enablement, PCI bridge chassis numbers and
multifunction. These checks are currently performed at plug time,
but they would best sit in a pre-plug handler in order to error
out as early as possible.

Create a spapr_pci_pre_plug() handler and move all the checking
there. Add a check that the associated DRC doesn't already have
an attached device. This is equivalent to the slot availability
check performed by do_pci_register_device() upon realization of
the PCI device.

This allows to pass &error_abort to spapr_drc_attach() and to end
up with a plug handler that doesn't need to report errors anymore.

Signed-off-by: Greg Kurz <groug@kaod.org>
---
 hw/ppc/spapr_pci.c | 43 +++++++++++++++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 88ce87f130a5..2829f298d9c1 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1532,8 +1532,8 @@ static bool bridge_has_valid_chassis_nr(Object *bridge, Error **errp)
     return true;
 }
 
-static void spapr_pci_plug(HotplugHandler *plug_handler,
-                           DeviceState *plugged_dev, Error **errp)
+static void spapr_pci_pre_plug(HotplugHandler *plug_handler,
+                               DeviceState *plugged_dev, Error **errp)
 {
     SpaprPhbState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
     PCIDevice *pdev = PCI_DEVICE(plugged_dev);
@@ -1542,9 +1542,6 @@ static void spapr_pci_plug(HotplugHandler *plug_handler,
     PCIBus *bus = PCI_BUS(qdev_get_parent_bus(DEVICE(pdev)));
     uint32_t slotnr = PCI_SLOT(pdev->devfn);
 
-    /* if DR is disabled we don't need to do anything in the case of
-     * hotplug or coldplug callbacks
-     */
     if (!phb->dr_enabled) {
         /* if this is a hotplug operation initiated by the user
          * we need to let them know it's not enabled
@@ -1552,17 +1549,14 @@ static void spapr_pci_plug(HotplugHandler *plug_handler,
         if (plugged_dev->hotplugged) {
             error_setg(errp, QERR_BUS_NO_HOTPLUG,
                        object_get_typename(OBJECT(phb)));
+            return;
         }
-        return;
     }
 
-    g_assert(drc);
-
     if (pc->is_bridge) {
         if (!bridge_has_valid_chassis_nr(OBJECT(plugged_dev), errp)) {
             return;
         }
-        spapr_pci_bridge_plug(phb, PCI_BRIDGE(plugged_dev));
     }
 
     /* Following the QEMU convention used for PCIe multifunction
@@ -1574,13 +1568,41 @@ static void spapr_pci_plug(HotplugHandler *plug_handler,
         error_setg(errp, "PCI: slot %d function 0 already occupied by %s,"
                    " additional functions can no longer be exposed to guest.",
                    slotnr, bus->devices[PCI_DEVFN(slotnr, 0)]->name);
+    }
+
+    if (drc && drc->dev) {
+        error_setg(errp, "PCI: slot %d already occupied by %s", slotnr,
+                   pci_get_function_0(PCI_DEVICE(drc->dev))->name);
         return;
     }
+}
+
+static void spapr_pci_plug(HotplugHandler *plug_handler,
+                           DeviceState *plugged_dev, Error **errp)
+{
+    SpaprPhbState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
+    PCIDevice *pdev = PCI_DEVICE(plugged_dev);
+    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(plugged_dev);
+    SpaprDrc *drc = drc_from_dev(phb, pdev);
+    uint32_t slotnr = PCI_SLOT(pdev->devfn);
 
-    if (!spapr_drc_attach(drc, DEVICE(pdev), errp)) {
+    /*
+     * If DR is disabled we don't need to do anything in the case of
+     * hotplug or coldplug callbacks.
+     */
+    if (!phb->dr_enabled) {
         return;
     }
 
+    g_assert(drc);
+
+    if (pc->is_bridge) {
+        spapr_pci_bridge_plug(phb, PCI_BRIDGE(plugged_dev));
+    }
+
+    /* spapr_pci_pre_plug() already checked the DRC is attachable */
+    spapr_drc_attach(drc, DEVICE(pdev), &error_abort);
+
     /* If this is function 0, signal hotplug for all the device functions.
      * Otherwise defer sending the hotplug event.
      */
@@ -2223,6 +2245,7 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
     /* Supported by TYPE_SPAPR_MACHINE */
     dc->user_creatable = true;
     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+    hp->pre_plug = spapr_pci_pre_plug;
     hp->plug = spapr_pci_plug;
     hp->unplug = spapr_pci_unplug;
     hp->unplug_request = spapr_pci_unplug_request;
-- 
2.26.2



  reply	other threads:[~2020-11-20 23:46 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-20 23:41 [PATCH for-6.0 0/9] spapr: Perform hotplug sanity checks at pre-plug Greg Kurz
2020-11-20 23:42 ` Greg Kurz [this message]
2020-11-23  4:50   ` [PATCH for-6.0 1/9] spapr: Do PCI device hotplug sanity checks at pre-plug only David Gibson
2020-11-20 23:42 ` [PATCH for-6.0 2/9] spapr: Do NVDIMM/PC-DIMM " Greg Kurz
2020-11-23  4:55   ` David Gibson
2020-11-20 23:42 ` [PATCH for-6.0 3/9] spapr: Fix pre-2.10 dummy ICP hack Greg Kurz
2020-11-23  5:03   ` David Gibson
2020-11-20 23:42 ` [PATCH for-6.0 4/9] spapr: Set compat mode in spapr_reset_vcpu() Greg Kurz
2020-11-23  5:11   ` David Gibson
2020-11-23 11:51     ` Greg Kurz
2020-11-25  2:39       ` David Gibson
2020-11-25  9:51         ` Greg Kurz
2020-11-26  4:57           ` David Gibson
2020-11-26  9:10             ` Greg Kurz
2020-11-26 16:23               ` Igor Mammedov
2020-11-26 20:53                 ` Igor Mammedov
2020-11-27  4:59               ` David Gibson
2020-11-27 13:25                 ` Greg Kurz
2020-11-20 23:42 ` [PATCH for-6.0 5/9] spapr: Simplify error path of spapr_core_plug() Greg Kurz
2020-11-23  5:13   ` David Gibson
2020-11-24 13:07     ` Greg Kurz
2020-11-25  2:40       ` David Gibson
2020-11-20 23:42 ` [PATCH for-6.0 6/9] spapr: Make PHB placement functions and spapr_pre_plug_phb() return status Greg Kurz
2020-11-23  5:14   ` David Gibson
2020-11-20 23:42 ` [PATCH for-6.0 7/9] spapr: Do PHB hoplug sanity check at pre-plug Greg Kurz
2020-11-23  5:26   ` David Gibson
2020-11-20 23:42 ` [PATCH for-6.0 8/9] spapr: Do TPM proxy hotplug sanity checks " Greg Kurz
2020-11-23  5:32   ` David Gibson
2020-11-20 23:42 ` [PATCH for-6.0 9/9] spapr: spapr_drc_attach() cannot fail Greg Kurz
2020-11-23  5:34   ` David Gibson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201120234208.683521-2-groug@kaod.org \
    --to=groug@kaod.org \
    --cc=david@gibson.dropbear.id.au \
    --cc=imammedo@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).