Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp1411591pxb; Thu, 28 Oct 2021 03:14:05 -0700 (PDT) X-Google-Smtp-Source: ABdhPJytppwGPkK9QbKz1gRpTQE4KxWxsIkaiIztoG8x1z25PIFILtKJ6tVwSTZKuQGOiXEPZq53 X-Received: by 2002:a50:9b4b:: with SMTP id a11mr4914100edj.316.1635416045514; Thu, 28 Oct 2021 03:14:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1635416045; cv=none; d=google.com; s=arc-20160816; b=i5gvJhLsCEhVux7nAupq+J7hiDss2n4v8lvCb/flTYpFg3hEQutVAhJ+HcXrZ5gBN9 3HFFpV+DVCjDrYfPkO9QEI4FEirqJHxgMX0EBNgCPGsJvDJh1uHg+6k/GBYx81Z4Xl2D JyyHOs8fu24zf1WQdi9ON7NAn7UfckE7WL/Kx0DBKiei6MMJyaGxOgJCETmZN1aKjU1M KeHNBcCRXLyAUAhr9Wyj61Gv4VCincoZUzJsQ6TlgsQ2TnZM79va9AfpkU4GMmSltD2i ndPqMeiNJxB7+SLxh676pM6A2e7Sh8cavCgUNyejpqGDLOdSmKNVgGs9uz4FuHVMpNJ2 ArqQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=x2sevkXopPa/npZcOtqrWwrkEQ1OQe4Rd6KhlqcskKY=; b=RksXpgVWyyGc6ZpYyMyROci4/BS+eCLZbQBeuTCON8do3Q+qM3alyzxlpwwZ3Ds13J iEPpJQwrxNWpDDqN3GyqUFsxbWAZf7xcLLM+Ase5Gnitxoue+X2TATAcQRbchoP/gC1Y HZSFGI5a88CrK17iS0khW97Ic/+ia65MDXDiL7DsonriNIlA5NxB0sJYVDf09bFzndUi g+iigORgtvBMOvWl9YaLci9CJBsPem6LqS3TM0sam7a1v59jzH5ygwNCKeWO2q3wYH+s EXCJVfagFyP8S0X466G6mU9eDNAoTIkf7h/HHBm2qBTWb8UFkYtatOmHeb0BwxrZ/vkC /ZeA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=S86rmGTm; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id hv9si4018525ejc.545.2021.10.28.03.13.41; Thu, 28 Oct 2021 03:14:05 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=S86rmGTm; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230183AbhJ1KOf (ORCPT + 99 others); Thu, 28 Oct 2021 06:14:35 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:53128 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230164AbhJ1KOd (ORCPT ); Thu, 28 Oct 2021 06:14:33 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1635415926; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=x2sevkXopPa/npZcOtqrWwrkEQ1OQe4Rd6KhlqcskKY=; b=S86rmGTmUmatmY5lRkXqnNVA1hqkvlbo94ZNNTBo4YBTjJrZRetl/YQt3hMEqIvTMUE9wj RMJCYSH1rThocZqeRUGmrWbnkjq1O2lecV1DgxvuwmLUo5PmTOp3KcMy2gisEi7G7YTLIn 961OLy2YWh2UAj6g36xKLErqnCXu+8I= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-321-jQeU5JeWNrGSDkOfpfp7dg-1; Thu, 28 Oct 2021 06:12:01 -0400 X-MC-Unique: jQeU5JeWNrGSDkOfpfp7dg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9128F1966323; Thu, 28 Oct 2021 10:11:59 +0000 (UTC) Received: from thinkpad.redhat.com (unknown [10.39.194.156]) by smtp.corp.redhat.com (Postfix) with ESMTP id E7FEA60C04; Thu, 28 Oct 2021 10:11:56 +0000 (UTC) From: Laurent Vivier To: linux-kernel@vger.kernel.org Cc: amit@kernel.org, Herbert Xu , Matt Mackall , virtualization@lists.linux-foundation.org, Dmitriy Vyukov , rusty@rustcorp.com.au, akong@redhat.com, Alexander Potapenko , "Michael S . Tsirkin" , linux-crypto@vger.kernel.org, Laurent Vivier Subject: [PATCH v2 3/4] hwrng: virtio - don't waste entropy Date: Thu, 28 Oct 2021 12:11:10 +0200 Message-Id: <20211028101111.128049-4-lvivier@redhat.com> In-Reply-To: <20211028101111.128049-1-lvivier@redhat.com> References: <20211028101111.128049-1-lvivier@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org if we don't use all the entropy available in the buffer, keep it and use it later. Signed-off-by: Laurent Vivier --- drivers/char/hw_random/virtio-rng.c | 52 +++++++++++++++++++---------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 173aeea835bb..8ba97cf4ca8f 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -26,6 +26,7 @@ struct virtrng_info { /* data transfer */ struct completion have_data; unsigned int data_avail; + unsigned int data_idx; /* minimal size returned by rng_buffer_size() */ #if SMP_CACHE_BYTES < 32 u8 data[32]; @@ -42,6 +43,9 @@ static void random_recv_done(struct virtqueue *vq) if (!virtqueue_get_buf(vi->vq, &vi->data_avail)) return; + vi->data_idx = 0; + vi->busy = false; + complete(&vi->have_data); } @@ -58,6 +62,16 @@ static void register_buffer(struct virtrng_info *vi) virtqueue_kick(vi->vq); } +static unsigned int copy_data(struct virtrng_info *vi, void *buf, + unsigned int size) +{ + size = min_t(unsigned int, size, vi->data_avail); + memcpy(buf, vi->data + vi->data_idx, size); + vi->data_idx += size; + vi->data_avail -= size; + return size; +} + static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) { int ret; @@ -68,17 +82,29 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) if (vi->hwrng_removed) return -ENODEV; - if (!vi->busy) { - vi->busy = true; - reinit_completion(&vi->have_data); - register_buffer(vi); + read = 0; + + /* copy available data */ + if (vi->data_avail) { + chunk = copy_data(vi, buf, size); + size -= chunk; + read += chunk; } if (!wait) - return 0; + return read; - read = 0; + /* We have already copied available entropy, + * so either size is 0 or data_avail is 0 + */ while (size != 0) { + /* data_avail is 0 */ + if (!vi->busy) { + /* no pending request, ask for more */ + vi->busy = true; + reinit_completion(&vi->have_data); + register_buffer(vi); + } ret = wait_for_completion_killable(&vi->have_data); if (ret < 0) return ret; @@ -88,20 +114,11 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) if (vi->data_avail == 0) return read; - chunk = min_t(unsigned int, size, vi->data_avail); - memcpy(buf + read, vi->data, chunk); - read += chunk; + chunk = copy_data(vi, buf + read, size); size -= chunk; - vi->data_avail = 0; - - if (size != 0) { - reinit_completion(&vi->have_data); - register_buffer(vi); - } + read += chunk; } - vi->busy = false; - return read; } @@ -161,6 +178,7 @@ static void remove_common(struct virtio_device *vdev) vi->hwrng_removed = true; vi->data_avail = 0; + vi->data_idx = 0; complete(&vi->have_data); vdev->config->reset(vdev); vi->busy = false; -- 2.31.1