From nobody Mon Apr 29 16:14:55 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1488875398372484.1998421926244; Tue, 7 Mar 2017 00:29:58 -0800 (PST) Received: from localhost ([::1]:48205 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1clAVI-0002hA-Qj for importer@patchew.org; Tue, 07 Mar 2017 03:29:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60136) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1clAUt-0002h2-6n for qemu-devel@nongnu.org; Tue, 07 Mar 2017 03:29:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1clAUq-0007Ts-27 for qemu-devel@nongnu.org; Tue, 07 Mar 2017 03:29:31 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51956) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1clAUp-0007TB-PO for qemu-devel@nongnu.org; Tue, 07 Mar 2017 03:29:27 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 859D483F45 for ; Tue, 7 Mar 2017 08:29:27 +0000 (UTC) Received: from jason-ThinkPad-T450s.redhat.com (vpn1-5-222.pek2.redhat.com [10.72.5.222]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v278TOt8020311; Tue, 7 Mar 2017 03:29:24 -0500 From: Jason Wang To: mst@redhat.com, marcel@redhat.com, qemu-devel@nongnu.org Date: Tue, 7 Mar 2017 16:29:21 +0800 Message-Id: <1488875361-4959-1-git-send-email-jasowang@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Tue, 07 Mar 2017 08:29:27 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH V2] virtio: do not require IOMMU to be created in advance 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: Paolo Bonzini , Jason Wang , peterx@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" After commit 96a8821d2141 ("virtio: unbreak virtio-pci with IOMMU after caching ring translations"), IOMMU was required to be created in advance. This is because we can only get the correct dma_as after pci IOMMU (e.g intel_iommu) was initialized. This is suboptimal and inconvenient for user. This patch releases this by: - introduce a bus_master_ready method for PCIDeviceClass and trigger this during pci_init_bus_master - implement virtio-pci method and 1) reset the dma_as 2) re-register the memory listener to the new dma_as Cc: Paolo Bonzini Signed-off-by: Jason Wang --- Changes from v1: - only call bus_master_ready() from pcibus_machine_done() to avoid break hotplug. --- hw/pci/pci.c | 7 ++++++- hw/virtio/virtio-pci.c | 9 +++++++++ hw/virtio/virtio.c | 19 +++++++++++++++++++ include/hw/pci/pci.h | 1 + include/hw/virtio/virtio.h | 1 + 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 273f1e4..df82863 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -99,7 +99,12 @@ static void pcibus_machine_done(Notifier *notifier, void= *data) =20 for (i =3D 0; i < ARRAY_SIZE(bus->devices); ++i) { if (bus->devices[i]) { - pci_init_bus_master(bus->devices[i]); + PCIDevice *pci_dev =3D bus->devices[i]; + PCIDeviceClass *pc =3D PCI_DEVICE_GET_CLASS(pci_dev); + pci_init_bus_master(pci_dev); + if (pc->bus_master_ready) { + pc->bus_master_ready(pci_dev); + } } } } diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index b76f3f6..21cbda2 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1845,6 +1845,14 @@ static void virtio_pci_exit(PCIDevice *pci_dev) address_space_destroy(&proxy->modern_as); } =20 +static void virtio_pci_bus_master_ready(PCIDevice *pci_dev) +{ + VirtIOPCIProxy *proxy =3D VIRTIO_PCI(pci_dev); + VirtIODevice *vdev =3D virtio_bus_get_device(&proxy->bus); + + virtio_device_reset_dma_as(vdev); +} + static void virtio_pci_reset(DeviceState *qdev) { VirtIOPCIProxy *proxy =3D VIRTIO_PCI(qdev); @@ -1904,6 +1912,7 @@ static void virtio_pci_class_init(ObjectClass *klass,= void *data) dc->props =3D virtio_pci_properties; k->realize =3D virtio_pci_realize; k->exit =3D virtio_pci_exit; + k->bus_master_ready =3D virtio_pci_bus_master_ready; k->vendor_id =3D PCI_VENDOR_ID_REDHAT_QUMRANET; k->revision =3D VIRTIO_PCI_ABI_VERSION; k->class_id =3D PCI_CLASS_OTHERS; diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index efce4b3..09f4cf4 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -2594,6 +2594,25 @@ bool virtio_device_ioeventfd_enabled(VirtIODevice *v= dev) return virtio_bus_ioeventfd_enabled(vbus); } =20 +void virtio_device_reset_dma_as(VirtIODevice *vdev) +{ + DeviceState *qdev =3D DEVICE(vdev); + BusState *qbus =3D BUS(qdev_get_parent_bus(qdev)); + VirtioBusState *bus =3D VIRTIO_BUS(qbus); + VirtioBusClass *klass =3D VIRTIO_BUS_GET_CLASS(bus); + bool has_iommu =3D virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFO= RM); + + if (klass->get_dma_as !=3D NULL && has_iommu) { + vdev->dma_as =3D klass->get_dma_as(qbus->parent); + } else { + vdev->dma_as =3D &address_space_memory; + } + + memory_listener_unregister(&vdev->listener); + memory_listener_register(&vdev->listener, vdev->dma_as); +} + + static const TypeInfo virtio_device_info =3D { .name =3D TYPE_VIRTIO_DEVICE, .parent =3D TYPE_DEVICE, diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 9349acb..e700a58 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -207,6 +207,7 @@ typedef struct PCIDeviceClass { =20 void (*realize)(PCIDevice *dev, Error **errp); int (*init)(PCIDevice *dev);/* TODO convert to realize() and remove */ + void (*bus_master_ready)(PCIDevice *dev); PCIUnregisterFunc *exit; PCIConfigReadFunc *config_read; PCIConfigWriteFunc *config_write; diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 15efcf2..21fa273 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -283,6 +283,7 @@ void virtio_device_stop_ioeventfd(VirtIODevice *vdev); int virtio_device_grab_ioeventfd(VirtIODevice *vdev); void virtio_device_release_ioeventfd(VirtIODevice *vdev); bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev); +void virtio_device_reset_dma_as(VirtIODevice *vdev); EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq); void virtio_queue_host_notifier_read(EventNotifier *n); void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext = *ctx, --=20 2.7.4