Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp1410282pxb; Thu, 28 Oct 2021 03:12:38 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz/5Hm32CV7DJnRL8u34xZJqMkb+XUJ4uI/+AaNSoUmjfCQwee1Vq/QGIXnAA1EkQh42alR X-Received: by 2002:a17:907:3d9e:: with SMTP id he30mr4200917ejc.9.1635415958783; Thu, 28 Oct 2021 03:12:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1635415958; cv=none; d=google.com; s=arc-20160816; b=dmX4XD9Di22V67LLewxB/OERTWQO95/IoXovqgro+kTlABTXktnUmhFeZzFn1y8a9c NY7EyDVZrYP+F/Dega/TE2X81bJUjE5X/JDB8hlXYsjvZ6XzWe9qr7vode4jfHEuzNK+ IobdwEYq3GqBaAzRc33BdfwXMLBnpwmKLpxBZsUea79HLvImkbx0THg+8bDRcKw7xk3i XUHvCBcMhWeQIfRFBBZIdm1GO6A/azUqW7Sk13w50EIGyyjKWbddcE7NQErRG6Pub/oX +KGmHAE370+8anxILLZK/PmjRJ01orIp4LGa/vXSQx8RlAvViq+KLnWePzpv3tAVpBV+ zAYg== 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=HdJ92XzufrX9eOcMyW1zoU8UWGOcU79OxK8YybzUEiv8dtOfT0dV0bH3SzMLrYdEga /2ZXlbiPibuYqDPPHVF6vujGtC53rjDeoZvEIPrrVO0GTU4KxCTprG8gCKJPYsndiaPn nxFPiLpWszKZYbhA9IdsxrZDmlEjWZyg9V1JOR2Q9fy6AQA2ROwfRaB1hSeFyWKqt/Mv LLPix6A2DRr6Ds3kuMoJKi0DwecsYDv5LWQW7vXRDNShQQkr8leNu1JJpwhpQffD/nlQ X8tBicmZ/z34P1SARkOj3MHR4bWRiRL04SOjiAYZLalqYxikgIfKfhrLZXqJEYZcIozh EpSg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=TjziSPrI; 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 dp9si4293598ejc.187.2021.10.28.03.12.11; Thu, 28 Oct 2021 03:12:38 -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=TjziSPrI; 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 S230025AbhJ1KOJ (ORCPT + 99 others); Thu, 28 Oct 2021 06:14:09 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:43484 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229946AbhJ1KOI (ORCPT ); Thu, 28 Oct 2021 06:14:08 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1635415901; 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=TjziSPrIe9YlE5ESapYrO8iB8bQ1hRg6ClduuPc5WB2a/Fq1WeIp7jAb/IEi2fr2IRSgcS Fww6htViXNvyKG78CLbtT8KmUNpR3cqPg6hhTu+oByUlbK2x3Eqb6GzOZqD2WtaB2gKB5C /CNC98wYbQF5jZPWkNFxqUAUvhqf7no= 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-174-jX_5fmHnMCy2UBIWTqUp1w-1; Thu, 28 Oct 2021 06:11:37 -0400 X-MC-Unique: jX_5fmHnMCy2UBIWTqUp1w-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 135D710A8E00; Thu, 28 Oct 2021 10:11:36 +0000 (UTC) Received: from thinkpad.redhat.com (unknown [10.39.194.156]) by smtp.corp.redhat.com (Postfix) with ESMTP id C02BE60CA0; Thu, 28 Oct 2021 10:11:31 +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 1/4] hwrng: virtio - add an internal buffer Date: Thu, 28 Oct 2021 12:11:08 +0200 Message-Id: <20211028101111.128049-2-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 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