From nobody Sun Nov 9 22:26:48 2025 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; dkim=fail; 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 1551981225247441.1607023433877; Thu, 7 Mar 2019 09:53:45 -0800 (PST) Received: from localhost ([127.0.0.1]:56397 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h1xDB-0004tG-Aj for importer@patchew.org; Thu, 07 Mar 2019 12:53:41 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39506) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h1wqn-0003Ba-P1 for qemu-devel@nongnu.org; Thu, 07 Mar 2019 12:30:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h1wql-00085i-QZ for qemu-devel@nongnu.org; Thu, 07 Mar 2019 12:30:33 -0500 Received: from mail-wr1-x42e.google.com ([2a00:1450:4864:20::42e]:40958) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1h1wql-00084O-6f for qemu-devel@nongnu.org; Thu, 07 Mar 2019 12:30:31 -0500 Received: by mail-wr1-x42e.google.com with SMTP id y6so3258348wrn.7 for ; Thu, 07 Mar 2019 09:30:30 -0800 (PST) Received: from 640k.localdomain ([93.56.166.5]) by smtp.gmail.com with ESMTPSA id d206sm9979753wmc.11.2019.03.07.09.30.28 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Mar 2019 09:30:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=b37Z1HAa42CzxE/GqGEezVy8CPdfzJcbJmdYCDMbnew=; b=I1Y7Cjkrbhom544D3yIdluRGXl/TWfv55GMZVhiuLr6AyiwmI++YTLUVtKyXVAJYKw iDzc2G9IBr3jeKH3iEyV0+dOjUH2G/1fAei+3ItniFBq5lfxWZJvEdjr2hEGVtOckL3S bNbWcJSSSPBs+nIC+0VAfDiigLj2eCmjumZ1LIXeLL9Z0rfuG2E1T1rhxOB63ma9e3QA Ux4sRHZaZZn00cWZ8ZLx+Eaf4wkuggor980Zgqlt88THObS+ZGY8csZ+o9zCBI0tyaJY O+bd2n7D/z7J2fZTRucIX+2XOh4E3BsrcJ3Fz4ydpyokC5LjzjknXVn/fG1Gi1qDpW7F j5mw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=b37Z1HAa42CzxE/GqGEezVy8CPdfzJcbJmdYCDMbnew=; b=CgKcqrXdYEma9e9i8OgqEy6DZHI8105BC1eEWuaU/seOVPSanDJHZ5IqrpvRlfYwGX e/LmxGWxbF4IqYIdR51lYQOVf3uMPFHzVYlg8MHQzNyC3HvDXIBUNwJy5gWcdqqhKG4Z E6u73uRZDjL0zGGgnjv4KVZOe7n5GtXdDKzwUt+byc271ECDMPbr1d6nO6kMzo8RQyIU TX79/GRqDvTlltKBCbglC+gQYRHRNh1Ni3vJwpYwTdLex+k5cXbfsL1HU1yIfCoqpYXY NIdrMZ9rpd70H/P6yv5e3wxAFNnQdFm8IGORf5jYZxEl8klXoVCQAIMV2a2JM/m5hGc0 9XmQ== X-Gm-Message-State: APjAAAVc7GlYPr3dESOoVnytHgNA3gdfAjoDsoNEAh01kEjaUutKvFrx m1qiffQqKL+fvfuE++wd/Ajtg0s6 X-Google-Smtp-Source: APXvYqy2oMkQ9HWO8BwvZEVIBMaKiSOrGplKTa0WhQ/CpVcbBldZ/ixvMOVQ9in2KfxQaFvc+H3wAA== X-Received: by 2002:adf:f5d0:: with SMTP id k16mr7389070wrp.325.1551979829084; Thu, 07 Mar 2019 09:30:29 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Thu, 7 Mar 2019 18:29:28 +0100 Message-Id: <1551979804-6060-22-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1551979804-6060-1-git-send-email-pbonzini@redhat.com> References: <1551979804-6060-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::42e Subject: [Qemu-devel] [PULL 21/57] tests/libqos: virtio-pci driver and interface nodes 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: thuth@redhat.com, Emanuele Giuseppe Esposito , lviver@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Emanuele Giuseppe Esposito Add QOSGraphObject to QVirtioPCIDevice structure, with a basic constructor. virtio-pci is not present in qgraph, since it will be used as starting point by its subclasses (virtio-*-pci) Signed-off-by: Emanuele Giuseppe Esposito Signed-off-by: Paolo Bonzini --- tests/Makefile.include | 1 + tests/libqos/virtio-pci.c | 106 ++++++++++++++++++++++++++++++++++--------= ---- tests/libqos/virtio-pci.h | 14 ++++++ tests/virtio-blk-test.c | 6 +++ 4 files changed, 99 insertions(+), 28 deletions(-) diff --git a/tests/Makefile.include b/tests/Makefile.include index dbd0e68..c9c6019 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -750,6 +750,7 @@ qos-test-obj-y =3D tests/qos-test.o $(libqgraph-obj-y) qos-test-obj-y +=3D $(libqos-pc-obj-y) $(libqos-spapr-obj-y) qos-test-obj-y +=3D tests/libqos/e1000e.o qos-test-obj-y +=3D tests/libqos/sdhci.o +qos-test-obj-y +=3D $(libqos-virtio-obj-y) =20 # Machines qos-test-obj-y +=3D tests/libqos/aarch64-xlnx-zcu102-machine.o diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c index 550dede..6bcdbbb 100644 --- a/tests/libqos/virtio-pci.c +++ b/tests/libqos/virtio-pci.c @@ -15,12 +15,26 @@ #include "libqos/pci-pc.h" #include "libqos/malloc.h" #include "libqos/malloc-pc.h" +#include "libqos/qgraph.h" #include "standard-headers/linux/virtio_ring.h" #include "standard-headers/linux/virtio_pci.h" =20 #include "hw/pci/pci.h" #include "hw/pci/pci_regs.h" =20 +/* virtio-pci is a superclass of all virtio-xxx-pci devices; + * the relation between virtio-pci and virtio-xxx-pci is implicit, + * and therefore virtio-pci does not produce virtio and is not + * reached by any edge, not even as a "contains" edge. + * In facts, every device is a QVirtioPCIDevice with + * additional fields, since every one has its own + * number of queues and various attributes. + * Virtio-pci provides default functions to start the + * hw and destroy the object, and nodes that want to + * override them should always remember to call the + * original qvirtio_pci_destructor and qvirtio_pci_start_hw. + */ + typedef struct QVirtioPCIForeachData { void (*func)(QVirtioDevice *d, void *data); uint16_t device_type; @@ -32,36 +46,36 @@ typedef struct QVirtioPCIForeachData { void qvirtio_pci_device_free(QVirtioPCIDevice *dev) { g_free(dev->pdev); - g_free(dev); } =20 -static QVirtioPCIDevice *qpcidevice_to_qvirtiodevice(QPCIDevice *pdev) +static void qvirtio_pci_init_from_pcidev(QVirtioPCIDevice *dev, QPCIDevice= *pci_dev) { - QVirtioPCIDevice *vpcidev; - vpcidev =3D g_malloc0(sizeof(*vpcidev)); + dev->pdev =3D pci_dev; + dev->vdev.device_type =3D qpci_config_readw(pci_dev, PCI_SUBSYSTEM_ID); =20 - if (pdev) { - vpcidev->pdev =3D pdev; - vpcidev->vdev.device_type =3D - qpci_config_readw(vpcidev->pdev, PCI_SUBSYSTEM= _ID); - } + dev->config_msix_entry =3D -1; =20 - vpcidev->config_msix_entry =3D -1; + dev->vdev.bus =3D &qvirtio_pci; =20 - return vpcidev; + /* each virtio-xxx-pci device should override at least this function */ + dev->obj.get_driver =3D NULL; + dev->obj.start_hw =3D qvirtio_pci_start_hw; + dev->obj.destructor =3D qvirtio_pci_destructor; } =20 static void qvirtio_pci_foreach_callback( QPCIDevice *dev, int devfn, void *data) { QVirtioPCIForeachData *d =3D data; - QVirtioPCIDevice *vpcidev =3D qpcidevice_to_qvirtiodevice(dev); + QVirtioPCIDevice *vpcidev =3D g_new0(QVirtioPCIDevice, 1); =20 + qvirtio_pci_init_from_pcidev(vpcidev, dev); if (vpcidev->vdev.device_type =3D=3D d->device_type && (!d->has_slot || vpcidev->pdev->devfn =3D=3D d->slot << 3)) { d->func(&vpcidev->vdev, d->user_data); } else { qvirtio_pci_device_free(vpcidev); + g_free(vpcidev); } } =20 @@ -69,14 +83,14 @@ static void qvirtio_pci_assign_device(QVirtioDevice *d,= void *data) { QVirtioPCIDevice **vpcidev =3D data; assert(!*vpcidev); - *vpcidev =3D (QVirtioPCIDevice *)d; + *vpcidev =3D container_of(d, QVirtioPCIDevice, vdev); } =20 #define CONFIG_BASE(dev) (VIRTIO_PCI_CONFIG_OFF((dev)->pdev->msix_enabled)) =20 static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, uint64_t off) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); return qpci_io_readb(dev->pdev, dev->bar, CONFIG_BASE(dev) + off); } =20 @@ -90,7 +104,7 @@ static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d= , uint64_t off) =20 static uint16_t qvirtio_pci_config_readw(QVirtioDevice *d, uint64_t off) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); uint16_t value; =20 value =3D qpci_io_readw(dev->pdev, dev->bar, CONFIG_BASE(dev) + off); @@ -102,7 +116,7 @@ static uint16_t qvirtio_pci_config_readw(QVirtioDevice = *d, uint64_t off) =20 static uint32_t qvirtio_pci_config_readl(QVirtioDevice *d, uint64_t off) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); uint32_t value; =20 value =3D qpci_io_readl(dev->pdev, dev->bar, CONFIG_BASE(dev) + off); @@ -114,7 +128,7 @@ static uint32_t qvirtio_pci_config_readl(QVirtioDevice = *d, uint64_t off) =20 static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t off) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); uint64_t val; =20 val =3D qpci_io_readq(dev->pdev, dev->bar, CONFIG_BASE(dev) + off); @@ -127,37 +141,37 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevic= e *d, uint64_t off) =20 static uint32_t qvirtio_pci_get_features(QVirtioDevice *d) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); return qpci_io_readl(dev->pdev, dev->bar, VIRTIO_PCI_HOST_FEATURES); } =20 static void qvirtio_pci_set_features(QVirtioDevice *d, uint32_t features) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); qpci_io_writel(dev->pdev, dev->bar, VIRTIO_PCI_GUEST_FEATURES, feature= s); } =20 static uint32_t qvirtio_pci_get_guest_features(QVirtioDevice *d) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); return qpci_io_readl(dev->pdev, dev->bar, VIRTIO_PCI_GUEST_FEATURES); } =20 static uint8_t qvirtio_pci_get_status(QVirtioDevice *d) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); return qpci_io_readb(dev->pdev, dev->bar, VIRTIO_PCI_STATUS); } =20 static void qvirtio_pci_set_status(QVirtioDevice *d, uint8_t status) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); qpci_io_writeb(dev->pdev, dev->bar, VIRTIO_PCI_STATUS, status); } =20 static bool qvirtio_pci_get_queue_isr_status(QVirtioDevice *d, QVirtQueue = *vq) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); QVirtQueuePCI *vqpci =3D (QVirtQueuePCI *)vq; uint32_t data; =20 @@ -182,7 +196,7 @@ static bool qvirtio_pci_get_queue_isr_status(QVirtioDev= ice *d, QVirtQueue *vq) =20 static bool qvirtio_pci_get_config_isr_status(QVirtioDevice *d) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); uint32_t data; =20 if (dev->pdev->msix_enabled) { @@ -206,19 +220,19 @@ static bool qvirtio_pci_get_config_isr_status(QVirtio= Device *d) =20 static void qvirtio_pci_queue_select(QVirtioDevice *d, uint16_t index) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); qpci_io_writeb(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_SEL, index); } =20 static uint16_t qvirtio_pci_get_queue_size(QVirtioDevice *d) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); return qpci_io_readw(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_NUM); } =20 static void qvirtio_pci_set_queue_address(QVirtioDevice *d, uint32_t pfn) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); qpci_io_writel(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_PFN, pfn); } =20 @@ -270,7 +284,7 @@ static void qvirtio_pci_virtqueue_cleanup(QVirtQueue *v= q, =20 static void qvirtio_pci_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq) { - QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)d; + QVirtioPCIDevice *dev =3D container_of(d, QVirtioPCIDevice, vdev); qpci_io_writew(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_NOTIFY, vq->index= ); } =20 @@ -294,6 +308,7 @@ const QVirtioBus qvirtio_pci =3D { .virtqueue_kick =3D qvirtio_pci_virtqueue_kick, }; =20 +/* TODO: delete this once qgraph is completed */ static void qvirtio_pci_foreach(QPCIBus *bus, uint16_t device_type, bool has_slot, int slot, void (*func)(QVirtioDevice *d, void *data), void *data) @@ -416,3 +431,38 @@ void qvirtio_pci_set_msix_configuration_vector(QVirtio= PCIDevice *d, vector =3D qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR); g_assert_cmphex(vector, !=3D, VIRTIO_MSI_NO_VECTOR); } + +void qvirtio_pci_destructor(QOSGraphObject *obj) +{ + QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)obj; + qvirtio_pci_device_disable(dev); + qvirtio_pci_device_free(dev); +} + +void qvirtio_pci_start_hw(QOSGraphObject *obj) +{ + QVirtioPCIDevice *dev =3D (QVirtioPCIDevice *)obj; + qvirtio_pci_device_enable(dev); + qvirtio_start_device(&dev->vdev); +} + +void virtio_pci_init(QVirtioPCIDevice *dev, QPCIBus *bus, QPCIAddress * ad= dr) +{ + QPCIDevice *pci_dev =3D qpci_device_find(bus, addr->devfn); + g_assert_nonnull(pci_dev); + qvirtio_pci_init_from_pcidev(dev, pci_dev); +} + +QVirtioPCIDevice *virtio_pci_new(QPCIBus *bus, QPCIAddress * addr) +{ + QVirtioPCIDevice *dev; + QPCIDevice *pci_dev =3D qpci_device_find(bus, addr->devfn); + if (!pci_dev) { + return NULL; + } + + dev =3D g_new0(QVirtioPCIDevice, 1); + qvirtio_pci_init_from_pcidev(dev, pci_dev); + dev->obj.free =3D g_free; + return dev; +} diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h index 6ef1909..5631352 100644 --- a/tests/libqos/virtio-pci.h +++ b/tests/libqos/virtio-pci.h @@ -12,8 +12,10 @@ =20 #include "libqos/virtio.h" #include "libqos/pci.h" +#include "libqos/qgraph.h" =20 typedef struct QVirtioPCIDevice { + QOSGraphObject obj; QVirtioDevice vdev; QPCIDevice *pdev; QPCIBar bar; @@ -31,11 +33,23 @@ typedef struct QVirtQueuePCI { =20 extern const QVirtioBus qvirtio_pci; =20 +void virtio_pci_init(QVirtioPCIDevice *dev, QPCIBus *bus, QPCIAddress * ad= dr); +QVirtioPCIDevice *virtio_pci_new(QPCIBus *bus, QPCIAddress * addr); QVirtioPCIDevice *qvirtio_pci_device_find(QPCIBus *bus, uint16_t device_ty= pe); QVirtioPCIDevice *qvirtio_pci_device_find_slot(QPCIBus *bus, uint16_t device_type, int s= lot); void qvirtio_pci_device_free(QVirtioPCIDevice *dev); =20 +/* virtio-pci object functions available for subclasses that + * override the original start_hw and destroy + * function. All virtio-xxx-pci subclass that override must + * take care of calling these two functions in the respective + * places + */ +void qvirtio_pci_destructor(QOSGraphObject *obj); +void qvirtio_pci_start_hw(QOSGraphObject *obj); + + void qvirtio_pci_device_enable(QVirtioPCIDevice *d); void qvirtio_pci_device_disable(QVirtioPCIDevice *d); =20 diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c index b449970..8f8ef19 100644 --- a/tests/virtio-blk-test.c +++ b/tests/virtio-blk-test.c @@ -412,6 +412,7 @@ static void pci_basic(void) qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, &qs->alloc); qvirtio_pci_device_disable(dev); qvirtio_pci_device_free(dev); + g_free(dev); qtest_shutdown(qs); } =20 @@ -505,6 +506,7 @@ static void pci_indirect(void) qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, &qs->alloc); qvirtio_pci_device_disable(dev); qvirtio_pci_device_free(dev); + g_free(dev); qtest_shutdown(qs); } =20 @@ -534,6 +536,7 @@ static void pci_config(void) =20 qvirtio_pci_device_disable(dev); qvirtio_pci_device_free(dev); + g_free(dev); =20 qtest_shutdown(qs); } @@ -642,6 +645,7 @@ static void pci_msix(void) qpci_msix_disable(dev->pdev); qvirtio_pci_device_disable(dev); qvirtio_pci_device_free(dev); + g_free(dev); qtest_shutdown(qs); } =20 @@ -765,6 +769,7 @@ static void pci_idx(void) qpci_msix_disable(dev->pdev); qvirtio_pci_device_disable(dev); qvirtio_pci_device_free(dev); + g_free(dev); qtest_shutdown(qs); } =20 @@ -785,6 +790,7 @@ static void pci_hotplug(void) g_assert(dev); qvirtio_pci_device_disable(dev); qvirtio_pci_device_free(dev); + g_free(dev); =20 /* unplug secondary disk */ if (strcmp(arch, "i386") =3D=3D 0 || strcmp(arch, "x86_64") =3D=3D 0) { --=20 1.8.3.1