From nobody Fri May 17 06:43:26 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1594764873; cv=none; d=zohomail.com; s=zohoarc; b=ltJfA9c2Nwhg6GfPjgLx7mRvFsZcPYM38RjRZGXxr8E2KvfgZhieWaHYszD9neL1HN8aWiR1GKzpJ2Wv1+315wZa+9MuDfBq91+xi9SFW3x6wmatVSS3Nxg34YMGoVlBuswOnTLrMl/xBNmlVUf64WbyinG6L2N8HBAyPU5tboA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1594764873; h=Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To; bh=qB93Li6ekbZFSAJ+sRf6yNJVZi8dzccptjt2UtOV3P4=; b=h8L86gGTvRHYsIdazA47XBLOtDHPEhxIJiTo7ZYJtasC4ydHaGoGSwRLe+qHgpB++pX4mwVh48PqBrhOSx2Dt20cKPz0rpJ93WvO5/vUSwhin81VAHP4dklHowIEEL6n9ryciXNloLrbvQkarZTAfSEYJQJyuPVuAvhhcLkEmtg= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1594764873002823.8148048710616; Tue, 14 Jul 2020 15:14:33 -0700 (PDT) Received: from localhost ([::1]:47006 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jvTC2-0006XO-Ug for importer@patchew.org; Tue, 14 Jul 2020 18:14:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43622) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jvTBM-000612-0m for qemu-devel@nongnu.org; Tue, 14 Jul 2020 18:13:48 -0400 Received: from [195.135.220.15] (port=40120 helo=mx2.suse.de) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jvTBK-0001eP-0M for qemu-devel@nongnu.org; Tue, 14 Jul 2020 18:13:47 -0400 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 0D868B12D; Tue, 14 Jul 2020 22:00:44 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: mwilck@suse.com To: "Michael S. Tsirkin" , Jason Wang Subject: [PATCH] virtio-rng: return available data with O_NONBLOCK Date: Wed, 15 Jul 2020 00:00:19 +0200 Message-Id: <20200714220019.10854-1-mwilck@suse.com> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Host-Lookup-Failed: Reverse DNS lookup failed for 195.135.220.15 (failed) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=mwilck@suse.com; helo=mx2.suse.de X-detected-operating-system: by eggs.gnu.org: First seen = 2020/07/13 21:34:19 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] X-Spam_score_int: -33 X-Spam_score: -3.4 X-Spam_bar: --- X-Spam_report: (-3.4 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Martin Wilck , qemu-devel@nongnu.org, virtualization@lists.linux-foundation.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Martin Wilck If a program opens /dev/hwrng with O_NONBLOCK and uses poll() and non-blocking read() to retrieve random data, it ends up in a tight loop with poll() always returning POLLIN and read() returning EAGAIN. This repeats forever until some process makes a blocking read() call. The reason is that virtio_read() always returns 0 in non-blocking mode, even if data is available. The following test program illustrates the behavior. void loop(int fd) { struct pollfd pfd0 =3D { .fd =3D fd, .events =3D POLLIN, }; int rc; unsigned int n; for (n =3D LOOPS; n > 0; n--) { struct pollfd pfd =3D pfd0; char buf[SIZE]; rc =3D poll(&pfd, 1, 1); if (rc > 0) { int rd =3D read(fd, buf, sizeof(buf)); if (rd =3D=3D -1) perror("read"); else printf("read %d bytes\n", rd); } else if (rc =3D=3D -1) perror("poll"); else fprintf(stderr, "timeout\n"); } } int main(void) { int fd; fd =3D open("/dev/hwrng", O_RDONLY|O_NONBLOCK); if (fd =3D=3D -1) { perror("open"); return 1; }; loop(fd); close(fd); return 0; } This can be observed in the real word e.g. with nested qemu/KVM virtual machines, if both the "outer" and "inner" VMs have a virtio-rng device. If the "inner" VM requests random data, qemu running in the "outer" VM uses this device in a non-blocking manner like the test program above. Fix it by returning available data if it exists. Signed-off-by: Martin Wilck --- drivers/char/hw_random/virtio-rng.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/v= irtio-rng.c index 79a6e47b5fbc..94806308d814 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -59,6 +59,9 @@ static int virtio_read(struct hwrng *rng, void *buf, size= _t size, bool wait) if (vi->hwrng_removed) return -ENODEV; =20 + if (vi->data_avail >=3D size || (vi->data_avail && !wait)) + return vi->data_avail; + if (!vi->busy) { vi->busy =3D true; reinit_completion(&vi->have_data); --=20 2.26.2