chardev: fix backend events regression with mux chardev

Kirill noticied that on recent versions on QEMU he was not able to
trigger SysRq to invoke debug capabilites of Linux Kernel.  He tracked
it down to qemu_chr_be_event() ignoring CHR_EVENT_BREAK due s->be
being NULL. The bug was introduced in 2.8, commit a4afa548fc ("char:
move front end handlers in CharBackend"). Since the commit, the
qemu_chr_be_event() failed to deliver CHR_EVENT_BREAK due to
qemu_chr_fe_init() does not set s->be in case of mux.

Let's fix this by teaching mux to send an event to the frontend with
the focus.

Reported-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Fixes: a4afa548fc ("char: move front end handlers in CharBackend")
Message-Id: <20171103152824.21948-2-marcandre.lureau@redhat.com>
Tested-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Marc-André Lureau 2017-11-03 16:28:23 +01:00 committed by Paolo Bonzini
parent 5a22ab7162
commit d09c4a4787
3 changed files with 23 additions and 6 deletions

View file

@ -43,10 +43,19 @@ static Object *get_chardevs_root(void)
return container_get(object_get_root(), "/chardevs");
}
void qemu_chr_be_event(Chardev *s, int event)
static void chr_be_event(Chardev *s, int event)
{
CharBackend *be = s->be;
if (!be || !be->chr_event) {
return;
}
be->chr_event(be->opaque, event);
}
void qemu_chr_be_event(Chardev *s, int event)
{
/* Keep track if the char device is open */
switch (event) {
case CHR_EVENT_OPENED:
@ -57,11 +66,7 @@ void qemu_chr_be_event(Chardev *s, int event)
break;
}
if (!be || !be->chr_event) {
return;
}
be->chr_event(be->opaque, event);
CHARDEV_GET_CLASS(s)->chr_be_event(s, event);
}
/* Not reporting errors from writing to logfile, as logs are
@ -244,6 +249,7 @@ static void char_class_init(ObjectClass *oc, void *data)
ChardevClass *cc = CHARDEV_CLASS(oc);
cc->chr_write = null_chr_write;
cc->chr_be_event = chr_be_event;
}
static void char_finalize(Object *obj)