From 977af6f951192b5e8a15582610f37c69fa18baa1 Mon Sep 17 00:00:00 2001 From: Joao Martins Date: Thu, 11 Oct 2018 11:43:01 -0400 Subject: [PATCH] hw/net/xen_nic: allow configuring as a device 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 --- hw/i386/xen/xen_platform.c | 3 +- hw/net/xen_nic.c | 86 ++++++++++++++++++++++++++++++++++--- hw/xen/xen-legacy-backend.c | 32 ++++++++------ target/i386/xen.c | 2 + 4 files changed, 103 insertions(+), 20 deletions(-) diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c index c29e3ad113..30e82025b8 100644 --- a/hw/i386/xen/xen_platform.c +++ b/hw/i386/xen/xen_platform.c @@ -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) diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c index 37cda8e4be..c261069f1a 100644 --- a/hw/net/xen_nic.c +++ b/hw/net/xen_nic.c @@ -20,6 +20,7 @@ */ #include "qemu/osdep.h" +#include "qemu/log.h" #include #include #include @@ -29,9 +30,14 @@ #include "net/checksum.h" #include "net/util.h" #include "hw/xen/xen-legacy-backend.h" +#include "net/tap.h" #include +#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) diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c index 2821c7a0dc..213c78504f 100644 --- a/hw/xen/xen-legacy-backend.c +++ b/hw/xen/xen-legacy-backend.c @@ -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 diff --git a/target/i386/xen.c b/target/i386/xen.c index 937a068893..9106ba9de4 100644 --- a/target/i386/xen.c +++ b/target/i386/xen.c @@ -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) -- 2.50.1