When attempting to initialise a mixture of pci and mmio virtio devices,
we cannot share an ops structure, otherwise the transport-specific
fields (init/exit and signal handling) will be globally set to the
transport of the last registered device.

This patch dynamically allocates a new ops structure for each instance
of a virtio net device.

Signed-off-by: Will Deacon <will.dea...@arm.com>
---
 tools/kvm/virtio/net.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/tools/kvm/virtio/net.c b/tools/kvm/virtio/net.c
index ae4712c3c550..dbb443124ee1 100644
--- a/tools/kvm/virtio/net.c
+++ b/tools/kvm/virtio/net.c
@@ -713,13 +713,20 @@ done:
 
 static int virtio_net__init_one(struct virtio_net_params *params)
 {
-       int i;
+       int i, err;
        struct net_dev *ndev;
+       struct virtio_ops *ops;
 
        ndev = calloc(1, sizeof(struct net_dev));
        if (ndev == NULL)
                return -ENOMEM;
 
+       ops = malloc(sizeof(*ops));
+       if (ops == NULL) {
+               err = -ENOMEM;
+               goto err_free_ndev;
+       }
+
        list_add_tail(&ndev->list, &ndevs);
 
        ndev->kvm = params->kvm;
@@ -749,12 +756,13 @@ static int virtio_net__init_one(struct virtio_net_params 
*params)
                uip_static_init(&ndev->info);
        }
 
+       *ops = net_dev_virtio_ops;
        if (params->trans && strcmp(params->trans, "mmio") == 0)
-               virtio_init(params->kvm, ndev, &ndev->vdev, &net_dev_virtio_ops,
-                           VIRTIO_MMIO, PCI_DEVICE_ID_VIRTIO_NET, 
VIRTIO_ID_NET, PCI_CLASS_NET);
+               virtio_init(params->kvm, ndev, &ndev->vdev, ops, VIRTIO_MMIO,
+                           PCI_DEVICE_ID_VIRTIO_NET, VIRTIO_ID_NET, 
PCI_CLASS_NET);
        else
-               virtio_init(params->kvm, ndev, &ndev->vdev, &net_dev_virtio_ops,
-                           VIRTIO_PCI, PCI_DEVICE_ID_VIRTIO_NET, 
VIRTIO_ID_NET, PCI_CLASS_NET);
+               virtio_init(params->kvm, ndev, &ndev->vdev, ops, VIRTIO_PCI,
+                           PCI_DEVICE_ID_VIRTIO_NET, VIRTIO_ID_NET, 
PCI_CLASS_NET);
 
        if (params->vhost)
                virtio_net__vhost_init(params->kvm, ndev);
@@ -763,6 +771,10 @@ static int virtio_net__init_one(struct virtio_net_params 
*params)
                compat_id = virtio_compat_add_message("virtio-net", 
"CONFIG_VIRTIO_NET");
 
        return 0;
+
+err_free_ndev:
+       free(ndev);
+       return err;
 }
 
 int virtio_net__init(struct kvm *kvm)
-- 
1.8.2.2

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to