Skip to content

Commit 54a53e9

Browse files
qc-azarrabijenswi-linaro
authored andcommitted
tee: add TEE_IOCTL_PARAM_ATTR_TYPE_UBUF
For drivers that can transfer data to the TEE without using shared memory from client, it is necessary to receive the user address directly, bypassing any processing by the TEE subsystem. Introduce TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT/OUTPUT/INOUT to represent userspace buffers. Reviewed-by: Sumit Garg <sumit.garg@oss.qualcomm.com> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> Tested-by: Harshal Dev <quic_hdev@quicinc.com> Signed-off-by: Amirreza Zarrabi <amirreza.zarrabi@oss.qualcomm.com> Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
1 parent 0cbaf65 commit 54a53e9

3 files changed

Lines changed: 55 additions & 6 deletions

File tree

drivers/tee/tee_core.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,17 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params,
494494
params[n].u.value.b = ip.b;
495495
params[n].u.value.c = ip.c;
496496
break;
497+
case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT:
498+
case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT:
499+
case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INOUT:
500+
params[n].u.ubuf.uaddr = u64_to_user_ptr(ip.a);
501+
params[n].u.ubuf.size = ip.b;
502+
503+
if (!access_ok(params[n].u.ubuf.uaddr,
504+
params[n].u.ubuf.size))
505+
return -EFAULT;
506+
507+
break;
497508
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
498509
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
499510
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
@@ -527,6 +538,11 @@ static int params_to_user(struct tee_ioctl_param __user *uparams,
527538
put_user(p->u.value.c, &up->c))
528539
return -EFAULT;
529540
break;
541+
case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT:
542+
case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INOUT:
543+
if (put_user((u64)p->u.ubuf.size, &up->b))
544+
return -EFAULT;
545+
break;
530546
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
531547
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
532548
if (put_user((u64)p->u.memref.size, &up->b))
@@ -727,6 +743,13 @@ static int params_to_supp(struct tee_context *ctx,
727743
ip.b = p->u.value.b;
728744
ip.c = p->u.value.c;
729745
break;
746+
case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT:
747+
case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT:
748+
case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INOUT:
749+
ip.a = (__force unsigned long)p->u.ubuf.uaddr;
750+
ip.b = p->u.ubuf.size;
751+
ip.c = 0;
752+
break;
730753
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT:
731754
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
732755
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
@@ -829,6 +852,16 @@ static int params_from_supp(struct tee_param *params, size_t num_params,
829852
p->u.value.b = ip.b;
830853
p->u.value.c = ip.c;
831854
break;
855+
case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT:
856+
case TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INOUT:
857+
p->u.ubuf.uaddr = u64_to_user_ptr(ip.a);
858+
p->u.ubuf.size = ip.b;
859+
860+
if (!access_ok(params[n].u.ubuf.uaddr,
861+
params[n].u.ubuf.size))
862+
return -EFAULT;
863+
864+
break;
832865
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT:
833866
case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT:
834867
/*

include/linux/tee_drv.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ struct tee_param_memref {
8282
struct tee_shm *shm;
8383
};
8484

85+
struct tee_param_ubuf {
86+
void __user *uaddr;
87+
size_t size;
88+
};
89+
8590
struct tee_param_value {
8691
u64 a;
8792
u64 b;
@@ -92,6 +97,7 @@ struct tee_param {
9297
u64 attr;
9398
union {
9499
struct tee_param_memref memref;
100+
struct tee_param_ubuf ubuf;
95101
struct tee_param_value value;
96102
} u;
97103
};

include/uapi/linux/tee.h

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,13 @@ struct tee_ioctl_buf_data {
151151
#define TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT 6
152152
#define TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT 7 /* input and output */
153153

154+
/*
155+
* These defines userspace buffer parameters.
156+
*/
157+
#define TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INPUT 8
158+
#define TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_OUTPUT 9
159+
#define TEE_IOCTL_PARAM_ATTR_TYPE_UBUF_INOUT 10 /* input and output */
160+
154161
/*
155162
* Mask for the type part of the attribute, leaves room for more types
156163
*/
@@ -186,14 +193,17 @@ struct tee_ioctl_buf_data {
186193
/**
187194
* struct tee_ioctl_param - parameter
188195
* @attr: attributes
189-
* @a: if a memref, offset into the shared memory object, else a value parameter
190-
* @b: if a memref, size of the buffer, else a value parameter
196+
* @a: if a memref, offset into the shared memory object,
197+
* else if a ubuf, address of the user buffer,
198+
* else a value parameter
199+
* @b: if a memref or ubuf, size of the buffer, else a value parameter
191200
* @c: if a memref, shared memory identifier, else a value parameter
192201
*
193-
* @attr & TEE_PARAM_ATTR_TYPE_MASK indicates if memref or value is used in
194-
* the union. TEE_PARAM_ATTR_TYPE_VALUE_* indicates value and
195-
* TEE_PARAM_ATTR_TYPE_MEMREF_* indicates memref. TEE_PARAM_ATTR_TYPE_NONE
196-
* indicates that none of the members are used.
202+
* @attr & TEE_PARAM_ATTR_TYPE_MASK indicates if memref, ubuf, or value is
203+
* used in the union. TEE_PARAM_ATTR_TYPE_VALUE_* indicates value,
204+
* TEE_PARAM_ATTR_TYPE_MEMREF_* indicates memref, and TEE_PARAM_ATTR_TYPE_UBUF_*
205+
* indicates ubuf. TEE_PARAM_ATTR_TYPE_NONE indicates that none of the members
206+
* are used.
197207
*
198208
* Shared memory is allocated with TEE_IOC_SHM_ALLOC which returns an
199209
* identifier representing the shared memory object. A memref can reference

0 commit comments

Comments
 (0)