From nobody Fri May 3 09:07:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 154886404757275.58543122845583; Wed, 30 Jan 2019 08:00:47 -0800 (PST) Received: from localhost ([127.0.0.1]:40260 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gosI8-0000ns-Ru for importer@patchew.org; Wed, 30 Jan 2019 11:00:44 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46774) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gosFJ-00074G-Ez for qemu-devel@nongnu.org; Wed, 30 Jan 2019 10:57:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gosFH-0008Tg-Ez for qemu-devel@nongnu.org; Wed, 30 Jan 2019 10:57:49 -0500 Received: from mx1.redhat.com ([209.132.183.28]:57754) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gosFG-0008Ps-VH; Wed, 30 Jan 2019 10:57:47 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 29AFD64385; Wed, 30 Jan 2019 15:57:41 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4D4BB1A914; Wed, 30 Jan 2019 15:57:39 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Date: Wed, 30 Jan 2019 16:57:28 +0100 Message-Id: <20190130155733.32742-2-david@redhat.com> In-Reply-To: <20190130155733.32742-1-david@redhat.com> References: <20190130155733.32742-1-david@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 30 Jan 2019 15:57:41 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 1/6] s390x/pci: Fix primary bus number for PCI bridges X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Pierre Morel , David Hildenbrand , Cornelia Huck , Collin Walling , Christian Borntraeger , qemu-s390x@nongnu.org, Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The primary bus number corresponds always to the bus number of the bus the bridge is attached to. Right now, if we have two bridges attached to the same bus (e.g. root bus) this is however not the case. The first bridge will have primary bus 0, the second bridge primary bus 1, which is wrong. Fix the assignment. While at it, drop setting the PCI_SUBORDINATE_BUS temporarily to 0xff. Setting it temporarily to that value (as discussed e.g. in [1]), is only relevant for a running system that probes the buses. The value is effectively unused for us just doing a DFS. Also add a comment why we have to reassign during every reset (which I found to be surprising. Please note that hotplugging of bridges is in general still broken, will be fixed next. [1] http://www.science.unitn.it/~fiorella/guidelinux/tlk/node76.html Reviewed-by: Thomas Huth Signed-off-by: David Hildenbrand Reviewed-by: Collin Walling --- hw/s390x/s390-pci-bus.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index f017c1ded0..b7c4613fde 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -862,7 +862,8 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_d= ev, DeviceState *dev, qbus_set_hotplug_handler(bus, DEVICE(s), errp); =20 if (dev->hotplugged) { - pci_default_write_config(pdev, PCI_PRIMARY_BUS, s->bus_no, 1); + pci_default_write_config(pdev, PCI_PRIMARY_BUS, + pci_dev_bus_num(pdev), 1); s->bus_no +=3D 1; pci_default_write_config(pdev, PCI_SECONDARY_BUS, s->bus_no, 1= ); do { @@ -1016,8 +1017,6 @@ static void s390_pci_enumerate_bridge(PCIBus *bus, PC= IDevice *pdev, void *opaque) { S390pciState *s =3D opaque; - unsigned int primary =3D s->bus_no; - unsigned int subordinate =3D 0xff; PCIBus *sec_bus =3D NULL; =20 if ((pci_default_read_config(pdev, PCI_HEADER_TYPE, 1) !=3D @@ -1026,7 +1025,7 @@ static void s390_pci_enumerate_bridge(PCIBus *bus, PC= IDevice *pdev, } =20 (s->bus_no)++; - pci_default_write_config(pdev, PCI_PRIMARY_BUS, primary, 1); + pci_default_write_config(pdev, PCI_PRIMARY_BUS, pci_dev_bus_num(pdev),= 1); pci_default_write_config(pdev, PCI_SECONDARY_BUS, s->bus_no, 1); pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, s->bus_no, 1); =20 @@ -1035,7 +1034,7 @@ static void s390_pci_enumerate_bridge(PCIBus *bus, PC= IDevice *pdev, return; } =20 - pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, subordinate, 1); + /* Assign numbers to all child bridges. The last is the highest number= . */ pci_for_each_device(sec_bus, pci_bus_num(sec_bus), s390_pci_enumerate_bridge, s); pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, s->bus_no, 1); @@ -1046,6 +1045,10 @@ static void s390_pcihost_reset(DeviceState *dev) S390pciState *s =3D S390_PCI_HOST_BRIDGE(dev); PCIBus *bus =3D s->parent_obj.bus; =20 + /* + * When resetting a PCI bridge, the assigned numbers are set to 0. So + * on every system reset, we also have to reassign numbers. + */ s->bus_no =3D 0; pci_for_each_device(bus, pci_bus_num(bus), s390_pci_enumerate_bridge, = s); } --=20 2.17.2 From nobody Fri May 3 09:07:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1548864150568922.6201853620483; Wed, 30 Jan 2019 08:02:30 -0800 (PST) Received: from localhost ([127.0.0.1]:40300 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gosJo-0002DT-OD for importer@patchew.org; Wed, 30 Jan 2019 11:02:28 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46812) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gosFK-00074w-Hq for qemu-devel@nongnu.org; Wed, 30 Jan 2019 10:57:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gosFJ-0008VC-Dv for qemu-devel@nongnu.org; Wed, 30 Jan 2019 10:57:50 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41670) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gosFH-0008R9-Gu; Wed, 30 Jan 2019 10:57:47 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4E7D1ED279; Wed, 30 Jan 2019 15:57:43 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 70001452C; Wed, 30 Jan 2019 15:57:41 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Date: Wed, 30 Jan 2019 16:57:29 +0100 Message-Id: <20190130155733.32742-3-david@redhat.com> In-Reply-To: <20190130155733.32742-1-david@redhat.com> References: <20190130155733.32742-1-david@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 30 Jan 2019 15:57:43 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 2/6] s390x/pci: Fix hotplugging of PCI bridges X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Pierre Morel , David Hildenbrand , Cornelia Huck , Collin Walling , Christian Borntraeger , qemu-s390x@nongnu.org, Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" When hotplugging a PCI bridge right now to the root port, we resolve pci_get_bus(pdev)->parent_dev, which results in a SEGFAULT. Hotplugging really only works right now when hotplugging to another bridge. Instead, we have to properly check if we are already at the root. Let's cleanup the code while at it a bit and factor out updating the subordiante bus number into a separate function. The check for "old_nr < nr" is right now not strictly necessary, but makes it more obvious what is actually going on. Most probably fixing up the topology is not our responsibility when hotplugging. The guest has to sort this out. But let's keep it for now and only fix current code to not crash. Reviewed-by: Thomas Huth Signed-off-by: David Hildenbrand Reviewed-by: Collin Walling --- hw/s390x/s390-pci-bus.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index b7c4613fde..9b5c5fff60 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -843,6 +843,21 @@ static void s390_pcihost_pre_plug(HotplugHandler *hotp= lug_dev, DeviceState *dev, } } =20 +static void s390_pci_update_subordinate(PCIDevice *dev, uint32_t nr) +{ + uint32_t old_nr; + + pci_default_write_config(dev, PCI_SUBORDINATE_BUS, nr, 1); + while (!pci_bus_is_root(pci_get_bus(dev))) { + dev =3D pci_get_bus(dev)->parent_dev; + + old_nr =3D pci_default_read_config(dev, PCI_SUBORDINATE_BUS, 1); + if (old_nr < nr) { + pci_default_write_config(dev, PCI_SUBORDINATE_BUS, nr, 1); + } + } +} + static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *de= v, Error **errp) { @@ -851,26 +866,21 @@ static void s390_pcihost_plug(HotplugHandler *hotplug= _dev, DeviceState *dev, S390PCIBusDevice *pbdev =3D NULL; =20 if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) { - BusState *bus; PCIBridge *pb =3D PCI_BRIDGE(dev); - PCIDevice *pdev =3D PCI_DEVICE(dev); =20 + pdev =3D PCI_DEVICE(dev); pci_bridge_map_irq(pb, dev->id, s390_pci_map_irq); pci_setup_iommu(&pb->sec_bus, s390_pci_dma_iommu, s); =20 - bus =3D BUS(&pb->sec_bus); - qbus_set_hotplug_handler(bus, DEVICE(s), errp); + qbus_set_hotplug_handler(BUS(&pb->sec_bus), DEVICE(s), errp); =20 if (dev->hotplugged) { pci_default_write_config(pdev, PCI_PRIMARY_BUS, pci_dev_bus_num(pdev), 1); s->bus_no +=3D 1; pci_default_write_config(pdev, PCI_SECONDARY_BUS, s->bus_no, 1= ); - do { - pdev =3D pci_get_bus(pdev)->parent_dev; - pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, - s->bus_no, 1); - } while (pci_get_bus(pdev) && pci_dev_bus_num(pdev)); + + s390_pci_update_subordinate(pdev, s->bus_no); } } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { pdev =3D PCI_DEVICE(dev); --=20 2.17.2 From nobody Fri May 3 09:07:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1548863987567977.9695256686349; Wed, 30 Jan 2019 07:59:47 -0800 (PST) Received: from localhost ([127.0.0.1]:40238 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gosHC-0008Sv-6O for importer@patchew.org; Wed, 30 Jan 2019 10:59:46 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46804) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gosFK-00074m-8J for qemu-devel@nongnu.org; Wed, 30 Jan 2019 10:57:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gosFJ-0008V5-Dc for qemu-devel@nongnu.org; Wed, 30 Jan 2019 10:57:50 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46032) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gosFH-0008SM-Ff; Wed, 30 Jan 2019 10:57:47 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 76B72356FE; Wed, 30 Jan 2019 15:57:45 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9695E452C; Wed, 30 Jan 2019 15:57:43 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Date: Wed, 30 Jan 2019 16:57:30 +0100 Message-Id: <20190130155733.32742-4-david@redhat.com> In-Reply-To: <20190130155733.32742-1-david@redhat.com> References: <20190130155733.32742-1-david@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Wed, 30 Jan 2019 15:57:45 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 3/6] s390x/pci: Warn when adding PCI devices without the 'zpci' feature X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Pierre Morel , David Hildenbrand , Cornelia Huck , Collin Walling , Christian Borntraeger , qemu-s390x@nongnu.org, Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" We decided to always create the PCI host bridge, even if 'zpci' is not enabled (due to migration compatibility). This however right now allows to add zPCI/PCI devices to a VM although the guest will never actually see them, confusing people that are using a simple CPU model that has no 'zpci' enabled - "Why isn't this working" (David Hildenbrand) Let's check for 'zpci' and at least print a warning that this will not work as expected. We could also bail out, however that might break existing QEMU commandlines. Reviewed-by: Thomas Huth Signed-off-by: David Hildenbrand Reviewed-by: Collin Walling --- hw/s390x/s390-pci-bus.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index 9b5c5fff60..2efd9186c2 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -826,6 +826,11 @@ static void s390_pcihost_pre_plug(HotplugHandler *hotp= lug_dev, DeviceState *dev, { S390pciState *s =3D S390_PCI_HOST_BRIDGE(hotplug_dev); =20 + if (!s390_has_feat(S390_FEAT_ZPCI)) { + warn_report("PCI/zPCI device without the 'zpci' CPU feature." + " The guest will not be able to see/use this device"); + } + if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { PCIDevice *pdev =3D PCI_DEVICE(dev); =20 --=20 2.17.2 From nobody Fri May 3 09:07:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1548864149894516.0735635964974; Wed, 30 Jan 2019 08:02:29 -0800 (PST) Received: from localhost ([127.0.0.1]:40298 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gosJn-0002Bu-7g for importer@patchew.org; Wed, 30 Jan 2019 11:02:27 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46846) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gosFL-00075b-F3 for qemu-devel@nongnu.org; Wed, 30 Jan 2019 10:57:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gosFJ-0008Vo-LW for qemu-devel@nongnu.org; Wed, 30 Jan 2019 10:57:51 -0500 Received: from mx1.redhat.com ([209.132.183.28]:42734) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gosFJ-0008U4-Ca; Wed, 30 Jan 2019 10:57:49 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A8F9B811D6; Wed, 30 Jan 2019 15:57:47 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id BC1AF452C; Wed, 30 Jan 2019 15:57:45 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Date: Wed, 30 Jan 2019 16:57:31 +0100 Message-Id: <20190130155733.32742-5-david@redhat.com> In-Reply-To: <20190130155733.32742-1-david@redhat.com> References: <20190130155733.32742-1-david@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 30 Jan 2019 15:57:47 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 4/6] s390x/pci: Introduce unplug requests and split unplug handler X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Pierre Morel , David Hildenbrand , Cornelia Huck , Collin Walling , Christian Borntraeger , qemu-s390x@nongnu.org, Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" PCI on s390x is really weird and how it was modeled in QEMU might not have been the right choice. Anyhow, right now it is the case that: - Hotplugging a PCI device will silently create a zPCI device (if none is provided) - Hotunplugging a zPCI device will unplug the PCI device (if any) - Hotunplugging a PCI device will unplug also the zPCI device As far as I can see, we can no longer change this behavior. But we should fix it. Both device types are handled via a single hotplug handler call. This is problematic for various reasons: 1. Unplugging via the zPCI device allows to unplug devices that are not hot removable. (check performed in qdev_unplug()) - bad. 2. Hotplug handler chains are not possible for the unplug case. In the future, the machine might want to override hotplug handlers, to process device specific stuff and to then branch off to the actual hotplug handler. We need separate hotplug handler calls for both the PCI and zPCI device to make this work reliably. All other PCI implementations are already prepared to handle this correctly, only s390x is missing. Therefore, introduce the unplug_request handler and properly perform unplug checks by redirecting to the separate unplug_request handlers. When finally unplugging, perform two separate hotplug_handler_unplug() calls, first for the PCI device, followed by the zPCI device. This now nicely splits unplugging paths for both devices. The redirect part is a little hairy, as the user is allowed to trigger unplug either via the PCI or the zPCI device. So redirect always to the PCI unplug request handler first and remember if that check has been performed in the zPCI device. Redirect then to the zPCI device unplug request handler to perform the magic. Remembering that we already checked the PCI device breaks the redirect loop. Signed-off-by: David Hildenbrand Reviewed-by: Collin Walling --- hw/s390x/s390-pci-bus.c | 166 +++++++++++++++++++++++++++------------- hw/s390x/s390-pci-bus.h | 1 + 2 files changed, 113 insertions(+), 54 deletions(-) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index 2efd9186c2..e84e00d20c 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -148,6 +148,22 @@ out: psccb->header.response_code =3D cpu_to_be16(rc); } =20 +static void s390_pci_perform_unplug(S390PCIBusDevice *pbdev) +{ + HotplugHandler *hotplug_ctrl; + + /* Unplug the PCI device */ + if (pbdev->pdev) { + hotplug_ctrl =3D qdev_get_hotplug_handler(DEVICE(pbdev->pdev)); + hotplug_handler_unplug(hotplug_ctrl, DEVICE(pbdev->pdev), + &error_abort); + } + + /* Unplug the zPCI device */ + hotplug_ctrl =3D qdev_get_hotplug_handler(DEVICE(pbdev)); + hotplug_handler_unplug(hotplug_ctrl, DEVICE(pbdev), &error_abort); +} + void s390_pci_sclp_deconfigure(SCCB *sccb) { IoaCfgSccb *psccb =3D (IoaCfgSccb *)sccb; @@ -179,7 +195,7 @@ void s390_pci_sclp_deconfigure(SCCB *sccb) rc =3D SCLP_RC_NORMAL_COMPLETION; =20 if (pbdev->release_timer) { - qdev_unplug(DEVICE(pbdev->pdev), NULL); + s390_pci_perform_unplug(pbdev); } } out: @@ -217,6 +233,24 @@ S390PCIBusDevice *s390_pci_find_dev_by_target(S390pciS= tate *s, return NULL; } =20 +static S390PCIBusDevice *s390_pci_find_dev_by_pci(S390pciState *s, + PCIDevice *pci_dev) +{ + S390PCIBusDevice *pbdev; + + if (!pci_dev) { + return NULL; + } + + QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) { + if (pbdev->pdev =3D=3D pci_dev) { + return pbdev; + } + } + + return NULL; +} + S390PCIBusDevice *s390_pci_find_dev_by_idx(S390pciState *s, uint32_t idx) { return g_hash_table_lookup(s->zpci_table, &idx); @@ -955,77 +989,100 @@ static void s390_pcihost_timer_cb(void *opaque) pbdev->state =3D ZPCI_FS_STANDBY; s390_pci_generate_plug_event(HP_EVENT_CONFIGURED_TO_STBRES, pbdev->fh, pbdev->fid); - qdev_unplug(DEVICE(pbdev), NULL); + s390_pci_perform_unplug(pbdev); } =20 static void s390_pcihost_unplug(HotplugHandler *hotplug_dev, DeviceState *= dev, Error **errp) { S390pciState *s =3D S390_PCI_HOST_BRIDGE(hotplug_dev); - PCIDevice *pci_dev =3D NULL; - PCIBus *bus; - int32_t devfn; S390PCIBusDevice *pbdev =3D NULL; =20 + if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { + PCIDevice *pci_dev =3D PCI_DEVICE(dev); + PCIBus *bus; + int32_t devfn; + + pbdev =3D s390_pci_find_dev_by_pci(s, PCI_DEVICE(dev)); + g_assert(pbdev); + + s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED, + pbdev->fh, pbdev->fid); + bus =3D pci_get_bus(pci_dev); + devfn =3D pci_dev->devfn; + object_unparent(OBJECT(pci_dev)); + + s390_pci_msix_free(pbdev); + s390_pci_iommu_free(s, bus, devfn); + pbdev->pdev =3D NULL; + pbdev->state =3D ZPCI_FS_RESERVED; + } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) { + pbdev =3D S390_PCI_DEVICE(dev); + + if (pbdev->release_timer) { + timer_del(pbdev->release_timer); + timer_free(pbdev->release_timer); + pbdev->release_timer =3D NULL; + } + pbdev->fid =3D 0; + QTAILQ_REMOVE(&s->zpci_devs, pbdev, link); + g_hash_table_remove(s->zpci_table, &pbdev->idx); + object_unparent(OBJECT(pbdev)); + } +} + +static void s390_pcihost_unplug_request(HotplugHandler *hotplug_dev, + DeviceState *dev, + Error **errp) +{ + S390pciState *s =3D S390_PCI_HOST_BRIDGE(hotplug_dev); + S390PCIBusDevice *pbdev; + if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) { error_setg(errp, "PCI bridge hot unplug currently not supported"); - return; } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { - pci_dev =3D PCI_DEVICE(dev); - - QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) { - if (pbdev->pdev =3D=3D pci_dev) { - break; - } - } - assert(pbdev !=3D NULL); + /* + * Redirect the unplug request to the zPCI device and remember that + * we've checked the PCI device already (to prevent endless recurs= ion). + */ + pbdev =3D s390_pci_find_dev_by_pci(s, PCI_DEVICE(dev)); + g_assert(pbdev); + pbdev->pci_unplug_request_processed =3D true; + qdev_unplug(DEVICE(pbdev), errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) { pbdev =3D S390_PCI_DEVICE(dev); - pci_dev =3D pbdev->pdev; - } else { - g_assert_not_reached(); - } =20 - switch (pbdev->state) { - case ZPCI_FS_RESERVED: - goto out; - case ZPCI_FS_STANDBY: - break; - default: - if (pbdev->release_timer) { + /* + * If unplug was initially requested for the zPCI device, we + * first have to redirect to the PCI device, which will in return + * redirect back to us after performing its checks (if the request + * is not blocked, e.g. because it's a PCI bridge). + */ + if (pbdev->pdev && !pbdev->pci_unplug_request_processed) { + qdev_unplug(DEVICE(pbdev->pdev), errp); return; } - s390_pci_generate_plug_event(HP_EVENT_DECONFIGURE_REQUEST, - pbdev->fh, pbdev->fid); - pbdev->release_timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, - s390_pcihost_timer_cb, - pbdev); - timer_mod(pbdev->release_timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + HOT_UNPLUG_TIMEO= UT); - return; - } + pbdev->pci_unplug_request_processed =3D false; =20 - if (pbdev->release_timer) { - timer_del(pbdev->release_timer); - timer_free(pbdev->release_timer); - pbdev->release_timer =3D NULL; + switch (pbdev->state) { + case ZPCI_FS_STANDBY: + case ZPCI_FS_RESERVED: + s390_pci_perform_unplug(pbdev); + break; + default: + if (pbdev->release_timer) { + return; + } + s390_pci_generate_plug_event(HP_EVENT_DECONFIGURE_REQUEST, + pbdev->fh, pbdev->fid); + pbdev->release_timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, + s390_pcihost_timer_cb, pbd= ev); + timer_mod(pbdev->release_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + HOT_UNPLUG_TIM= EOUT); + } + } else { + g_assert_not_reached(); } - - s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED, - pbdev->fh, pbdev->fid); - bus =3D pci_get_bus(pci_dev); - devfn =3D pci_dev->devfn; - object_unparent(OBJECT(pci_dev)); - fmb_timer_free(pbdev); - s390_pci_msix_free(pbdev); - s390_pci_iommu_free(s, bus, devfn); - pbdev->pdev =3D NULL; - pbdev->state =3D ZPCI_FS_RESERVED; -out: - pbdev->fid =3D 0; - QTAILQ_REMOVE(&s->zpci_devs, pbdev, link); - g_hash_table_remove(s->zpci_table, &pbdev->idx); - object_unparent(OBJECT(pbdev)); } =20 static void s390_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev, @@ -1077,6 +1134,7 @@ static void s390_pcihost_class_init(ObjectClass *klas= s, void *data) dc->realize =3D s390_pcihost_realize; hc->pre_plug =3D s390_pcihost_pre_plug; hc->plug =3D s390_pcihost_plug; + hc->unplug_request =3D s390_pcihost_unplug_request; hc->unplug =3D s390_pcihost_unplug; msi_nonbroken =3D true; } diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h index dadad1f758..b1a6bb8296 100644 --- a/hw/s390x/s390-pci-bus.h +++ b/hw/s390x/s390-pci-bus.h @@ -336,6 +336,7 @@ struct S390PCIBusDevice { IndAddr *summary_ind; IndAddr *indicator; QEMUTimer *release_timer; + bool pci_unplug_request_processed; QTAILQ_ENTRY(S390PCIBusDevice) link; }; =20 --=20 2.17.2 From nobody Fri May 3 09:07:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1548863994212183.5935831259469; Wed, 30 Jan 2019 07:59:54 -0800 (PST) Received: from localhost ([127.0.0.1]:40240 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gosHI-000058-LE for importer@patchew.org; Wed, 30 Jan 2019 10:59:52 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46868) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gosFM-000768-5U for qemu-devel@nongnu.org; Wed, 30 Jan 2019 10:57:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gosFK-00005o-Uc for qemu-devel@nongnu.org; Wed, 30 Jan 2019 10:57:52 -0500 Received: from mx1.redhat.com ([209.132.183.28]:53378) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gosFK-0008WJ-LI; Wed, 30 Jan 2019 10:57:50 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C506137E74; Wed, 30 Jan 2019 15:57:49 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id E181B1A914; Wed, 30 Jan 2019 15:57:47 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Date: Wed, 30 Jan 2019 16:57:32 +0100 Message-Id: <20190130155733.32742-6-david@redhat.com> In-Reply-To: <20190130155733.32742-1-david@redhat.com> References: <20190130155733.32742-1-david@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Wed, 30 Jan 2019 15:57:49 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 5/6] s390x/pci: Drop release timer and replace it with a flag X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Pierre Morel , David Hildenbrand , Cornelia Huck , Collin Walling , Christian Borntraeger , qemu-s390x@nongnu.org, Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Let's handle it similar to x86 ACPI PCI code and don't use a timer. Instead, remember if an unplug request is pending and keep it pending for eternity. (a follow up patch will process the request on reboot). We expect that a guest that is up and running, will process the unplug request and trigger the unplug. This is normal operation, no timer needed. If the guest does not react, this usually means something in the guest is going wrong. Simply removing the device after 30 seconds does not really sound like a good idea. It might sometimes be wanted, but I consider this rather an "opt-in" decision as it might harm a guest not prepared for it. If we ever actually want a "forced/surprise removal", we will have to implement something on top of the existing "device_del" framework. E.g. also x86 might want to do a forced/surprise removal of PCI devices under some conditions. "device_del X, forced=3Dtrue" could be an option and will require changes to the hotplug handler infrastructure. This will then move the responsibility on when to do a forced removal to a higher level. Doing a forced removal right now overcomplicates things and doesn't really. Let's allow to send multiple requests. Signed-off-by: David Hildenbrand Reviewed-by: Collin Walling --- hw/s390x/s390-pci-bus.c | 38 +++++++------------------------------- hw/s390x/s390-pci-bus.h | 3 +-- 2 files changed, 8 insertions(+), 33 deletions(-) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index e84e00d20c..867801ccf9 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -194,7 +194,7 @@ void s390_pci_sclp_deconfigure(SCCB *sccb) pbdev->state =3D ZPCI_FS_STANDBY; rc =3D SCLP_RC_NORMAL_COMPLETION; =20 - if (pbdev->release_timer) { + if (pbdev->unplug_requested) { s390_pci_perform_unplug(pbdev); } } @@ -975,23 +975,6 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_= dev, DeviceState *dev, } } =20 -static void s390_pcihost_timer_cb(void *opaque) -{ - S390PCIBusDevice *pbdev =3D opaque; - - if (pbdev->summary_ind) { - pci_dereg_irqs(pbdev); - } - if (pbdev->iommu->enabled) { - pci_dereg_ioat(pbdev->iommu); - } - - pbdev->state =3D ZPCI_FS_STANDBY; - s390_pci_generate_plug_event(HP_EVENT_CONFIGURED_TO_STBRES, - pbdev->fh, pbdev->fid); - s390_pci_perform_unplug(pbdev); -} - static void s390_pcihost_unplug(HotplugHandler *hotplug_dev, DeviceState *= dev, Error **errp) { @@ -1018,12 +1001,6 @@ static void s390_pcihost_unplug(HotplugHandler *hotp= lug_dev, DeviceState *dev, pbdev->state =3D ZPCI_FS_RESERVED; } else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) { pbdev =3D S390_PCI_DEVICE(dev); - - if (pbdev->release_timer) { - timer_del(pbdev->release_timer); - timer_free(pbdev->release_timer); - pbdev->release_timer =3D NULL; - } pbdev->fid =3D 0; QTAILQ_REMOVE(&s->zpci_devs, pbdev, link); g_hash_table_remove(s->zpci_table, &pbdev->idx); @@ -1070,15 +1047,14 @@ static void s390_pcihost_unplug_request(HotplugHand= ler *hotplug_dev, s390_pci_perform_unplug(pbdev); break; default: - if (pbdev->release_timer) { - return; - } + /* + * Allow to send multiple requests, e.g. if the guest crashed + * before releasing the device, we would not be able to send + * another request to the same VM (e.g. fresh OS). + */ + pbdev->unplug_requested =3D true; s390_pci_generate_plug_event(HP_EVENT_DECONFIGURE_REQUEST, pbdev->fh, pbdev->fid); - pbdev->release_timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, - s390_pcihost_timer_cb, pbd= ev); - timer_mod(pbdev->release_timer, - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + HOT_UNPLUG_TIM= EOUT); } } else { g_assert_not_reached(); diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h index b1a6bb8296..550f3cc5e9 100644 --- a/hw/s390x/s390-pci-bus.h +++ b/hw/s390x/s390-pci-bus.h @@ -35,7 +35,6 @@ #define ZPCI_MAX_UID 0xffff #define UID_UNDEFINED 0 #define UID_CHECKING_ENABLED 0x01 -#define HOT_UNPLUG_TIMEOUT (NANOSECONDS_PER_SECOND * 60 * 5) =20 #define S390_PCI_HOST_BRIDGE(obj) \ OBJECT_CHECK(S390pciState, (obj), TYPE_S390_PCI_HOST_BRIDGE) @@ -335,8 +334,8 @@ struct S390PCIBusDevice { MemoryRegion msix_notify_mr; IndAddr *summary_ind; IndAddr *indicator; - QEMUTimer *release_timer; bool pci_unplug_request_processed; + bool unplug_requested; QTAILQ_ENTRY(S390PCIBusDevice) link; }; =20 --=20 2.17.2 From nobody Fri May 3 09:07:47 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1548864209301902.6011343790454; Wed, 30 Jan 2019 08:03:29 -0800 (PST) Received: from localhost ([127.0.0.1]:40302 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gosKk-0002pc-W0 for importer@patchew.org; Wed, 30 Jan 2019 11:03:27 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46953) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gosFP-00079D-0a for qemu-devel@nongnu.org; Wed, 30 Jan 2019 10:57:55 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gosFO-00009q-5b for qemu-devel@nongnu.org; Wed, 30 Jan 2019 10:57:54 -0500 Received: from mx1.redhat.com ([209.132.183.28]:49692) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gosFN-00008p-WE; Wed, 30 Jan 2019 10:57:54 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2EE3285550; Wed, 30 Jan 2019 15:57:53 +0000 (UTC) Received: from t460s.redhat.com (ovpn-116-235.ams2.redhat.com [10.36.116.235]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1C2E41A914; Wed, 30 Jan 2019 15:57:49 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Date: Wed, 30 Jan 2019 16:57:33 +0100 Message-Id: <20190130155733.32742-7-david@redhat.com> In-Reply-To: <20190130155733.32742-1-david@redhat.com> References: <20190130155733.32742-1-david@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 30 Jan 2019 15:57:53 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 6/6] s390x/pci: Unplug remaining requested devices on pcihost reset X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Pierre Morel , David Hildenbrand , Cornelia Huck , Collin Walling , Christian Borntraeger , qemu-s390x@nongnu.org, Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" When resetting the guest we should unplug and remove all devices that are still pending. With this patch, the requested device will be unpluged on reboot (S390_RESET_EXTERNAL and S390_RESET_REIPL, which reset the pcihost bridge via qemu_devices_reset()). This approach is similar to what's done for acpi PCI hotplug in acpi_pcihp_reset() -> acpi_pcihp_update() -> acpi_pcihp_update_hotplug_bus() -> acpi_pcihp_eject_slot(). s390_pci_generate_plug_event()'s will still be generated, I guess this is not an issue. The same thing would happen right now when unplugging a device just before starting the guest. Signed-off-by: David Hildenbrand Reviewed-by: Collin Walling --- hw/s390x/s390-pci-bus.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index 867801ccf9..b9b0f44087 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -1092,6 +1092,21 @@ static void s390_pcihost_reset(DeviceState *dev) { S390pciState *s =3D S390_PCI_HOST_BRIDGE(dev); PCIBus *bus =3D s->parent_obj.bus; + S390PCIBusDevice *pbdev, *next; + + /* Process all pending unplug requests */ + QTAILQ_FOREACH_SAFE(pbdev, &s->zpci_devs, link, next) { + if (pbdev->unplug_requested) { + if (pbdev->summary_ind) { + pci_dereg_irqs(pbdev); + } + if (pbdev->iommu->enabled) { + pci_dereg_ioat(pbdev->iommu); + } + pbdev->state =3D ZPCI_FS_STANDBY; + s390_pci_perform_unplug(pbdev); + } + } =20 /* * When resetting a PCI bridge, the assigned numbers are set to 0. So --=20 2.17.2