Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp668118pxb; Wed, 22 Sep 2021 10:09:59 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyxTMyLM8xeQEP3B1lV5Ey90L6/AHgM5gfXJuv++fEAVWesuyxk2xqOrW7tK8Ajcgflq+RG X-Received: by 2002:a5d:950d:: with SMTP id d13mr84997iom.138.1632330599505; Wed, 22 Sep 2021 10:09:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1632330599; cv=none; d=google.com; s=arc-20160816; b=C0h9QOxDWy5wDFXPDUYGYsohlyQVM7At9EZA7l2vnYTNjgosLMDH7lxhch5brht0/L 62ZYHcpv09hyF9d68gGpixrZGuxS54ZDNxEgcbfUee3Bp7S6tNLnLYHYwQ3Z3euJ4Tag rVNVFZ2WhsEUN5qsaSYJah+JZPTNKEHsDtil9SOLAyNIp9wnMOGzFZBGDIUahor0hmDs 0BRQuY6wooOYmqXtQrB4Kgy6cMJkFA4c4xtTZu9jkLVy0xYKFQaUIZbzWpe5gXsSlS7P mXhdqnpcXPhRmGBpQ90Mlbr5ROndNrj0XfxZBLyitErlrw/fMtsOIYZuXrKW30q0wews gTqQ== 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=hmVOjxLeJWEmyCqfs0Tb1bLYB+sc0BhB8/yHgn5Iolk=; b=GYBFfCtOOmAqBlcRWqu/WtL6IANQEcztboK5AJiZGahGGAWzym/LvZUZmxXEAd2nYl BIzTdjx0UEcSbZUFu3WDDU5rptqNdejhyH9TH2z6fMDBZB9Z918cbYlysL/pb2Mb7lEZ /3U33CWNcndcfpnWUQbxm0954u/n5DEV+LOEJuoTmqt95RFt7YCcBLFOsn/3f82hK0Kh 6odLpUHoesdRJrujNOWR88Q68jad1DtdcEiahWa4ggvJy5FllOZdZOzo2OWnauFwNHR4 grTxMyLYlp7Ytk51PRJqlXDSf71Jsyvw63GSW2mk2L/HBD+/O48CnGdfZOQR6MGEQz9p fE6A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=NgnF+BWB; 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 g187si2947644jag.38.2021.09.22.10.09.37; Wed, 22 Sep 2021 10:09:59 -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=NgnF+BWB; 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 S236834AbhIVRKw (ORCPT + 99 others); Wed, 22 Sep 2021 13:10:52 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:55206 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236784AbhIVRKr (ORCPT ); Wed, 22 Sep 2021 13:10:47 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1632330557; 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=hmVOjxLeJWEmyCqfs0Tb1bLYB+sc0BhB8/yHgn5Iolk=; b=NgnF+BWB1qIyvOF1sLLpahqDOqjuphb3zh3br2fB6XbRFuXccwnRsZqPGknI+AKulHug9G XOTmgD7XAxANHztAF/dy3CLKR7Ib+RQDrXaLqZAeyGh7vc69P1VnNOpUjrEZIbfPurtxZv d11EFjWxhJevi6qweQ265DEDl3OZl0A= 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-259-JbM5iIzSMG2_Abmdmd-yZg-1; Wed, 22 Sep 2021 13:09:13 -0400 X-MC-Unique: JbM5iIzSMG2_Abmdmd-yZg-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 382AD79EDD; Wed, 22 Sep 2021 17:09:12 +0000 (UTC) Received: from thinkpad.redhat.com (unknown [10.39.192.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id E7430970E1; Wed, 22 Sep 2021 17:09:08 +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 1/4] hwrng: virtio - add an internal buffer Date: Wed, 22 Sep 2021 19:09:00 +0200 Message-Id: <20210922170903.577801-2-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-crypto@vger.kernel.org hwrng core uses two buffers that can be mixed in the virtio-rng queue. If the buffer is provided with wait=0 it is enqueued in the virtio-rng queue but unused by the caller. On the next call, core provides another buffer but the first one is filled instead and the new one queued. And the caller reads the data from the new one that is not updated, and the data in the first one are lost. To avoid this mix, virtio-rng needs to use its own unique internal buffer at a cost of a data copy to the caller buffer. Signed-off-by: Laurent Vivier --- drivers/char/hw_random/virtio-rng.c | 43 ++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index a90001e02bf7..208c547dcac1 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -18,13 +18,20 @@ static DEFINE_IDA(rng_index_ida); struct virtrng_info { struct hwrng hwrng; struct virtqueue *vq; - struct completion have_data; char name[25]; - unsigned int data_avail; int index; bool busy; bool hwrng_register_done; bool hwrng_removed; + /* data transfer */ + struct completion have_data; + unsigned int data_avail; + /* minimal size returned by rng_buffer_size() */ +#if SMP_CACHE_BYTES < 32 + u8 data[32]; +#else + u8 data[SMP_CACHE_BYTES]; +#endif }; static void random_recv_done(struct virtqueue *vq) @@ -39,14 +46,14 @@ static void random_recv_done(struct virtqueue *vq) } /* The host will fill any buffer we give it with sweet, sweet randomness. */ -static void register_buffer(struct virtrng_info *vi, u8 *buf, size_t size) +static void register_buffer(struct virtrng_info *vi) { struct scatterlist sg; - sg_init_one(&sg, buf, size); + sg_init_one(&sg, vi->data, sizeof(vi->data)); /* There should always be room for one buffer. */ - virtqueue_add_inbuf(vi->vq, &sg, 1, buf, GFP_KERNEL); + virtqueue_add_inbuf(vi->vq, &sg, 1, vi->data, GFP_KERNEL); virtqueue_kick(vi->vq); } @@ -55,6 +62,8 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) { int ret; struct virtrng_info *vi = (struct virtrng_info *)rng->priv; + unsigned int chunk; + size_t read; if (vi->hwrng_removed) return -ENODEV; @@ -62,19 +71,33 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) if (!vi->busy) { vi->busy = true; reinit_completion(&vi->have_data); - register_buffer(vi, buf, size); + register_buffer(vi); } if (!wait) return 0; - ret = wait_for_completion_killable(&vi->have_data); - if (ret < 0) - return ret; + read = 0; + while (size != 0) { + ret = wait_for_completion_killable(&vi->have_data); + if (ret < 0) + return ret; + + chunk = min_t(unsigned int, size, vi->data_avail); + memcpy(buf + read, vi->data, chunk); + read += chunk; + size -= chunk; + vi->data_avail = 0; + + if (size != 0) { + reinit_completion(&vi->have_data); + register_buffer(vi); + } + } vi->busy = false; - return vi->data_avail; + return read; } static void virtio_cleanup(struct hwrng *rng) -- 2.31.1