From patchwork Sun Nov 27 11:32:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cao jin X-Patchwork-Id: 699659 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tRSWt0m3jz9vDx for ; Sun, 27 Nov 2016 22:39:22 +1100 (AEDT) Received: from localhost ([::1]:53812 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cAxnj-0007j5-F6 for incoming@patchwork.ozlabs.org; Sun, 27 Nov 2016 06:39:19 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43811) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cAxeI-0008Rh-7e for qemu-devel@nongnu.org; Sun, 27 Nov 2016 06:29:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cAxeH-00010b-76 for qemu-devel@nongnu.org; Sun, 27 Nov 2016 06:29:34 -0500 Received: from [59.151.112.132] (port=43067 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cAxeG-0000xx-MP for qemu-devel@nongnu.org; Sun, 27 Nov 2016 06:29:33 -0500 X-IronPort-AV: E=Sophos;i="5.22,518,1449504000"; d="scan'208";a="13345173" Received: from unknown (HELO cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 27 Nov 2016 19:29:27 +0800 Received: from G08CNEXCHPEKD02.g08.fujitsu.local (unknown [10.167.33.83]) by cn.fujitsu.com (Postfix) with ESMTP id 7EC3F43972CE; Sun, 27 Nov 2016 19:29:24 +0800 (CST) Received: from G08FNSTD140223.g08.fujitsu.local (10.167.226.69) by G08CNEXCHPEKD02.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.319.2; Sun, 27 Nov 2016 19:29:34 +0800 From: Cao jin To: Date: Sun, 27 Nov 2016 19:32:30 +0800 Message-ID: <1480246353-10297-8-git-send-email-caoj.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1480246353-10297-1-git-send-email-caoj.fnst@cn.fujitsu.com> References: <1480246353-10297-1-git-send-email-caoj.fnst@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.226.69] X-yoursite-MailScanner-ID: 7EC3F43972CE.AD1DA X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: caoj.fnst@cn.fujitsu.com X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 59.151.112.132 Subject: [Qemu-devel] [PATCH v10 07/10] pci: introduce function validation check during hotplug 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: Chen Fan , izumi.taku@jp.fujitsu.com, alex.williamson@redhat.com, Dou Liyang , mst@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Chen Fan PCI hotplug requires that function 0 is added last to close the slot. Since vfio-pci supporting AER, we require that the VM bus contains the same set of devices as the host bus to support AER, we can perform an AER validation test whenever the function 0 is hot-added into VM. Signed-off-by: Chen Fan Signed-off-by: Dou Liyang Signed-off-by: Cao jin Reviewed-by: Michael S. Tsirkin --- hw/pci/pci.c | 29 +++++++++++++++++++++++++++++ include/hw/pci/pci.h | 1 + 2 files changed, 30 insertions(+) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 24fae16..26eaf4c 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1942,6 +1942,20 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn) return bus->devices[devfn]; } +static void pci_function_is_valid(PCIBus *bus, PCIDevice *d, void *opaque) +{ + PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(d); + Error **errp = opaque; + + if (*errp) { + return; + } + + if (pc->is_valid_func) { + pc->is_valid_func(d, errp); + } +} + static void pci_qdev_realize(DeviceState *qdev, Error **errp) { PCIDevice *pci_dev = (PCIDevice *)qdev; @@ -1984,6 +1998,21 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp) pci_qdev_unrealize(DEVICE(pci_dev), NULL); return; } + + /* + * Hot-added function number 0 indicates the closure of the slot, it is + * time to check whether all functions under the same bus is valid. + */ + if (DEVICE(pci_dev)->hotplugged && + pci_get_function_0(pci_dev) == pci_dev) { + pci_for_each_device(bus, pci_bus_num(bus), + pci_function_is_valid, &local_err); + if (local_err) { + error_propagate(errp, local_err); + pci_qdev_unrealize(DEVICE(pci_dev), NULL); + return; + } + } } static void pci_default_realize(PCIDevice *dev, Error **errp) diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 772692f..678f305 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -205,6 +205,7 @@ typedef struct PCIDeviceClass { void (*realize)(PCIDevice *dev, Error **errp); int (*init)(PCIDevice *dev);/* TODO convert to realize() and remove */ + void (*is_valid_func)(PCIDevice *dev, Error **errp); PCIUnregisterFunc *exit; PCIConfigReadFunc *config_read; PCIConfigWriteFunc *config_write;