]> www.infradead.org Git - users/dwmw2/qemu.git/commitdiff
hw/net/xen_nic: allow configuring as a device
authorJoao Martins <joao.m.martins@oracle.com>
Thu, 11 Oct 2018 15:43:01 +0000 (11:43 -0400)
committerJoao Martins <joao.m.martins@oracle.com>
Tue, 19 Feb 2019 14:00:57 +0000 (09:00 -0500)
Currently Qemu assumes (for the tupical Xen usecase) that it will just
watch directories and manage the synthetic device. Here we try to allow
the initial device initialization by creating the xenstore directories
accordingly.

Additionally make the backend also register "qnic" backend which is
needed for Xen emulated nics.

Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
hw/i386/xen/xen_platform.c
hw/net/xen_nic.c
hw/xen/xen-legacy-backend.c
target/i386/xen.c

index c29e3ad1132df5466aee095ca026eb80a67f4ea0..30e82025b840c16fc20dd28b86ed3f40b929b13a 100644 (file)
@@ -140,8 +140,9 @@ static void del_nic_peer(NICState *nic, void *opaque)
     NetClientState *nc;
 
     nc = qemu_get_queue(nic);
-    if (nc->peer)
+    if (strcmp(nc->model, "xen-nic") && nc->peer) {
         qemu_del_net_client(nc->peer);
+    }
 }
 
 static void pci_unplug_nics(PCIBus *bus)
index 37cda8e4bec26e10e85d18aab4afaf4a311ad4ac..c261069f1aa22fe3e1c29fae91b813669ac4bc9d 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/log.h"
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <sys/wait.h>
 #include "net/checksum.h"
 #include "net/util.h"
 #include "hw/xen/xen-legacy-backend.h"
+#include "net/tap.h"
 
 #include <xen/io/netif.h>
 
+#define TYPE_XEN_NIC "xen-nic"
+#define XEN_NIC(obj) \
+    OBJECT_CHECK(struct XenNetDev, (obj), TYPE_XEN_NIC)
+
 /* ------------------------------------------------------------- */
 
 struct XenNetDev {
@@ -44,6 +50,7 @@ struct XenNetDev {
     struct netif_rx_sring *rxs;
     netif_tx_back_ring_t  tx_ring;
     netif_rx_back_ring_t  rx_ring;
+    XenBackendType        be;
     NICConf               conf;
     NICState              *nic;
 };
@@ -294,12 +301,12 @@ static int net_init(struct XenLegacyDevice *xendev)
         return -1;
     }
 
-    netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf,
-                               "xen", NULL, netdev);
-
-    snprintf(qemu_get_queue(netdev->nic)->info_str,
-             sizeof(qemu_get_queue(netdev->nic)->info_str),
-             "nic: xenbus vif macaddr=%s", netdev->mac);
+    if (!netdev->nic) {
+        netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf,
+                                   "xen", NULL, netdev);
+        qemu_format_nic_info_str(qemu_get_queue(netdev->nic),
+                                 netdev->conf.macaddr.a);
+    }
 
     /* fill info */
     xenstore_write_be_int(&netdev->xendev, "feature-rx-copy", 1);
@@ -410,3 +417,70 @@ struct XenDevOps xen_netdev_ops = {
     .disconnect = net_disconnect,
     .free       = net_free,
 };
+
+static Property xen_nic_properties[] = {
+    DEFINE_XEN_PROPERTIES(struct XenNetDev, be),
+    DEFINE_NIC_PROPERTIES(struct XenNetDev, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void xen_nic_instance_init(Object *obj)
+{
+    struct XenNetDev *n = XEN_NIC(obj);
+
+    device_add_bootindex_property(obj, &n->conf.bootindex,
+                                  "bootindex", "/ethernet-phy@0",
+                                  DEVICE(n), NULL);
+}
+
+static void xen_nic_device_realize(DeviceState *dev, Error **errp)
+{
+    struct XenNetDev *n = XEN_NIC(dev);
+
+    qemu_macaddr_default_if_unset(&n->conf.macaddr);
+
+    n->nic = qemu_new_nic(&net_xen_info, &n->conf,
+                          object_get_typename(OBJECT(dev)), dev->id, n);
+    qemu_format_nic_info_str(qemu_get_queue(n->nic), n->conf.macaddr.a);
+
+    n->xendev.type = n->be.type;
+    n->xendev.dom = xen_domid;
+    n->xendev.dev = 0;
+
+    xen_pv_insert_xendev(&n->xendev);
+
+    xen_config_dev_nic_by_conf(qemu_get_queue(n->nic), n->conf.macaddr, &n->be);
+}
+
+static void xen_nic_device_unrealize(DeviceState *dev, Error **errp)
+{
+}
+
+static void xen_nic_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = xen_nic_device_realize;
+    dc->unrealize = xen_nic_device_unrealize;
+    dc->props = xen_nic_properties;
+    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
+
+    if (xen_mode == XEN_EMULATE) {
+        xen_netdev_ops.flags &= ~DEVOPS_FLAG_NEED_GNTDEV;
+    }
+}
+
+static const TypeInfo xen_nic_info = {
+    .name = TYPE_XEN_NIC,
+    .parent = TYPE_XENBACKEND,
+    .instance_size = sizeof(struct XenNetDev),
+    .instance_init = xen_nic_instance_init,
+    .class_init = xen_nic_class_init,
+};
+
+static void xen_nic_register_types(void)
+{
+    type_register_static(&xen_nic_info);
+}
+
+type_init(xen_nic_register_types)
index 2821c7a0dc93248e6c46dd13604795b35d321da9..213c78504fead357deafe22dc4652516bf31195d 100644 (file)
@@ -309,24 +309,28 @@ static struct XenLegacyDevice *xen_be_get_xendev(const char *type, int dom,
                                                  struct XenDevOps *ops)
 {
     struct XenLegacyDevice *xendev;
+    bool new;
 
     xendev = xen_pv_find_xendev(type, dom, dev);
-    if (xendev) {
+    if (xendev && xendev->ops) {
         return xendev;
     }
 
+    new = !xendev;
     /* init new xendev */
-    xendev = g_malloc0(ops->size);
-    object_initialize(&xendev->qdev, ops->size, TYPE_XENBACKEND);
-    OBJECT(xendev)->free = g_free;
-    qdev_set_parent_bus(DEVICE(xendev), xen_sysbus);
-    qdev_set_id(DEVICE(xendev), g_strdup_printf("xen-%s-%d", type, dev));
-    qdev_init_nofail(DEVICE(xendev));
-    object_unref(OBJECT(xendev));
-
-    xendev->type  = type;
-    xendev->dom   = dom;
-    xendev->dev   = dev;
+    if (!xendev) {
+        xendev = g_malloc0(ops->size);
+        object_initialize(&xendev->qdev, ops->size, TYPE_XENBACKEND);
+        OBJECT(xendev)->free = g_free;
+        qdev_set_parent_bus(DEVICE(xendev), xen_sysbus);
+        qdev_set_id(DEVICE(xendev), g_strdup_printf("xen-%s-%d", type, dev));
+        qdev_init_nofail(DEVICE(xendev));
+        object_unref(OBJECT(xendev));
+        xendev->type  = type;
+        xendev->dom   = dom;
+        xendev->dev   = dev;
+    }
+
     xendev->ops   = ops;
 
     snprintf(xendev->be, sizeof(xendev->be), "backend/%s/%d/%d",
@@ -347,7 +351,8 @@ static struct XenLegacyDevice *xen_be_get_xendev(const char *type, int dom,
         qemu_set_cloexec(xenevtchn_fd(xendev->evtchndev));
     }
 
-    xen_pv_insert_xendev(xendev);
+    if (new)
+        xen_pv_insert_xendev(xendev);
 
     if (xendev->ops->alloc) {
         xendev->ops->alloc(xendev);
@@ -813,6 +818,7 @@ void xen_be_register_common(void)
 
     xen_be_register("console", &xen_console_ops);
     xen_be_register("vkbd", &xen_kbdmouse_ops);
+    xen_be_register("qnic", &xen_netdev_ops);
 #ifdef CONFIG_VIRTFS
     xen_be_register("9pfs", &xen_9pfs_ops);
 #endif
index 937a0688939dd4172a0f1d8d8c01d32b65822b5a..9106ba9de458272e6b0b38f3c3e22e1fbec3ac04 100644 (file)
@@ -360,6 +360,8 @@ static void kvm_xen_exit(Notifier *n, void *data)
         xs_rm(xsh, XBT_NULL, xs_get_domain_path(xsh, xen->domid));
         xs_close(xsh);
     }
+
+    xen_config_cleanup();
 }
 
 void kvm_xen_init(XenState *xen)