Commit 6bd6b955 authored by Mark Syms's avatar Mark Syms Committed by Anthony PERARD
Browse files

xen-bus: only set the xen device frontend state if it is missing



Some toolstack implementations will set the frontend xenstore
keys to Initialising which will then trigger the in guest PV
drivers to begin initialising and some implementations will
then set their state to Closing. If this has occurred then
device realize must not overwrite the frontend keys as then
the handshake will stall.

Signed-off-by: default avatarMark Syms <mark.syms@citrix.com>

Also avoid creating the frontend area if it already exists.

Signed-off-by: default avatarPaul Durrant <paul.durrant@citrix.com>
Reviewed-by: default avatarAnthony PERARD <anthony.perard@citrix.com>
Message-Id: <20190918115745.39006-1-paul.durrant@citrix.com>
Signed-off-by: default avatarAnthony PERARD <anthony.perard@citrix.com>
parent ef916ab3
Loading
Loading
Loading
Loading
+31 −16
Original line number Diff line number Diff line
@@ -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,6 +872,11 @@ static void xen_device_frontend_create(XenDevice *xendev, Error **errp)

    xendev->frontend_path = xen_device_get_frontend_path(xendev);

    /*
     * 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;
@@ -879,6 +891,7 @@ static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
                                    "failed to create frontend: ");
            return;
        }
    }

    xendev->frontend_state_watch =
        xen_device_add_watch(xendev, xendev->frontend_path, "state",
@@ -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);

    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);
    }

    xendev->exit.notify = xen_device_exit;
    qemu_add_exit_notifier(&xendev->exit);