From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57322) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bG8Kk-0003J0-8A for qemu-devel@nongnu.org; Thu, 23 Jun 2016 13:22:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bG8Kj-0006VY-6w for qemu-devel@nongnu.org; Thu, 23 Jun 2016 13:22:30 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45614) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bG8Ki-0006VO-WA for qemu-devel@nongnu.org; Thu, 23 Jun 2016 13:22:29 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 93C2BC01B13F for ; Thu, 23 Jun 2016 17:22:28 +0000 (UTC) From: Paolo Bonzini Date: Thu, 23 Jun 2016 19:22:18 +0200 Message-Id: <1466702539-17607-6-git-send-email-pbonzini@redhat.com> In-Reply-To: <1466702539-17607-1-git-send-email-pbonzini@redhat.com> References: <1466702539-17607-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH v2 5/6] serial: remove watch on reset List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: dgilbert@redhat.com Otherwise, this can cause serial_xmit to be entered with LSR.TEMT=0, which is invalid and causes an assertion failure. Reported-by: Bret Ketchum Tested-by: Bret Ketchum Signed-off-by: Paolo Bonzini --- hw/char/serial.c | 16 ++++++++++++---- include/hw/char/serial.h | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/hw/char/serial.c b/hw/char/serial.c index 0b09094..af39e8f 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -228,6 +228,7 @@ static gboolean serial_watch_cb(GIOChannel *chan, GIOCondition cond, void *opaque) { SerialState *s = opaque; + s->watch_tag = 0; serial_xmit(s); return FALSE; } @@ -258,10 +259,12 @@ static void serial_xmit(SerialState *s) if (s->mcr & UART_MCR_LOOP) { /* in loopback mode, say that we just received a char */ serial_receive1(s, &s->tsr, 1); - } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) { - if (s->tsr_retry < MAX_XMIT_RETRY && - qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, - serial_watch_cb, s) > 0) { + } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1 && + s->tsr_retry < MAX_XMIT_RETRY) { + assert(s->watch_tag == 0); + s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, + serial_watch_cb, s); + if (s->watch_tag > 0) { s->tsr_retry++; return; } @@ -821,6 +824,11 @@ static void serial_reset(void *opaque) { SerialState *s = opaque; + if (s->watch_tag > 0) { + g_source_remove(s->watch_tag); + s->watch_tag = 0; + } + s->rbr = 0; s->ier = 0; s->iir = UART_IIR_NO_INT; diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h index 6a322eb..9feddc6 100644 --- a/include/hw/char/serial.h +++ b/include/hw/char/serial.h @@ -56,6 +56,7 @@ struct SerialState { int it_shift; int baudbase; uint32_t tsr_retry; + guint watch_tag; uint32_t wakeup; /* Time when the last byte was successfully sent out of the tsr */ -- 2.5.5