From patchwork Fri Mar 6 04:39:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 1250043 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48YZfJ71nTz9sRR for ; Fri, 6 Mar 2020 15:39:52 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ozlabs.ru Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48YZfH2RsvzDqQ6 for ; Fri, 6 Mar 2020 15:39:51 +1100 (AEDT) X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=ozlabs.ru (client-ip=107.174.27.60; helo=ozlabs.ru; envelope-from=aik@ozlabs.ru; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=ozlabs.ru Received: from ozlabs.ru (unknown [107.174.27.60]) by lists.ozlabs.org (Postfix) with ESMTP id 48YZf43TsDzDqLH for ; Fri, 6 Mar 2020 15:39:39 +1100 (AEDT) Received: from fstn1-p1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 6C43AAE80024; Thu, 5 Mar 2020 23:37:56 -0500 (EST) From: Alexey Kardashevskiy To: slof@lists.ozlabs.org Date: Fri, 6 Mar 2020 15:39:33 +1100 Message-Id: <20200306043933.97055-1-aik@ozlabs.ru> X-Mailer: git-send-email 2.17.1 Subject: [SLOF] [PATCH slof] virtio-serial: Close device completely X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" Linux closes stdout at the end of prom_init which triggers the FW quiesce code which closes the virtio-serial instance. This misses stopping the virtio queues, clearing the "emit" token and other things. However this seemed working for a little longer (until the Linux driver took over) till 0cdb2dd13c3e which moved the VQ descriptors around which caused use-after-free corruption. This adds virtio_queue_term_vq(), cleanup in the forth driver, few checks and reverts emit to hvterm-emit. Fixes: 0cdb2dd13c3e ("virtio: Store queue descriptors in virtio_device") Signed-off-by: Alexey Kardashevskiy --- Turns out it is close(stdout) what triggers quiesce, not the client interface's "quiesce". This helps with iommu_platform=off but iommu_platform=on still does not work. Debugging... /home/aik/pbuild/qemu-localhost-ppc64/ppc64-softmmu/qemu-system-ppc64 \ -device virtio-serial,id=virtio-serial0,iommu_platform=on,disable-modern=off,disable-legacy=on,ioeventfd=off \ -nodefaults \ -chardev stdio,id=STDIO0,signal=off,mux=on \ -device virtconsole,id=virtconsole0,chardev=STDIO0 \ -mon id=MON0,chardev=STDIO0,mode=readline \ -nographic \ -vga none \ -machine pseries,cap-cfpc=broken,cap-sbbc=broken,cap-ibs=broken,cap-ccf-assist=off,ic-mode=xics \ -m 2G \ -smp 1 \ -bios p/slof/boot_rom.bin \ -enable-kvm \ -initrd t/le.cpio \ -kernel t/vml4120le \ -L /home/aik/t/qemu-ppc64-bios/ \ -trace events=qemu_trace_events \ -d guest_errors \ -chardev socket,id=SOCKET0,server,nowait,path=qemu.mon.ssh55056 \ -mon chardev=SOCKET0,mode=control --- lib/libvirtio/virtio-serial.c | 7 +++++++ board-qemu/slof/virtio-serial.fs | 11 ++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/libvirtio/virtio-serial.c b/lib/libvirtio/virtio-serial.c index d1503a44f433..92afb02014b2 100644 --- a/lib/libvirtio/virtio-serial.c +++ b/lib/libvirtio/virtio-serial.c @@ -102,6 +102,10 @@ void virtio_serial_shutdown(struct virtio_device *dev) /* Quiesce device */ virtio_set_status(dev, VIRTIO_STAT_FAILED); + /* Stop queues */ + virtio_queue_term_vq(dev, &dev->vq[TX_Q], TX_Q); + virtio_queue_term_vq(dev, &dev->vq[RX_Q], RX_Q); + /* Reset device */ virtio_reset_device(dev); } @@ -114,6 +118,9 @@ int virtio_serial_putchar(struct virtio_device *dev, char c) uint16_t last_used_idx, avail_idx; struct vqs *vq = &dev->vq[TX_Q]; + if (!vq->desc) + return 0; + avail_idx = virtio_modern16_to_cpu(dev, vq->avail->idx); last_used_idx = vq->used->idx; diff --git a/board-qemu/slof/virtio-serial.fs b/board-qemu/slof/virtio-serial.fs index 42ab3e2ccc9c..5293ab1f6341 100644 --- a/board-qemu/slof/virtio-serial.fs +++ b/board-qemu/slof/virtio-serial.fs @@ -25,6 +25,8 @@ virtio-setup-vd VALUE virtiodev close-dev THEN FALSE to initialized? + ['] hvterm-emit to emit + 0 to virtiodev THEN ; @@ -61,12 +63,18 @@ virtiodev virtio-serial-init drop : close open-count 0> IF open-count 1 - dup to open-count - 0= IF close THEN + 0= IF + close + FALSE to initialized? + ['] hvterm-emit to emit + 0 to virtiodev + THEN THEN close ; : write ( addr len -- actual ) + virtiodev 0= IF nip EXIT THEN tuck 0 ?DO dup c@ virtiodev SWAP virtio-serial-putchar @@ -77,6 +85,7 @@ virtiodev virtio-serial-init drop : read ( addr len -- actual ) 0= IF drop 0 EXIT THEN + virtiodev 0= IF nip EXIT THEN virtiodev virtio-serial-haschar 0= IF 0 swap c! -2 EXIT THEN virtiodev virtio-serial-getchar swap c! 1 ;