Skip to content

Commit

Permalink
hw/xen: fix XenStore watch delivery to guest
Browse files Browse the repository at this point in the history
When fire_watch_cb() found the response buffer empty, it would call
deliver_watch() to generate the XS_WATCH_EVENT message in the response
buffer and send an event channel notification to the guest… without
actually *copying* the response buffer into the ring. So there was
nothing for the guest to see. The pending response didn't actually get
processed into the ring until the guest next triggered some activity
from its side.

Add the missing call to put_rsp().

It might have been slightly nicer to call xen_xenstore_event() here,
which would *almost* have worked. Except for the fact that it calls
xen_be_evtchn_pending() to check that it really does have an event
pending (and clear the eventfd for next time). And under Xen it's
defined that setting that fd to O_NONBLOCK isn't guaranteed to work,
so the emu implementation follows suit.

This fixes Xen device hot-unplug.

Cc: qemu-stable@nongnu.org
Fixes: 0254c4d ("hw/xen: Add xenstore wire implementation and implementation stubs")
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Reviewed-by: Paul Durrant <paul@xen.org>
(cherry picked from commit 4a5780f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
  • Loading branch information
dwmw2 authored and Michael Tokarev committed Nov 9, 2023
1 parent 0f2dd05 commit b644416
Showing 1 changed file with 5 additions and 3 deletions.
8 changes: 5 additions & 3 deletions hw/i386/kvm/xen_xenstore.c
Original file line number Diff line number Diff line change
Expand Up @@ -1357,10 +1357,12 @@ static void fire_watch_cb(void *opaque, const char *path, const char *token)
} else {
deliver_watch(s, path, token);
/*
* If the message was queued because there was already ring activity,
* no need to wake the guest. But if not, we need to send the evtchn.
* Attempt to queue the message into the actual ring, and send
* the event channel notification if any bytes are copied.
*/
xen_be_evtchn_notify(s->eh, s->be_port);
if (s->rsp_pending && put_rsp(s) > 0) {
xen_be_evtchn_notify(s->eh, s->be_port);
}
}
}

Expand Down

0 comments on commit b644416

Please sign in to comment.