On Thu, Oct 29, 2026 at 05:13:17PM +0900, Haruka Kuze wrote:
> No driver exists for virtio-rpmb devices (virtio ID 28), so OP-TEE
> running in a guest can not use them.
> 
> This registers the virtio-rpmb devices found with the RPMB sub-system.
> Each request is done in one transfer on request queue, and for key
> programming and data writing a result read frame is appended so that
> the device can return the result.
> 
> These frames are copied since the caller's buffers are not always
> usable for DMA.
> 
> These frames follow the emmc definition, so that the device is
> registered as RPMB_TYPE_EMMC. The device has no identifier of own, so
> that a fixed dev_id is used for the key derivation for the device.
> 
> Based on the virtio-rpmb driver in Alex Bennée's RPMB series.
> 
> Link: 
> https://lore.kernel.org/all/[email protected]/
> Signed-off-by: Haruka Kuze <[email protected]>
> ---
>  MAINTAINERS                      |   7 +
>  drivers/misc/Kconfig             |  10 ++
>  drivers/misc/Makefile            |   1 +
>  drivers/misc/virtio_rpmb.c       | 294 +++++++++++++++++++++++++++++++
>  include/uapi/linux/virtio_rpmb.h |  56 ++++++
>  5 files changed, 368 insertions(+)
>  create mode 100644 drivers/misc/virtio_rpmb.c
>  create mode 100644 include/uapi/linux/virtio_rpmb.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 748ce4d1c6a2..488003a28534 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -29707,6 +29707,13 @@ S:   Maintained
>  F:   drivers/char/hw_random/virtio-rng.c
>  F:   include/uapi/linux/virtio_rng.h
>  
> +VIRTIO RPMB DRIVER
> +M:   Haruka Kuze <[email protected]>
> +L:   [email protected]
> +S:   Maintained
> +F:   drivers/misc/virtio_rpmb.c
> +F:   include/uapi/linux/virtio_rpmb.h
> +
>  VIRTIO RTC DRIVER
>  M:   Peter Hilber <[email protected]>
>  L:   [email protected]
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index c40e89cc5724..eb3518ecc8fe 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -91,6 +91,16 @@ config RPMB
>  
>         If unsure, select N.
>  
> +config VIRTIO_RPMB
> +     tristate "Virtio RPMB driver"
> +     depends on VIRTIO && RPMB
> +     help
> +       Driver for virtio RPMB devices. The device is registered with the
> +       RPMB subsystem, where in-kernel users such as OP-TEE can use it.
> +
> +       To compile this driver as a module, choose M here: the module will
> +       be called virtio_rpmb.
> +
>  config TI_FPC202
>       tristate "TI FPC202 Dual Port Controller"
>       depends on I2C
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index 7cc3d615d37a..e4390bb8bdc0 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -16,6 +16,7 @@ obj-$(CONFIG_TIFM_CORE)             += tifm_core.o
>  obj-$(CONFIG_TIFM_7XX1)              += tifm_7xx1.o
>  obj-$(CONFIG_PHANTOM)                += phantom.o
>  obj-$(CONFIG_RPMB)           += rpmb-core.o
> +obj-$(CONFIG_VIRTIO_RPMB)    += virtio_rpmb.o
>  obj-$(CONFIG_QCOM_COINCELL)  += qcom-coincell.o
>  obj-$(CONFIG_QCOM_FASTRPC)   += fastrpc.o
>  obj-$(CONFIG_SENSORS_BH1770) += bh1770glc.o
> diff --git a/drivers/misc/virtio_rpmb.c b/drivers/misc/virtio_rpmb.c
> new file mode 100644
> index 000000000000..f02bdf13aa43
> --- /dev/null
> +++ b/drivers/misc/virtio_rpmb.c
> @@ -0,0 +1,294 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Virtio RPMB driver
> + *
> + * Copyright (c) 2018-2019 Intel Corporation.
> + * Copyright (c) 2021-2022 Linaro Ltd.
> + *
> + * Based on the virtio-rpmb driver in Alex Bennée's RPMB series.
> + */
> +
> +#include <linux/completion.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/rpmb.h>
> +#include <linux/scatterlist.h>
> +#include <linux/slab.h>
> +#include <linux/virtio.h>
> +#include <linux/virtio_config.h>
> +#include <linux/virtio_ids.h>
> +#include <linux/virtio_rpmb.h>
> +
> +#define VIRTIO_RPMB_FRAME_SIZE       sizeof(struct virtio_rpmb_frame)
> +static_assert(VIRTIO_RPMB_FRAME_SIZE == 512);
> +
> +/*
> + * This device has no identifier on its own.
> + * This value is used as input when OP-TEE is deriving the RPMB
> + * key, so it shall stay stable.
> + */
> +static const u8 virtio_rpmb_dev_id[16] = "virtio-rpmb";
> +
> +/**
> + * struct virtio_rpmb - virtio RPMB device state
> + * @vdev: virtio device
> + * @vq: request queue, NULL while the device is gone or frozen
> + * @lock: serializes requests and protects @vq
> + * @rdev: RPMB device
> + * @max_wr: maximum number of blocks in one write request, 0 if unlimited
> + * @max_rd: maximum number of blocks in one read request, 0 if unlimited
> + */
> +struct virtio_rpmb {
> +     struct virtio_device *vdev;
> +     struct virtqueue *vq;
> +     struct mutex lock;
> +     struct rpmb_dev *rdev;
> +     u8 max_wr;
> +     u8 max_rd;
> +};
> +
> +struct virtio_rpmb_req {
> +     struct completion done;
> +     unsigned int len;
> +};
> +
> +static void virtio_rpmb_done(struct virtqueue *vq)
> +{
> +     struct virtio_rpmb_req *req;
> +     unsigned int len;
> +
> +     while ((req = virtqueue_get_buf(vq, &len))) {
> +             req->len = len;
> +             complete(&req->done);
> +     }
> +}
> +
> +static int virtio_rpmb_xfer(struct virtio_rpmb *vr, void *out,
> +                         unsigned int out_len, void *in, unsigned int in_len)
> +{
> +     struct scatterlist out_sg, in_sg, *sgs[2] = { &out_sg, &in_sg };
> +     struct virtio_rpmb_req req;
> +     int ret;
> +
> +     sg_init_one(&out_sg, out, out_len);
> +     sg_init_one(&in_sg, in, in_len);
> +     init_completion(&req.done);
> +
> +     mutex_lock(&vr->lock);

guard()?

thanks,

greg k-h

Reply via email to