From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48203) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YuZOs-0005f1-5c for qemu-devel@nongnu.org; Tue, 19 May 2015 00:45:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YuZOr-0004Pz-4k for qemu-devel@nongnu.org; Tue, 19 May 2015 00:45:06 -0400 Received: from [59.151.112.132] (port=41757 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YuZOm-0004Dc-O1 for qemu-devel@nongnu.org; Tue, 19 May 2015 00:45:05 -0400 From: Chen Fan Date: Tue, 19 May 2015 12:42:46 +0800 Message-ID: <0a0a9cca04fd00560d356133f7b89512c567e5fa.1432008287.git.chen.fan.fnst@cn.fujitsu.com> In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain Subject: [Qemu-devel] [RFC v7 04/11] vfio: add check host bus reset is support or not List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: izumi.taku@jp.fujitsu.com, alex.williamson@redhat.com when machine is done, we should check the all vfio devices whether support host bus reset, then when need virtual secondary bus reset, we should reset host bus. Signed-off-by: Chen Fan --- hw/vfio/pci.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 43869e9..ff639db 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -168,6 +168,7 @@ typedef struct VFIOPCIDevice { bool req_enabled; bool has_flr; bool has_pm_reset; + bool has_bus_reset; bool rom_read_failed; } VFIOPCIDevice; @@ -3533,6 +3534,82 @@ static void vfio_pci_host_needs_bus_reset(Notifier *n, void *opaque) vbasedev->needs_bus_reset = true; } +static void vfio_check_host_bus_reset(VFIODevice *vbasedev) +{ + VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev); + struct vfio_pci_hot_reset_info *info = NULL; + struct vfio_pci_dependent_device *devices; + VFIOGroup *group; + int ret, i; + + ret = vfio_get_hot_reset_info(vdev, &info); + if (ret < 0) { + goto out; + } + + devices = &info->devices[0]; + + /* Verify that we have all the groups required */ + for (i = 0; i < info->count; i++) { + PCIHostDeviceAddress host; + VFIOPCIDevice *tmp; + VFIODevice *vbasedev_iter; + + host.domain = devices[i].segment; + host.bus = devices[i].bus; + host.slot = PCI_SLOT(devices[i].devfn); + host.function = PCI_FUNC(devices[i].devfn); + + if (vfio_pci_host_match(&host, &vdev->host)) { + continue; + } + + QLIST_FOREACH(group, &vfio_group_list, next) { + if (group->groupid == devices[i].group_id) { + break; + } + } + + if (!group) { + goto out; + } + + QLIST_FOREACH(vbasedev_iter, &group->device_list, next) { + if (vbasedev_iter->type != VFIO_DEVICE_TYPE_PCI) { + continue; + } + tmp = container_of(vbasedev_iter, VFIOPCIDevice, vbasedev); + if (vfio_pci_host_match(&host, &tmp->host)) { + if (PCI_BUS(vdev->pdev.bus) != + PCI_BUS(tmp->pdev.bus)) { + goto out; + } + } + } + } + + vdev->has_bus_reset = true; + +out: + g_free(info); +} + +static void vfio_pci_machine_done_notify(Notifier *notifier, void *unused) +{ + VFIOGroup *group; + VFIODevice *vbasedev; + + QLIST_FOREACH(group, &vfio_group_list, next) { + QLIST_FOREACH(vbasedev, &group->device_list, next) { + vfio_check_host_bus_reset(vbasedev); + } + } +} + +static Notifier machine_notifier = { + .notify = vfio_pci_machine_done_notify, +}; + static int vfio_initfn(PCIDevice *pdev) { VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); @@ -3821,6 +3898,12 @@ static const TypeInfo vfio_pci_dev_info = { static void register_vfio_pci_dev_type(void) { type_register_static(&vfio_pci_dev_info); + + /* + * Register notifier when machine init is done, since we need + * check the configration manner after all vfio device are inited. + */ + qemu_add_machine_init_done_notifier(&machine_notifier); } type_init(register_vfio_pci_dev_type) -- 1.9.3