From patchwork Thu Nov 1 15:11:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Pisarenko X-Patchwork-Id: 10664101 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7B368157A for ; Thu, 1 Nov 2018 15:12:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6A2392BFFE for ; Thu, 1 Nov 2018 15:12:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5EC212BFFF; Thu, 1 Nov 2018 15:12:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B9ED52C021 for ; Thu, 1 Nov 2018 15:12:46 +0000 (UTC) Received: from localhost ([::1]:42541 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gIEeL-00062T-LW for patchwork-qemu-devel@patchwork.kernel.org; Thu, 01 Nov 2018 11:12:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55770) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gIEdd-0005Rm-EN for qemu-devel@nongnu.org; Thu, 01 Nov 2018 11:12:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gIEdZ-0005tS-Fo for qemu-devel@nongnu.org; Thu, 01 Nov 2018 11:12:01 -0400 Received: from mail-lf1-x142.google.com ([2a00:1450:4864:20::142]:40518) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gIEdZ-0005su-6q for qemu-devel@nongnu.org; Thu, 01 Nov 2018 11:11:57 -0400 Received: by mail-lf1-x142.google.com with SMTP id n3-v6so14449151lfe.7 for ; Thu, 01 Nov 2018 08:11:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=lStSumnxCSD9JzyV4oh9MD7mA6FKZv0Rwwl7BoX3j+U=; b=L9csV8CThK90UJOoKmSA/mGwFRBRQekNiTnLtoZF+WMQEXfKOzXK640Xal9zmd7I8o WuunJW/3iBDvc6n5U0dQb0RbHZ6v2ZtLbUIzlp0Ww5lnCqRdrf78BRKEQ23VDbzgYzL3 yiHAlHoeR7Ee+R58QRojYmwGBlPa4MepF5dDsFhwUmQlYhklJMfU5IF9iCNaMKyo1eK4 YUVAIUcQelmK/LC4HmfJ1Ips7uF/94NdOwM2x68t+/ogN7zk3eRtHCQ5PT/hzM7k4qDo y2UW/18TSGXRqopfwJFYrRE2uZaSJxTjjmAc7W97PkqEPvdmVII/ANsAM+sd5Eky73GQ /5HQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=lStSumnxCSD9JzyV4oh9MD7mA6FKZv0Rwwl7BoX3j+U=; b=ryju/BeuAAxKCgixi6qn3+e55t3MCX+42ODYJugEf+pjCFUx91JwzKYfnkoc0Ge4o5 uQ7NUxIC1psAZyVOElq7vYJLU/mFkXkmMLJQp93iIjkhkU4f7eXyqXCbLDYXhkak2Rcc 6QSHYmglvbuTTXVDYPcvMX1HiY8RllehlLbJyGUg/XzB7CS6tsvOG2laCBWW3OCY8MQz Mtl7srSpdfj3+lxBUD0gvmBK31bjx12Jio/93O2sYObp1G2DctyvDaa7RjTRG3dn+iiD fnEjsP8Gv0GQl/VDpizdP1NaLwSQjTE4qw1Ovw2j/xXcFdc7+ex91Yt/Six+4VcTvHAZ 3kYg== X-Gm-Message-State: AGRZ1gIFJuepkLXmLqYad2lwoAgat6F1E9Rw31a/EnF6ez9F8MUvs3oT hqVaxPei2YOf3rW1fYR2a95At51m X-Google-Smtp-Source: AJdET5d0RvN5VS5f5QAP1TlK9v/sjMCICgsFTF+na7scftf4YmTcQHeUmipObLvpxLaC6TebCMSOYQ== X-Received: by 2002:a19:f813:: with SMTP id a19mr4548040lff.67.1541085115179; Thu, 01 Nov 2018 08:11:55 -0700 (PDT) Received: from localhost.localdomain ([77.221.221.49]) by smtp.gmail.com with ESMTPSA id q2-v6sm4633441lfa.37.2018.11.01.08.11.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 01 Nov 2018 08:11:54 -0700 (PDT) From: Artem Pisarenko To: qemu-devel@nongnu.org Date: Thu, 1 Nov 2018 21:11:42 +0600 Message-Id: <49e9640f3fc040a9c9ab40f93935a6572b34bdff.1541085026.git.artem.k.pisarenko@gmail.com> X-Mailer: git-send-email 2.7.4 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::142 Subject: [Qemu-devel] [PATCH] virtserialport/virtconsole: fix messy opening/closing port X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini , "Michael S. Tsirkin" , Artem Pisarenko , Amit Shah Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This fixes wrong interfacing between virtio serial port and bus models, and corresponding chardev backends, caused extra and incorrect activity during guest boot process (when virtserialport device used). Signed-off-by: Artem Pisarenko --- Notes: Although this doesn't trigger any issue/bug (known to me), this may prevent them in future. Also this patch optimizes emulation performance by avoiding extra activity and fixes a case, when serial port wasn't closed if backend closed while being disabled (even worse - serial port will open again!). hw/char/virtio-console.c | 24 ++++++++++++++++++++---- hw/char/virtio-serial-bus.c | 8 +++++++- include/hw/virtio/virtio-serial.h | 8 ++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c index 2cbe1d4..634e9bf 100644 --- a/hw/char/virtio-console.c +++ b/hw/char/virtio-console.c @@ -25,6 +25,7 @@ typedef struct VirtConsole { VirtIOSerialPort parent_obj; + bool backend_active; CharBackend chr; guint watch; } VirtConsole; @@ -149,6 +150,11 @@ static void chr_event(void *opaque, int event) VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(vcon); trace_virtio_console_chr_event(port->id, event); + + if (!vcon->backend_active) { + return; + } + switch (event) { case CHR_EVENT_OPENED: virtio_serial_open(port); @@ -187,17 +193,24 @@ static int chr_be_change(void *opaque) return 0; } +static bool virtconsole_is_backend_enabled(VirtIOSerialPort *port) +{ + VirtConsole *vcon = VIRTIO_CONSOLE(port); + + return vcon->backend_active; +} + static void virtconsole_enable_backend(VirtIOSerialPort *port, bool enable) { VirtConsole *vcon = VIRTIO_CONSOLE(port); - if (!qemu_chr_fe_backend_connected(&vcon->chr)) { - return; - } - if (enable) { VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port); + if (!k->is_console && virtio_serial_is_opened(port) + && !qemu_chr_fe_backend_open(&vcon->chr)) { + virtio_serial_close(port); + } qemu_chr_fe_set_handlers(&vcon->chr, chr_can_read, chr_read, k->is_console ? NULL : chr_event, chr_be_change, vcon, NULL, false); @@ -205,6 +218,7 @@ static void virtconsole_enable_backend(VirtIOSerialPort *port, bool enable) qemu_chr_fe_set_handlers(&vcon->chr, NULL, NULL, NULL, NULL, NULL, NULL, false); } + vcon->backend_active = enable; } static void virtconsole_realize(DeviceState *dev, Error **errp) @@ -220,6 +234,7 @@ static void virtconsole_realize(DeviceState *dev, Error **errp) } if (qemu_chr_fe_backend_connected(&vcon->chr)) { + vcon->backend_active = true; /* * For consoles we don't block guest data transfer just * because nothing is connected - we'll just let it go @@ -278,6 +293,7 @@ static void virtserialport_class_init(ObjectClass *klass, void *data) k->unrealize = virtconsole_unrealize; k->have_data = flush_buf; k->set_guest_connected = set_guest_connected; + k->is_backend_enabled = virtconsole_is_backend_enabled; k->enable_backend = virtconsole_enable_backend; k->guest_writable = guest_writable; dc->props = virtserialport_properties; diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index 04e3ebe..d23d99d 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -258,6 +258,11 @@ static size_t send_control_event(VirtIOSerial *vser, uint32_t port_id, } /* Functions for use inside qemu to open and read from/write to ports */ +bool virtio_serial_is_opened(VirtIOSerialPort *port) +{ + return port->host_connected; +} + int virtio_serial_open(VirtIOSerialPort *port) { /* Don't allow opening an already-open port */ @@ -643,7 +648,8 @@ static void set_status(VirtIODevice *vdev, uint8_t status) QTAILQ_FOREACH(port, &vser->ports, next) { VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port); - if (vsc->enable_backend) { + if (vsc->is_backend_enabled && vsc->enable_backend + && (vsc->is_backend_enabled(port) != vdev->vm_running)) { vsc->enable_backend(port, vdev->vm_running); } } diff --git a/include/hw/virtio/virtio-serial.h b/include/hw/virtio/virtio-serial.h index 12657a9..4b72562 100644 --- a/include/hw/virtio/virtio-serial.h +++ b/include/hw/virtio/virtio-serial.h @@ -58,6 +58,8 @@ typedef struct VirtIOSerialPortClass { /* Guest opened/closed device. */ void (*set_guest_connected)(VirtIOSerialPort *port, int guest_connected); + /* Is backend currently enabled for virtio serial port */ + bool (*is_backend_enabled)(VirtIOSerialPort *port); /* Enable/disable backend for virtio serial port */ void (*enable_backend)(VirtIOSerialPort *port, bool enable); @@ -194,6 +196,12 @@ struct VirtIOSerial { /* Interface to the virtio-serial bus */ /* + * Checks status of connection to the port + * Returns true if connected, false otherwise. + */ +bool virtio_serial_is_opened(VirtIOSerialPort *port); + +/* * Open a connection to the port * Returns 0 on success (always). */