summaryrefslogtreecommitdiff
path: root/hw/xen
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xen')
-rw-r--r--hw/xen/xen-host-pci-device.h2
-rw-r--r--hw/xen/xen_backend.c173
-rw-r--r--hw/xen/xen_devconfig.c52
-rw-r--r--hw/xen/xen_pt.c2
-rw-r--r--hw/xen/xen_pt.h2
-rw-r--r--hw/xen/xen_pt_config_init.c5
-rw-r--r--hw/xen/xen_pt_msi.c1
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"