diff options
Diffstat (limited to 'hw/xen')
-rw-r--r-- | hw/xen/xen-host-pci-device.h | 2 | ||||
-rw-r--r-- | hw/xen/xen_backend.c | 173 | ||||
-rw-r--r-- | hw/xen/xen_devconfig.c | 52 | ||||
-rw-r--r-- | hw/xen/xen_pt.c | 2 | ||||
-rw-r--r-- | hw/xen/xen_pt.h | 2 | ||||
-rw-r--r-- | hw/xen/xen_pt_config_init.c | 5 | ||||
-rw-r--r-- | hw/xen/xen_pt_msi.c | 1 |
7 files changed, 140 insertions, 97 deletions
diff --git a/hw/xen/xen-host-pci-device.h b/hw/xen/xen-host-pci-device.h index 6acf36e13..4d8d34ecb 100644 --- a/hw/xen/xen-host-pci-device.h +++ b/hw/xen/xen-host-pci-device.h @@ -55,4 +55,4 @@ int xen_host_pci_set_block(XenHostPCIDevice *d, int pos, uint8_t *buf, int xen_host_pci_find_ext_cap_offset(XenHostPCIDevice *s, uint32_t cap); -#endif /* !XEN_HOST_PCI_DEVICE_H_ */ +#endif /* XEN_HOST_PCI_DEVICE_H */ diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index 60575ad38..69a238817 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -23,16 +23,20 @@ */ #include "qemu/osdep.h" -#include <sys/mman.h> #include <sys/signal.h> #include "hw/hw.h" +#include "hw/sysbus.h" #include "sysemu/char.h" #include "qemu/log.h" #include "hw/xen/xen_backend.h" #include <xen/grant_table.h> +#define TYPE_XENSYSDEV "xensysdev" + +DeviceState *xen_sysdev; + /* ------------------------------------------------------------- */ /* public */ @@ -42,11 +46,36 @@ struct xs_handle *xenstore = NULL; const char *xen_protocol; /* private */ +struct xs_dirs { + char *xs_dir; + QTAILQ_ENTRY(xs_dirs) list; +}; +static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup = + QTAILQ_HEAD_INITIALIZER(xs_cleanup); + static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = QTAILQ_HEAD_INITIALIZER(xendevs); static int debug = 0; /* ------------------------------------------------------------- */ +static void xenstore_cleanup_dir(char *dir) +{ + struct xs_dirs *d; + + d = g_malloc(sizeof(*d)); + d->xs_dir = dir; + QTAILQ_INSERT_TAIL(&xs_cleanup, d, list); +} + +void xen_config_cleanup(void) +{ + struct xs_dirs *d; + + QTAILQ_FOREACH(d, &xs_cleanup, list) { + xs_rm(xenstore, 0, d->xs_dir); + } +} + int xenstore_write_str(const char *base, const char *node, const char *val) { char abspath[XEN_BUFSIZE]; @@ -75,6 +104,30 @@ char *xenstore_read_str(const char *base, const char *node) return ret; } +int xenstore_mkdir(char *path, int p) +{ + struct xs_permissions perms[2] = { + { + .id = 0, /* set owner: dom0 */ + }, { + .id = xen_domid, + .perms = p, + } + }; + + if (!xs_mkdir(xenstore, 0, path)) { + xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", path); + return -1; + } + xenstore_cleanup_dir(g_strdup(path)); + + if (!xs_set_permissions(xenstore, 0, path, perms, 2)) { + xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", path); + return -1; + } + return 0; +} + int xenstore_write_int(const char *base, const char *node, int ival) { char val[12]; @@ -268,48 +321,28 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, /* * release xen backend device. */ -static struct XenDevice *xen_be_del_xendev(int dom, int dev) +static void xen_be_del_xendev(struct XenDevice *xendev) { - struct XenDevice *xendev, *xnext; - - /* - * This is pretty much like QTAILQ_FOREACH(xendev, &xendevs, next) but - * we save the next pointer in xnext because we might free xendev. - */ - xnext = xendevs.tqh_first; - while (xnext) { - xendev = xnext; - xnext = xendev->next.tqe_next; - - if (xendev->dom != dom) { - continue; - } - if (xendev->dev != dev && dev != -1) { - continue; - } - - if (xendev->ops->free) { - xendev->ops->free(xendev); - } - - if (xendev->fe) { - char token[XEN_BUFSIZE]; - snprintf(token, sizeof(token), "fe:%p", xendev); - xs_unwatch(xenstore, xendev->fe, token); - g_free(xendev->fe); - } + if (xendev->ops->free) { + xendev->ops->free(xendev); + } - if (xendev->evtchndev != NULL) { - xenevtchn_close(xendev->evtchndev); - } - if (xendev->gnttabdev != NULL) { - xengnttab_close(xendev->gnttabdev); - } + if (xendev->fe) { + char token[XEN_BUFSIZE]; + snprintf(token, sizeof(token), "fe:%p", xendev); + xs_unwatch(xenstore, xendev->fe, token); + g_free(xendev->fe); + } - QTAILQ_REMOVE(&xendevs, xendev, next); - g_free(xendev); + if (xendev->evtchndev != NULL) { + xenevtchn_close(xendev->evtchndev); } - return NULL; + if (xendev->gnttabdev != NULL) { + xengnttab_close(xendev->gnttabdev); + } + + QTAILQ_REMOVE(&xendevs, xendev, next); + g_free(xendev); } /* @@ -629,7 +662,7 @@ static void xenstore_update_be(char *watch, char *type, int dom, if (xendev != NULL) { bepath = xs_read(xenstore, 0, xendev->be, &len); if (bepath == NULL) { - xen_be_del_xendev(dom, dev); + xen_be_del_xendev(xendev); } else { free(bepath); xen_be_backend_changed(xendev, path); @@ -714,6 +747,10 @@ int xen_be_init(void) /* Check if xen_init() have been called */ goto err; } + + xen_sysdev = qdev_create(NULL, TYPE_XENSYSDEV); + qdev_init_nofail(xen_sysdev); + return 0; err: @@ -726,9 +763,33 @@ err: int xen_be_register(const char *type, struct XenDevOps *ops) { + char path[50]; + int rc; + + if (ops->backend_register) { + rc = ops->backend_register(); + if (rc) { + return rc; + } + } + + snprintf(path, sizeof(path), "device-model/%u/backends/%s", xen_domid, + type); + xenstore_mkdir(path, XS_PERM_NONE); + return xenstore_scan(type, xen_domid, ops); } +void xen_be_register_common(void) +{ + xen_be_register("console", &xen_console_ops); + xen_be_register("vkbd", &xen_kbdmouse_ops); + xen_be_register("qdisk", &xen_blkdev_ops); +#ifdef CONFIG_USB_LIBUSB + xen_be_register("qusb", &xen_usb_ops); +#endif +} + int xen_be_bind_evtchn(struct XenDevice *xendev) { if (xendev->local_port != -1) { @@ -800,3 +861,35 @@ void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ... } qemu_log_flush(); } + +static int xen_sysdev_init(SysBusDevice *dev) +{ + return 0; +} + +static Property xen_sysdev_properties[] = { + {/* end of property list */}, +}; + +static void xen_sysdev_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + + k->init = xen_sysdev_init; + dc->props = xen_sysdev_properties; +} + +static const TypeInfo xensysdev_info = { + .name = TYPE_XENSYSDEV, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(SysBusDevice), + .class_init = xen_sysdev_class_init, +}; + +static void xenbe_register_types(void) +{ + type_register_static(&xensysdev_info); +} + +type_init(xenbe_register_types); diff --git a/hw/xen/xen_devconfig.c b/hw/xen/xen_devconfig.c index 1f30fe4f5..b7d290df6 100644 --- a/hw/xen/xen_devconfig.c +++ b/hw/xen/xen_devconfig.c @@ -5,54 +5,6 @@ /* ------------------------------------------------------------- */ -struct xs_dirs { - char *xs_dir; - QTAILQ_ENTRY(xs_dirs) list; -}; -static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup = QTAILQ_HEAD_INITIALIZER(xs_cleanup); - -static void xen_config_cleanup_dir(char *dir) -{ - struct xs_dirs *d; - - d = g_malloc(sizeof(*d)); - d->xs_dir = dir; - QTAILQ_INSERT_TAIL(&xs_cleanup, d, list); -} - -void xen_config_cleanup(void) -{ - struct xs_dirs *d; - - QTAILQ_FOREACH(d, &xs_cleanup, list) { - xs_rm(xenstore, 0, d->xs_dir); - } -} - -/* ------------------------------------------------------------- */ - -static int xen_config_dev_mkdir(char *dev, int p) -{ - struct xs_permissions perms[2] = {{ - .id = 0, /* set owner: dom0 */ - },{ - .id = xen_domid, - .perms = p, - }}; - - if (!xs_mkdir(xenstore, 0, dev)) { - xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", dev); - return -1; - } - xen_config_cleanup_dir(g_strdup(dev)); - - if (!xs_set_permissions(xenstore, 0, dev, perms, 2)) { - xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", dev); - return -1; - } - return 0; -} - static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev, char *fe, char *be, int len) { @@ -66,8 +18,8 @@ static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev, snprintf(be, len, "%s/backend/%s/%d/%d", dom, btype, xen_domid, vdev); free(dom); - xen_config_dev_mkdir(fe, XS_PERM_READ | XS_PERM_WRITE); - xen_config_dev_mkdir(be, XS_PERM_READ); + xenstore_mkdir(fe, XS_PERM_READ | XS_PERM_WRITE); + xenstore_mkdir(be, XS_PERM_READ); return 0; } diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index f593b046e..b6d71bb52 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -842,7 +842,7 @@ static void xen_pt_realize(PCIDevice *d, Error **errp) goto err_out; } if (!scratch) { - error_setg(errp, "no pin interrupt"); + XEN_PT_LOG(d, "no pin interrupt\n"); goto out; } diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h index c2f8e1fc2..191d9caea 100644 --- a/hw/xen/xen_pt.h +++ b/hw/xen/xen_pt.h @@ -332,4 +332,4 @@ int xen_pt_register_vga_regions(XenHostPCIDevice *dev); int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev); void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev, Error **errp); -#endif /* !XEN_PT_H */ +#endif /* XEN_PT_H */ diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c index 9869ffda0..6f18366f6 100644 --- a/hw/xen/xen_pt_config_init.c +++ b/hw/xen/xen_pt_config_init.c @@ -2049,9 +2049,8 @@ void xen_pt_config_init(XenPCIPassthroughState *s, Error **errp) for (j = 0; regs->size != 0; j++, regs++) { xen_pt_config_reg_init(s, reg_grp_entry, regs, &err); if (err) { - error_append_hint(&err, "Failed to initialize %d/%zu" - " reg 0x%x in grp_type = 0x%x (%d/%zu)", - j, ARRAY_SIZE(xen_pt_emu_reg_grps[i].emu_regs), + error_append_hint(&err, "Failed to init register %d" + " offsets 0x%x in grp_type = 0x%x (%d/%zu)", j, regs->offset, xen_pt_emu_reg_grps[i].grp_type, i, ARRAY_SIZE(xen_pt_emu_reg_grps)); error_propagate(errp, err); diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c index 9a16f2bff..62add0639 100644 --- a/hw/xen/xen_pt_msi.c +++ b/hw/xen/xen_pt_msi.c @@ -10,7 +10,6 @@ */ #include "qemu/osdep.h" -#include <sys/mman.h> #include "hw/xen/xen_backend.h" #include "xen_pt.h" |