Re: [PATCH v4 1/2] tee: enable support to register kernel memory

From: Jens Wiklander
Date: Wed Mar 25 2020 - 04:30:02 EST


Hi Sumit,

On Mon, Mar 23, 2020 at 1:19 PM Sumit Garg <sumit.garg@xxxxxxxxxx> wrote:
>
> Enable support to register kernel memory reference with TEE. This change
> will allow TEE bus drivers to register memory references.
>
> Signed-off-by: Sumit Garg <sumit.garg@xxxxxxxxxx>
> ---
> drivers/tee/tee_shm.c | 26 ++++++++++++++++++++++++--
> include/linux/tee_drv.h | 1 +
> 2 files changed, 25 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c
> index 937ac5a..b88274c 100644
> --- a/drivers/tee/tee_shm.c
> +++ b/drivers/tee/tee_shm.c
> @@ -9,6 +9,7 @@
> #include <linux/sched.h>
> #include <linux/slab.h>
> #include <linux/tee_drv.h>
> +#include <linux/uio.h>
> #include "tee_private.h"
>
> static void tee_shm_release(struct tee_shm *shm)
> @@ -218,13 +219,14 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
> {
> struct tee_device *teedev = ctx->teedev;
> const u32 req_flags = TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED;
> + const u32 req_ker_flags = TEE_SHM_DMA_BUF | TEE_SHM_KERNEL_MAPPED;

I'd prefer naming these two "req_user_flags" and "req_kernel_flags".

Thanks,
Jens

> struct tee_shm *shm;
> void *ret;
> int rc;
> int num_pages;
> unsigned long start;
>
> - if (flags != req_flags)
> + if (flags != req_flags && flags != req_ker_flags)
> return ERR_PTR(-ENOTSUPP);
>
> if (!tee_device_get(teedev))
> @@ -259,7 +261,27 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr,
> goto err;
> }
>
> - rc = get_user_pages_fast(start, num_pages, FOLL_WRITE, shm->pages);
> + if (flags & TEE_SHM_USER_MAPPED) {
> + rc = get_user_pages_fast(start, num_pages, FOLL_WRITE,
> + shm->pages);
> + } else {
> + struct kvec *kiov;
> + int i;
> +
> + kiov = kcalloc(num_pages, sizeof(*kiov), GFP_KERNEL);
> + if (!kiov) {
> + ret = ERR_PTR(-ENOMEM);
> + goto err;
> + }
> +
> + for (i = 0; i < num_pages; i++) {
> + kiov[i].iov_base = (void *)(start + i * PAGE_SIZE);
> + kiov[i].iov_len = PAGE_SIZE;
> + }
> +
> + rc = get_kernel_pages(kiov, num_pages, 0, shm->pages);
> + kfree(kiov);
> + }
> if (rc > 0)
> shm->num_pages = rc;
> if (rc != num_pages) {
> diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h
> index 7a03f68..dedf8fa 100644
> --- a/include/linux/tee_drv.h
> +++ b/include/linux/tee_drv.h
> @@ -26,6 +26,7 @@
> #define TEE_SHM_REGISTER BIT(3) /* Memory registered in secure world */
> #define TEE_SHM_USER_MAPPED BIT(4) /* Memory mapped in user space */
> #define TEE_SHM_POOL BIT(5) /* Memory allocated from pool */
> +#define TEE_SHM_KERNEL_MAPPED BIT(6) /* Memory mapped in kernel space */
>
> struct device;
> struct tee_device;
> --
> 2.7.4
>