Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp669137pxb; Wed, 22 Sep 2021 10:11:00 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzHEKLefo0DVMJPHjDCTxPkjBv7tj8AeZtFZnbidfRXjgNjGBahHomFnRem1df6/aIfUrDl X-Received: by 2002:a05:6e02:1588:: with SMTP id m8mr113067ilu.188.1632330660232; Wed, 22 Sep 2021 10:11:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1632330660; cv=none; d=google.com; s=arc-20160816; b=UmSf8BWBRUPd/Ww/WDoyvgf3XwesQjdF9xFfLZpzhpcPqpca65fhvA+/upve7pjLOa hkRYQR65bzex/vptFZ6x7lAJZ5gtbuzzBp64sEBmv+R/wb2ArcncK/jvw5K1f/KWg3rE lotplCFVD03HyYarc9D9I4JxmUL1QJV8LYL9aazQKoOhTBrFDnfCi6Ni6sZTtEiBfjFF z0wMoppqODWkc8rF/kTvYdUHbzrDH7A7CYhEnSSFOOgI/j8skYfPqfXf6Jc+VEOwxbH/ 71ZLoRCNiSgiVSc0RykbNasfUj3T60nP2D8OcUxYDxcewRobx0xsGwvhPPsnFRLm2p4k e8dg== 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=l9z0y0N2g77ayUcG/jgND8ffRv4aoJnf2ehdKHclmbQOkuHImwrUsaj1Ht4dyxnIVf EVqhM5Z+bX3xCayWEGsq0GKTjzvQ2OTBhLKfS266rEdWHiRnlWVRLDlFJ0eEczcPqCt1 SKcbKMq8odGZ57pnuiUXtI0Nan+AOf0zXUg70UUzzaz7U5akTyJEf6TCnPFTj0x4AztU R9T5R4FoFo3HuW2QOnsXB83EknKS35f9Q/vitzy3+4b6DiRG5J8yCxnA+eKNxUSjRpeX bWtes/FG3k2FckIaXxUBj2RqZTG//YpPPbHbTEzeKmZ8uFBufB1IxgoVC246rZl6Ew3V EM3A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=G1hnMxE7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-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 g6si1445009ila.86.2021.09.22.10.10.46; Wed, 22 Sep 2021 10:11:00 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-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=G1hnMxE7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-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 S236823AbhIVRLD (ORCPT + 99 others); Wed, 22 Sep 2021 13:11:03 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:32805 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236824AbhIVRKv (ORCPT ); Wed, 22 Sep 2021 13:10:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1632330560; 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=G1hnMxE7kjSWG1vNvm1gpk8gqBW8oM9bKeTjOdF047ezBS7bWxgoiVTtXMs9a+a/yo5Art Z42znKTaWEd30M3RM1hr1P8oeAkK4YnhIKLcKIJdbdVFpq0/rm4JTEHgB0tA6lXokO01NX nz0iffdffkdHqbOM5oe6mB/rDIDCHiI= 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-563-qy-jW-h4PeK5UPnxP8bkMQ-1; Wed, 22 Sep 2021 13:09:19 -0400 X-MC-Unique: qy-jW-h4PeK5UPnxP8bkMQ-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id F117C180830F; Wed, 22 Sep 2021 17:09:17 +0000 (UTC) Received: from thinkpad.redhat.com (unknown [10.39.192.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7098B652A1; Wed, 22 Sep 2021 17:09:15 +0000 (UTC) From: Laurent Vivier To: linux-kernel@vger.kernel.org Cc: Alexander Potapenko , linux-crypto@vger.kernel.org, Dmitriy Vyukov , rusty@rustcorp.com.au, amit@kernel.org, akong@redhat.com, Herbert Xu , "Michael S . Tsirkin" , Matt Mackall , virtualization@lists.linux-foundation.org, Laurent Vivier Subject: [PATCH 3/4] hwrng: virtio - don't waste entropy Date: Wed, 22 Sep 2021 19:09:02 +0200 Message-Id: <20210922170903.577801-4-lvivier@redhat.com> In-Reply-To: <20210922170903.577801-1-lvivier@redhat.com> References: <20210922170903.577801-1-lvivier@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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