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
