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/20220405093759.1126835-4-alex.bennee@linaro.org/ Signed-off-by: Haruka Kuze harukak@zohomail.eu
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 harukak@zohomail.eu +L: virtualization@lists.linux.dev +S: Maintained +F: drivers/misc/virtio_rpmb.c +F: include/uapi/linux/virtio_rpmb.h
VIRTIO RTC DRIVER M: Peter Hilber peter.hilber@oss.qualcomm.com L: virtualization@lists.linux.dev 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 theRPMB subsystem, where in-kernel users such as OP-TEE can use it.To compile this driver as a module, choose M here: the module willbe 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