summary refs log tree commit diff stats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/xen/xen-bus.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 55c157393d..c2ad22a42d 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -857,6 +857,13 @@ static void xen_device_frontend_changed(void *opaque)
     }
 }
 
+static bool xen_device_frontend_exists(XenDevice *xendev)
+{
+    enum xenbus_state state;
+
+    return (xen_device_frontend_scanf(xendev, "state", "%u", &state) == 1);
+}
+
 static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
 {
     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
@@ -865,19 +872,25 @@ static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
 
     xendev->frontend_path = xen_device_get_frontend_path(xendev);
 
-    perms[0].id = xendev->frontend_id;
-    perms[0].perms = XS_PERM_NONE;
-    perms[1].id = xenbus->backend_id;
-    perms[1].perms = XS_PERM_READ | XS_PERM_WRITE;
+    /*
+     * The frontend area may have already been created by a legacy
+     * toolstack.
+     */
+    if (!xen_device_frontend_exists(xendev)) {
+        perms[0].id = xendev->frontend_id;
+        perms[0].perms = XS_PERM_NONE;
+        perms[1].id = xenbus->backend_id;
+        perms[1].perms = XS_PERM_READ | XS_PERM_WRITE;
 
-    g_assert(xenbus->xsh);
+        g_assert(xenbus->xsh);
 
-    xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path, perms,
-                   ARRAY_SIZE(perms), &local_err);
-    if (local_err) {
-        error_propagate_prepend(errp, local_err,
-                                "failed to create frontend: ");
-        return;
+        xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path, perms,
+                       ARRAY_SIZE(perms), &local_err);
+        if (local_err) {
+            error_propagate_prepend(errp, local_err,
+                                    "failed to create frontend: ");
+            return;
+        }
     }
 
     xendev->frontend_state_watch =
@@ -1290,12 +1303,14 @@ static void xen_device_realize(DeviceState *dev, Error **errp)
     xen_device_backend_set_online(xendev, true);
     xen_device_backend_set_state(xendev, XenbusStateInitWait);
 
-    xen_device_frontend_printf(xendev, "backend", "%s",
-                               xendev->backend_path);
-    xen_device_frontend_printf(xendev, "backend-id", "%u",
-                               xenbus->backend_id);
+    if (!xen_device_frontend_exists(xendev)) {
+        xen_device_frontend_printf(xendev, "backend", "%s",
+                                   xendev->backend_path);
+        xen_device_frontend_printf(xendev, "backend-id", "%u",
+                                   xenbus->backend_id);
 
-    xen_device_frontend_set_state(xendev, XenbusStateInitialising, true);
+        xen_device_frontend_set_state(xendev, XenbusStateInitialising, true);
+    }
 
     xendev->exit.notify = xen_device_exit;
     qemu_add_exit_notifier(&xendev->exit);