Sync tee.h with Linux kernel v5.6

TEE_IOC_SHM_REGISTER_FD (not upstream) and struct is moved down just
above TEE_IOC_SHM_REGISTER to keep IOCTL numbers in order.

struct tee_ioctl_param now matches the kernel version, that is, the
union with value and memref is replaced by just the value fields.

Acked-by: Jerome Forissier <jerome@forissier.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/libteec/include/linux/tee.h b/libteec/include/linux/tee.h
index 8b3b68a..f883ebc 100644
--- a/libteec/include/linux/tee.h
+++ b/libteec/include/linux/tee.h
@@ -48,8 +48,9 @@
 
 #define TEE_MAX_ARG_SIZE	1024
 
-#define TEE_GEN_CAP_GP		(1 << 0) /* GlobalPlatform compliant TEE */
-#define TEE_GEN_CAP_REG_MEM	(1 << 2) /* Support registering shared memory */
+#define TEE_GEN_CAP_GP		(1 << 0)/* GlobalPlatform compliant TEE */
+#define TEE_GEN_CAP_PRIVILEGED	(1 << 1)/* Privileged device (for supplicant) */
+#define TEE_GEN_CAP_REG_MEM	(1 << 2)/* Supports registering shared memory */
 #define TEE_GEN_CAP_MEMREF_NULL	(1 << 3) /* Support NULL MemRef */
 
 #define TEE_MEMREF_NULL		((__u64)-1) /* NULL MemRef Buffer */
@@ -58,6 +59,7 @@
  * TEE Implementation ID
  */
 #define TEE_IMPL_ID_OPTEE	1
+#define TEE_IMPL_ID_AMDTEE	2
 
 /*
  * OP-TEE specific capabilities
@@ -137,60 +139,6 @@
 	__s32 id;
 } __aligned(8);
 
-/**
- * TEE_IOC_SHM_REGISTER_FD - register a shared memory from a file descriptor
- *
- * Returns a file descriptor on success or < 0 on failure
- *
- * The returned file descriptor refers to the shared memory object in kernel
- * land. The shared memory is freed when the descriptor is closed.
- */
-#define TEE_IOC_SHM_REGISTER_FD	_IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 8, \
-				     struct tee_ioctl_shm_register_fd_data)
-
-/**
- * struct tee_ioctl_shm_register_data - Shared memory register argument
- * @addr:      [in] Start address of shared memory to register
- * @length:    [in/out] Length of shared memory to register
- * @flags:     [in/out] Flags to/from registration.
- * @id:                [out] Identifier of the shared memory
- *
- * The flags field should currently be zero as input. Updated by the call
- * with actual flags as defined by TEE_IOCTL_SHM_* above.
- * This structure is used as argument for TEE_IOC_SHM_REGISTER below.
- */
-struct tee_ioctl_shm_register_data {
-	__u64 addr;
-	__u64 length;
-	__u32 flags;
-	__s32 id;
-};
-
-/**
- * TEE_IOC_SHM_REGISTER - Register shared memory
- *
- * Registers shared memory between the user space process and secure OS.
- *
- * Returns a file descriptor on success or < 0 on failure
- *
- * The shared memory is unregisterred when the descriptor is closed.
- */
-#define TEE_IOC_SHM_REGISTER   _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 9, \
-				     struct tee_ioctl_shm_register_data)
-
-/**
- * struct tee_ioctl_buf_data - Variable sized buffer
- * @buf_ptr:	[in] A __user pointer to a buffer
- * @buf_len:	[in] Length of the buffer above
- *
- * Used as argument for TEE_IOC_OPEN_SESSION, TEE_IOC_INVOKE,
- * TEE_IOC_SUPPL_RECV, and TEE_IOC_SUPPL_SEND below.
- */
-struct tee_ioctl_buf_data {
-	__u64 buf_ptr;
-	__u64 buf_len;
-};
-
 /*
  * Attributes for struct tee_ioctl_param, selects field in the union
  */
@@ -235,62 +183,28 @@
 #define TEE_IOCTL_LOGIN_GROUP_APPLICATION	6
 
 /**
- * struct tee_ioctl_param_memref - memory reference
- * @shm_offs:	Offset into the shared memory object
- * @size:	Size of the buffer
- * @shm_id:	Shared memory identifier
- *
- * Shared memory is allocated with TEE_IOC_SHM_ALLOC which returns an
- * identifier representing the shared memory object. A memref can reference
- * a part of a shared memory by specifying an offset (@shm_offs) and @size
- * of the object. To supply the entire shared memory object set @shm_offs
- * to 0 and @size to the previously returned size of the object.
- *
- * As per GlobalPlatform Client API v1.0 specification, a client can present
- * a NULL shared memory reference when querying an output (or in/out) shared
- * memory size.
- *
- * If a null reference is passed to a TA in the TEE, the field @c of
- * structure tee_ioctl_param_value must be set to TEE_MEMREF_NULL indicating
- * a NULL memory reference.
- */
-struct tee_ioctl_param_memref {
-	__u64 shm_offs;
-	__u64 size;
-	__s64 shm_id;
-};
-
-/**
- * struct tee_ioctl_param_value - values
- * @a: first value
- * @b: second value
- * @c: third value
- *
- * Value parameters are passed unchecked to the destination
- */
-struct tee_ioctl_param_value {
-	__u64 a;
-	__u64 b;
-	__u64 c;
-};
-
-/**
  * struct tee_ioctl_param - parameter
  * @attr: attributes
- * @memref: a memory reference
- * @value: a value
+ * @a: if a memref, offset into the shared memory object, else a value parameter
+ * @b: if a memref, size of the buffer, else a value parameter
+ * @c: if a memref, shared memory identifier, else a value parameter
  *
  * @attr & TEE_PARAM_ATTR_TYPE_MASK indicates if memref or value is used in
  * the union. TEE_PARAM_ATTR_TYPE_VALUE_* indicates value and
  * TEE_PARAM_ATTR_TYPE_MEMREF_* indicates memref. TEE_PARAM_ATTR_TYPE_NONE
  * indicates that none of the members are used.
+ *
+ * Shared memory is allocated with TEE_IOC_SHM_ALLOC which returns an
+ * identifier representing the shared memory object. A memref can reference
+ * a part of a shared memory by specifying an offset (@a) and size (@b) of
+ * the object. To supply the entire shared memory object set the offset
+ * (@a) to 0 and size (@b) to the previously returned size of the object.
  */
 struct tee_ioctl_param {
 	__u64 attr;
-	union {
-		struct tee_ioctl_param_memref memref;
-		struct tee_ioctl_param_value value;
-	} u;
+	__u64 a;
+	__u64 b;
+	__u64 c;
 };
 
 #define TEE_IOCTL_UUID_LEN		16
@@ -315,17 +229,9 @@
 	__u32 ret;
 	__u32 ret_origin;
 	__u32 num_params;
-	/*
-	 * this struct is 8 byte aligned since the 'struct tee_ioctl_param'
-	 * which follows requires 8 byte alignment.
-	 *
-	 * Commented out element used to visualize the layout dynamic part
-	 * of the struct. This field is not available at all if
-	 * num_params == 0.
-	 *
-	 * struct tee_ioctl_param params[num_params];
-	 */
-} __aligned(8);
+	/* num_params tells the actual number of element in params */
+	struct tee_ioctl_param params[];
+};
 
 /**
  * TEE_IOC_OPEN_SESSION - opens a session to a Trusted Application
@@ -354,17 +260,9 @@
 	__u32 ret;
 	__u32 ret_origin;
 	__u32 num_params;
-	/*
-	 * this struct is 8 byte aligned since the 'struct tee_ioctl_param'
-	 * which follows requires 8 byte alignment.
-	 *
-	 * Commented out element used to visualize the layout dynamic part
-	 * of the struct. This field is not available at all if
-	 * num_params == 0.
-	 *
-	 * struct tee_ioctl_param params[num_params];
-	 */
-} __aligned(8);
+	/* num_params tells the actual number of element in params */
+	struct tee_ioctl_param params[];
+};
 
 /**
  * TEE_IOC_INVOKE - Invokes a function in a Trusted Application
@@ -417,17 +315,9 @@
 struct tee_iocl_supp_recv_arg {
 	__u32 func;
 	__u32 num_params;
-	/*
-	 * this struct is 8 byte aligned since the 'struct tee_ioctl_param'
-	 * which follows requires 8 byte alignment.
-	 *
-	 * Commented out element used to visualize the layout dynamic part
-	 * of the struct. This field is not available at all if
-	 * num_params == 0.
-	 *
-	 * struct tee_ioctl_param params[num_params];
-	 */
-} __aligned(8);
+	/* num_params tells the actual number of element in params */
+	struct tee_ioctl_param params[];
+};
 
 /**
  * TEE_IOC_SUPPL_RECV - Receive a request for a supplicant function
@@ -446,17 +336,10 @@
 struct tee_iocl_supp_send_arg {
 	__u32 ret;
 	__u32 num_params;
-	/*
-	 * this struct is 8 byte aligned since the 'struct tee_ioctl_param'
-	 * which follows requires 8 byte alignment.
-	 *
-	 * Commented out element used to visualize the layout dynamic part
-	 * of the struct. This field is not available at all if
-	 * num_params == 0.
-	 *
-	 * struct tee_ioctl_param params[num_params];
-	 */
-} __aligned(8);
+	/* num_params tells the actual number of element in params */
+	struct tee_ioctl_param params[];
+};
+
 /**
  * TEE_IOC_SUPPL_SEND - Receive a request for a supplicant function
  *
@@ -466,6 +349,59 @@
 #define TEE_IOC_SUPPL_SEND	_IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 7, \
 				     struct tee_ioctl_buf_data)
 
+/**
+ * struct tee_ioctl_shm_register_data - Shared memory register argument
+ * @addr:      [in] Start address of shared memory to register
+ * @length:    [in/out] Length of shared memory to register
+ * @flags:     [in/out] Flags to/from registration.
+ * @id:                [out] Identifier of the shared memory
+ *
+ * The flags field should currently be zero as input. Updated by the call
+ * with actual flags as defined by TEE_IOCTL_SHM_* above.
+ * This structure is used as argument for TEE_IOC_SHM_REGISTER below.
+ */
+struct tee_ioctl_shm_register_data {
+	__u64 addr;
+	__u64 length;
+	__u32 flags;
+	__s32 id;
+};
+
+/**
+ * TEE_IOC_SHM_REGISTER_FD - register a shared memory from a file descriptor
+ *
+ * Returns a file descriptor on success or < 0 on failure
+ *
+ * The returned file descriptor refers to the shared memory object in kernel
+ * land. The shared memory is freed when the descriptor is closed.
+ */
+#define TEE_IOC_SHM_REGISTER_FD	_IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 8, \
+				     struct tee_ioctl_shm_register_fd_data)
+
+/**
+ * struct tee_ioctl_buf_data - Variable sized buffer
+ * @buf_ptr:	[in] A __user pointer to a buffer
+ * @buf_len:	[in] Length of the buffer above
+ *
+ * Used as argument for TEE_IOC_OPEN_SESSION, TEE_IOC_INVOKE,
+ * TEE_IOC_SUPPL_RECV, and TEE_IOC_SUPPL_SEND below.
+ */
+struct tee_ioctl_buf_data {
+	__u64 buf_ptr;
+	__u64 buf_len;
+};
+
+/**
+ * TEE_IOC_SHM_REGISTER - Register shared memory argument
+ *
+ * Registers shared memory between the user space process and secure OS.
+ *
+ * Returns a file descriptor on success or < 0 on failure
+ *
+ * The shared memory is unregisterred when the descriptor is closed.
+ */
+#define TEE_IOC_SHM_REGISTER   _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 9, \
+				     struct tee_ioctl_shm_register_data)
 /*
  * Five syscalls are used when communicating with the TEE driver.
  * open(): opens the device associated with the driver
diff --git a/libteec/src/tee_client_api.c b/libteec/src/tee_client_api.c
index c265268..c8511c2 100644
--- a/libteec/src/tee_client_api.c
+++ b/libteec/src/tee_client_api.c
@@ -51,6 +51,11 @@
 /* How many device sequence numbers will be tried before giving up */
 #define TEEC_MAX_DEV_SEQ	10
 
+/* Helpers to access memref parts of a struct tee_ioctl_param */
+#define MEMREF_SHM_ID(p)	((p)->c)
+#define MEMREF_SHM_OFFS(p)	((p)->a)
+#define MEMREF_SIZE(p)		((p)->b)
+
 static pthread_mutex_t teec_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static void teec_mutex_lock(pthread_mutex_t *mu)
@@ -196,7 +201,7 @@
 			return TEEC_ERROR_BAD_PARAMETERS;
 
 		/* Null pointer, indicate no shared memory attached */
-		param->u.memref.shm_id = TEE_MEMREF_NULL;
+		MEMREF_SHM_ID(param) = TEE_MEMREF_NULL;
 		shm->id = -1;
 	} else {
 		res = TEEC_AllocateSharedMemory(ctx, shm);
@@ -204,10 +209,11 @@
 			return res;
 
 		memcpy(shm->buffer, tmpref->buffer, tmpref->size);
-		param->u.memref.shm_id = shm->id;
+		MEMREF_SHM_ID(param) = shm->id;
 	}
 
-	param->u.memref.size = tmpref->size;
+	MEMREF_SIZE(param) = tmpref->size;
+
 	return TEEC_SUCCESS;
 }
 
@@ -237,8 +243,9 @@
 	if (shm->shadow_buffer && (flags & TEEC_MEM_INPUT))
 		memcpy(shm->shadow_buffer, shm->buffer, shm->size);
 
-	param->u.memref.shm_id = shm->id;
-	param->u.memref.size = shm->size;
+	MEMREF_SHM_ID(param) = shm->id;
+	MEMREF_SIZE(param) = shm->size;
+
 	return TEEC_SUCCESS;
 }
 
@@ -284,9 +291,10 @@
 		memcpy((char *)shm->shadow_buffer + memref->offset,
 		       (char *)shm->buffer + memref->offset, memref->size);
 
-	param->u.memref.shm_id = shm->id;
-	param->u.memref.shm_offs = memref->offset;
-	param->u.memref.size = memref->size;
+	MEMREF_SHM_ID(param) = shm->id;
+	MEMREF_SHM_OFFS(param) = memref->offset;
+	MEMREF_SIZE(param) = memref->size;
+
 	return TEEC_SUCCESS;
 }
 
@@ -318,8 +326,8 @@
 		case TEEC_VALUE_OUTPUT:
 		case TEEC_VALUE_INOUT:
 			params[n].attr = param_type;
-			params[n].u.value.a = operation->params[n].value.a;
-			params[n].u.value.b = operation->params[n].value.b;
+			params[n].a = operation->params[n].value.a;
+			params[n].b = operation->params[n].value.b;
 			break;
 		case TEEC_MEMREF_TEMP_INPUT:
 		case TEEC_MEMREF_TEMP_OUTPUT:
@@ -359,11 +367,10 @@
 			TEEC_SharedMemory *shm)
 {
 	if (param_type != TEEC_MEMREF_TEMP_INPUT) {
-		if (param->u.memref.size <= tmpref->size && tmpref->buffer)
-			memcpy(tmpref->buffer, shm->buffer,
-			       param->u.memref.size);
+		if (MEMREF_SIZE(param) <= tmpref->size && tmpref->buffer)
+			memcpy(tmpref->buffer, shm->buffer, MEMREF_SIZE(param));
 
-		tmpref->size = param->u.memref.size;
+		tmpref->size = MEMREF_SIZE(param);
 	}
 }
 
@@ -379,11 +386,11 @@
 		 * the shadow buffer into the real buffer now that we've
 		 * returned from secure world.
 		 */
-		if (shm->shadow_buffer && param->u.memref.size <= shm->size)
+		if (shm->shadow_buffer && MEMREF_SIZE(param) <= shm->size)
 			memcpy(shm->buffer, shm->shadow_buffer,
-			       param->u.memref.size);
+			       MEMREF_SIZE(param));
 
-		memref->size = param->u.memref.size;
+		memref->size = MEMREF_SIZE(param);
 	}
 }
 
@@ -399,12 +406,12 @@
 		 * the shadow buffer into the real buffer now that we've
 		 * returned from secure world.
 		 */
-		if (shm->shadow_buffer && param->u.memref.size <= memref->size)
+		if (shm->shadow_buffer && MEMREF_SIZE(param) <= memref->size)
 			memcpy((char *)shm->buffer + memref->offset,
 			       (char *)shm->shadow_buffer + memref->offset,
-			       param->u.memref.size);
+			       MEMREF_SIZE(param));
 
-		memref->size = param->u.memref.size;
+		memref->size = MEMREF_SIZE(param);
 	}
 }
 
@@ -426,8 +433,8 @@
 			break;
 		case TEEC_VALUE_OUTPUT:
 		case TEEC_VALUE_INOUT:
-			operation->params[n].value.a = params[n].u.value.a;
-			operation->params[n].value.b = params[n].u.value.b;
+			operation->params[n].value.a = params[n].a;
+			operation->params[n].value.b = params[n].b;
 			break;
 		case TEEC_MEMREF_TEMP_INPUT:
 		case TEEC_MEMREF_TEMP_OUTPUT:
diff --git a/tee-supplicant/src/prof.c b/tee-supplicant/src/prof.c
index 08fb278..3a3056e 100644
--- a/tee-supplicant/src/prof.c
+++ b/tee-supplicant/src/prof.c
@@ -64,9 +64,9 @@
 		TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	id = params[0].u.value.a;
+	id = params[0].a;
 
-	if (params[1].u.memref.size != sizeof(TEEC_UUID))
+	if (MEMREF_SIZE(params + 1) != sizeof(TEEC_UUID))
 		return TEEC_ERROR_BAD_PARAMETERS;
 
 	u = tee_supp_param_to_va(params + 1);
@@ -77,7 +77,7 @@
 	if (!buf)
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	bufsize = params[2].u.memref.size;
+	bufsize = MEMREF_SIZE(params + 2);
 
 	if (id < 0 || id > 100)
 		return TEEC_ERROR_BAD_PARAMETERS;
@@ -120,7 +120,7 @@
 			close(fd);
 			if (st < 0 || st != (int)bufsize)
 				break;
-			params[0].u.value.a = id;
+			params[0].a = id;
 			goto success;
 		}
 		if (errno != EEXIST)
diff --git a/tee-supplicant/src/tee_socket.c b/tee-supplicant/src/tee_socket.c
index 41d71b1..14819a0 100644
--- a/tee-supplicant/src/tee_socket.c
+++ b/tee-supplicant/src/tee_socket.c
@@ -262,13 +262,13 @@
 	    !chk_pt(params + 3, TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT))
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	instance_id = params[0].u.value.b;
-	port = params[1].u.value.a;
-	protocol = params[1].u.value.b;
-	ip_vers = params[1].u.value.c;
+	instance_id = params[0].b;
+	port = params[1].a;
+	protocol = params[1].b;
+	ip_vers = params[1].c;
 
 	server = tee_supp_param_to_va(params + 2);
-	if (!server || server[params[2].u.memref.size - 1] != '\0')
+	if (!server || server[MEMREF_SIZE(params + 2) - 1] != '\0')
 		return TEE_ISOCKET_ERROR_HOSTNAME;
 
 	res = sock_connect(ip_vers, protocol, server, port, &fd);
@@ -281,7 +281,7 @@
 		return TEEC_ERROR_OUT_OF_MEMORY;
 	}
 
-	params[3].u.value.a = handle;
+	params[3].a = handle;
 	return TEEC_SUCCESS;
 }
 
@@ -296,8 +296,8 @@
 	    !chk_pt(params + 0, TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT))
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	instance_id = params[0].u.value.b;
-	handle = params[0].u.value.c;
+	instance_id = params[0].b;
+	handle = params[0].c;
 	fd = sock_handle_to_fd(instance_id, handle);
 	if (fd < 0)
 		return TEEC_ERROR_BAD_PARAMETERS;
@@ -329,7 +329,7 @@
 	    !chk_pt(params + 0, TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT))
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	instance_id = params[0].u.value.b;
+	instance_id = params[0].b;
 	sock_lock();
 	si = sock_instance_find(instance_id);
 	if (si)
@@ -465,17 +465,17 @@
 	    !chk_pt(params + 2, TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT))
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	instance_id = params[0].u.value.b;
-	handle = params[0].u.value.c;
+	instance_id = params[0].b;
+	handle = params[0].c;
 	fd = sock_handle_to_fd(instance_id, handle);
 	if (fd < 0)
 		return TEEC_ERROR_BAD_PARAMETERS;
 
 	buf = tee_supp_param_to_va(params + 1);
-	bytes = params[1].u.memref.size;
-	res = write_with_timeout(fd, buf, &bytes, params[2].u.value.a);
+	bytes = MEMREF_SIZE(params + 1);
+	res = write_with_timeout(fd, buf, &bytes, params[2].a);
 	if (res == TEEC_SUCCESS)
-		params[2].u.value.b = bytes;
+		params[2].b = bytes;
 	return res;
 }
 
@@ -516,18 +516,18 @@
 	    !chk_pt(params + 2, TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT))
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	instance_id = params[0].u.value.b;
-	handle = params[0].u.value.c;
+	instance_id = params[0].b;
+	handle = params[0].c;
 	fd = sock_handle_to_fd(instance_id, handle);
 	if (fd < 0)
 		return TEEC_ERROR_BAD_PARAMETERS;
 
 	buf = tee_supp_param_to_va(params + 1);
 
-	bytes = params[1].u.memref.size;
-	res = read_with_timeout(fd, buf, &bytes, params[2].u.value.a);
+	bytes = MEMREF_SIZE(params + 1);
+	res = read_with_timeout(fd, buf, &bytes, params[2].a);
 	if (res == TEEC_SUCCESS)
-		params[1].u.memref.size = bytes;
+		MEMREF_SIZE(params + 1) = bytes;
 
 	return res;
 }
@@ -692,9 +692,9 @@
 	    !chk_pt(params + 2, TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT))
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	instance_id = params[0].u.value.b;
-	handle = params[0].u.value.c;
-	command = params[2].u.value.a;
+	instance_id = params[0].b;
+	handle = params[0].c;
+	command = params[2].a;
 	fd = sock_handle_to_fd(instance_id, handle);
 	if (fd < 0)
 		return TEEC_ERROR_BAD_PARAMETERS;
@@ -707,14 +707,14 @@
 
 	switch (socktype) {
 	case SOCK_STREAM:
-		sz = params[1].u.memref.size;
+		sz = MEMREF_SIZE(params + 1);
 		res = tee_socket_ioctl_tcp(fd, command, buf, &sz);
-		params[1].u.memref.size = sz;
+		MEMREF_SIZE(params + 1) = sz;
 		return res;
 	case SOCK_DGRAM:
-		sz = params[1].u.memref.size;
+		sz = MEMREF_SIZE(params + 1);
 		res = tee_socket_ioctl_udp(fd, command, buf, &sz);
-		params[1].u.memref.size = sz;
+		MEMREF_SIZE(params + 1) = sz;
 		return res;
 	default:
 		return TEEC_ERROR_BAD_PARAMETERS;
@@ -727,7 +727,7 @@
 	if (!num_params || !tee_supp_param_is_value(params))
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	switch (params->u.value.a) {
+	switch (params->a) {
 	case OPTEE_MRC_SOCKET_OPEN:
 		return tee_socket_open(num_params, params);
 	case OPTEE_MRC_SOCKET_CLOSE:
diff --git a/tee-supplicant/src/tee_supp_fs.c b/tee-supplicant/src/tee_supp_fs.c
index f652f86..5580ba9 100644
--- a/tee-supplicant/src/tee_supp_fs.c
+++ b/tee-supplicant/src/tee_supp_fs.c
@@ -177,7 +177,7 @@
 			return TEEC_ERROR_ITEM_NOT_FOUND;
 	}
 
-	params[2].u.value.a = fd;
+	params[2].a = fd;
 	return TEEC_SUCCESS;
 }
 
@@ -256,7 +256,7 @@
 	}
 
 out:
-	params[2].u.value.a = fd;
+	params[2].a = fd;
 	return TEEC_SUCCESS;
 }
 
@@ -270,7 +270,7 @@
 			TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT)
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	fd = params[0].u.value.b;
+	fd = params[0].b;
 	while (close(fd)) {
 		if (errno != EINTR)
 			return TEEC_ERROR_GENERIC;
@@ -295,13 +295,13 @@
 			TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT)
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	fd = params[0].u.value.b;
-	offs = params[0].u.value.c;
+	fd = params[0].b;
+	offs = params[0].c;
 
 	buf = tee_supp_param_to_va(params + 1);
 	if (!buf)
 		return TEEC_ERROR_BAD_PARAMETERS;
-	len = params[1].u.memref.size;
+	len = MEMREF_SIZE(params + 1);
 
 	s = 0;
 	r = -1;
@@ -319,7 +319,7 @@
 		s += r;
 	}
 
-	params[1].u.memref.size = s;
+	MEMREF_SIZE(params + 1) = s;
 	return TEEC_SUCCESS;
 }
 
@@ -339,13 +339,13 @@
 			TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	fd = params[0].u.value.b;
-	offs = params[0].u.value.c;
+	fd = params[0].b;
+	offs = params[0].c;
 
 	buf = tee_supp_param_to_va(params + 1);
 	if (!buf)
 		return TEEC_ERROR_BAD_PARAMETERS;
-	len = params[1].u.memref.size;
+	len = MEMREF_SIZE(params + 1);
 
 	while (len) {
 		r = pwrite(fd, buf, len, offs);
@@ -374,8 +374,8 @@
 			TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT)
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	fd = params[0].u.value.b;
-	len = params[0].u.value.c;
+	fd = params[0].b;
+	len = params[0].c;
 
 	while (ftruncate(fd, len)) {
 		if (errno != EINTR)
@@ -445,7 +445,7 @@
 			TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT)
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	overwrite = !!params[0].u.value.b;
+	overwrite = !!params[0].b;
 
 	old_fname = tee_supp_param_to_va(params + 1);
 	if (!old_fname)
@@ -537,7 +537,7 @@
 		return TEEC_ERROR_OUT_OF_MEMORY;
 	}
 
-	params[2].u.value.a = handle;
+	params[2].a = handle;
 	return TEEC_SUCCESS;
 }
 
@@ -551,7 +551,7 @@
 			TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT)
 		return TEEC_ERROR_BAD_PARAMETERS;
 
-	dir = handle_put(&dir_handle_db, params[0].u.value.b);
+	dir = handle_put(&dir_handle_db, params[0].b);
 	if (!dir)
 		return TEEC_ERROR_BAD_PARAMETERS;
 
@@ -580,9 +580,9 @@
 	buf = tee_supp_param_to_va(params + 1);
 	if (!buf)
 		return TEEC_ERROR_BAD_PARAMETERS;
-	len = params[1].u.memref.size;
+	len = MEMREF_SIZE(params + 1);
 
-	dir = handle_lookup(&dir_handle_db, params[0].u.value.b);
+	dir = handle_lookup(&dir_handle_db, params[0].b);
 	if (!dir)
 		return TEEC_ERROR_BAD_PARAMETERS;
 
@@ -595,7 +595,7 @@
 	}
 
 	fname_len = strlen(dirent->d_name) + 1;
-	params[1].u.memref.size = fname_len;
+	MEMREF_SIZE(params + 1) = fname_len;
 	if (fname_len > len)
 		return TEEC_ERROR_SHORT_BUFFER;
 
@@ -619,7 +619,7 @@
 		}
 	}
 
-	switch (params->u.value.a) {
+	switch (params->a) {
 	case OPTEE_MRF_OPEN:
 		return ree_fs_new_open(num_params, params);
 	case OPTEE_MRF_CREATE:
diff --git a/tee-supplicant/src/tee_supplicant.c b/tee-supplicant/src/tee_supplicant.c
index 187f4a6..94cf382 100644
--- a/tee-supplicant/src/tee_supplicant.c
+++ b/tee-supplicant/src/tee_supplicant.c
@@ -88,6 +88,12 @@
 	pthread_mutex_t mutex;
 };
 
+struct param_value {
+	uint64_t a;
+	uint64_t b;
+	uint64_t c;
+};
+
 static pthread_mutex_t shm_mutex = PTHREAD_MUTEX_INITIALIZER;
 static struct tee_shm *shm_head;
 
@@ -122,7 +128,7 @@
 }
 
 static int get_value(size_t num_params, struct tee_ioctl_param *params,
-		     const uint32_t idx, struct tee_ioctl_param_value **value)
+		     const uint32_t idx, struct param_value **value)
 {
 	if (idx >= num_params)
 		return -1;
@@ -131,7 +137,7 @@
 	case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT:
 	case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT:
 	case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
-		*value = &params[idx].u.value;
+		*value = (void *)&params[idx].a;
 		return 0;
 	default:
 		return -1;
@@ -198,6 +204,8 @@
 		     const uint32_t idx, TEEC_SharedMemory *shm)
 {
 	struct tee_shm *tshm = NULL;
+	size_t offs = 0;
+	size_t sz = 0;
 
 	if (idx >= num_params)
 		return -1;
@@ -213,7 +221,7 @@
 
 	memset(shm, 0, sizeof(*shm));
 
-	tshm = find_tshm(params[idx].u.memref.shm_id);
+	tshm = find_tshm(MEMREF_SHM_ID(params + idx));
 	if (!tshm) {
 		/*
 		 * It doesn't make sense to query required size of an
@@ -229,17 +237,19 @@
 		 */
 		return 0;
 	}
-	if ((params[idx].u.memref.size + params[idx].u.memref.shm_offs) <
-	    params[idx].u.memref.size)
+
+	sz = MEMREF_SIZE(params + idx);
+	offs = MEMREF_SHM_OFFS(params + idx);
+	if ((sz + offs) < sz)
 		return -1;
-	if ((params[idx].u.memref.size + params[idx].u.memref.shm_offs) >
-	    tshm->size)
+	if ((sz + offs) > tshm->size)
 		return -1;
 
 	shm->flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
-	shm->size = params[idx].u.memref.size - params[idx].u.memref.shm_offs;
-	shm->id = params[idx].u.memref.shm_id;
-	shm->buffer = (uint8_t *)tshm->p + params[idx].u.memref.shm_offs;
+	shm->size = sz - offs;
+	shm->id = MEMREF_SHM_ID(params + idx);
+	shm->buffer = (uint8_t *)tshm->p + offs;
+
 	return 0;
 }
 
@@ -255,7 +265,7 @@
 {
 	int ta_found = 0;
 	size_t size = 0;
-	struct tee_ioctl_param_value *val_cmd = NULL;
+	struct param_value *val_cmd = NULL;
 	TEEC_UUID uuid;
 	TEEC_SharedMemory shm_ta;
 
@@ -275,7 +285,7 @@
 		return TEEC_ERROR_ITEM_NOT_FOUND;
 	}
 
-	params[1].u.memref.size = size;
+	MEMREF_SIZE(params + 1) = size;
 
 	/*
 	 * If a buffer wasn't provided, just tell which size it should be.
@@ -356,7 +366,7 @@
 static uint32_t process_alloc(struct thread_arg *arg, size_t num_params,
 			      struct tee_ioctl_param *params)
 {
-	struct tee_ioctl_param_value *val = NULL;
+	struct param_value *val = NULL;
 	struct tee_shm *shm = NULL;
 
 	if (num_params != 1 || get_value(num_params, params, 0, &val))
@@ -379,7 +389,7 @@
 
 static uint32_t process_free(size_t num_params, struct tee_ioctl_param *params)
 {
-	struct tee_ioctl_param_value *val = NULL;
+	struct param_value *val = NULL;
 	struct tee_shm *shm = NULL;
 	int id = 0;
 
@@ -743,19 +753,18 @@
 	if (!tee_supp_param_is_memref(param))
 		return NULL;
 
-	end_offs = param->u.memref.size + param->u.memref.shm_offs;
-	if (end_offs < param->u.memref.size ||
-	    end_offs < param->u.memref.shm_offs)
+	end_offs = MEMREF_SIZE(param) + MEMREF_SHM_OFFS(param);
+	if (end_offs < MEMREF_SIZE(param) || end_offs < MEMREF_SHM_OFFS(param))
 		return NULL;
 
-	tshm = find_tshm(param->u.memref.shm_id);
+	tshm = find_tshm(MEMREF_SHM_ID(param));
 	if (!tshm)
 		return NULL;
 
 	if (end_offs > tshm->size)
 		return NULL;
 
-	return (uint8_t *)tshm->p + param->u.memref.shm_offs;
+	return (uint8_t *)tshm->p + MEMREF_SHM_OFFS(param);
 }
 
 void tee_supp_mutex_lock(pthread_mutex_t *mu)
diff --git a/tee-supplicant/src/tee_supplicant.h b/tee-supplicant/src/tee_supplicant.h
index 7e7c9cc..11f2b80 100644
--- a/tee-supplicant/src/tee_supplicant.h
+++ b/tee-supplicant/src/tee_supplicant.h
@@ -31,6 +31,11 @@
 #include <stdbool.h>
 #include <pthread.h>
 
+/* Helpers to access memref parts of a struct tee_ioctl_param */
+#define MEMREF_SHM_ID(p)	((p)->c)
+#define MEMREF_SHM_OFFS(p)	((p)->a)
+#define MEMREF_SIZE(p)		((p)->b)
+
 struct tee_ioctl_param;
 
 bool tee_supp_param_is_memref(struct tee_ioctl_param *param);