From d09c4a47874f30820b08c39ad39bcca9b8cde084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Fri, 3 Nov 2017 16:28:23 +0100 Subject: chardev: fix backend events regression with mux chardev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 a4afa548fc6d ("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 Signed-off-by: Marc-André Lureau Fixes: a4afa548fc6d ("char: move front end handlers in CharBackend") Message-Id: <20171103152824.21948-2-marcandre.lureau@redhat.com> Tested-by: Kirill A. Shutemov Signed-off-by: Paolo Bonzini --- chardev/char-mux.c | 10 ++++++++++ chardev/char.c | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) (limited to 'chardev') diff --git a/chardev/char-mux.c b/chardev/char-mux.c index 4cda5e7458..567bf965cd 100644 --- a/chardev/char-mux.c +++ b/chardev/char-mux.c @@ -123,6 +123,15 @@ static void mux_chr_send_event(MuxChardev *d, int mux_nr, int event) } } +static void mux_chr_be_event(Chardev *chr, int event) +{ + MuxChardev *d = MUX_CHARDEV(chr); + + if (d->focus != -1) { + mux_chr_send_event(d, d->focus, event); + } +} + static int mux_proc_byte(Chardev *chr, MuxChardev *d, int ch) { if (d->term_got_escape) { @@ -346,6 +355,7 @@ static void char_mux_class_init(ObjectClass *oc, void *data) cc->chr_write = mux_chr_write; cc->chr_accept_input = mux_chr_accept_input; cc->chr_add_watch = mux_chr_add_watch; + cc->chr_be_event = mux_chr_be_event; } static const TypeInfo char_mux_type_info = { diff --git a/chardev/char.c b/chardev/char.c index 2ae4f465ec..8c3765ee99 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -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) -- cgit v1.2.1