Skip to content

Commit 757cc3e

Browse files
Rijo Thomasherbertx
authored andcommitted
tee: add AMD-TEE driver
Adds AMD-TEE driver. * targets AMD APUs which has AMD Secure Processor with software-based Trusted Execution Environment (TEE) support * registers with TEE subsystem * defines tee_driver_ops function callbacks * kernel allocated memory is used as shared memory between normal world and secure world. * acts as REE (Rich Execution Environment) communication agent, which uses the services of AMD Secure Processor driver to submit commands for processing in TEE environment Cc: Ard Biesheuvel <[email protected]> Cc: Tom Lendacky <[email protected]> Acked-by: Jens Wiklander <[email protected]> Co-developed-by: Devaraj Rangasamy <[email protected]> Signed-off-by: Devaraj Rangasamy <[email protected]> Signed-off-by: Rijo Thomas <[email protected]> Reviewed-by: Gary R Hook <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 1a74fa3 commit 757cc3e

File tree

10 files changed

+1334
-1
lines changed

10 files changed

+1334
-1
lines changed

drivers/tee/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ if TEE
1414
menu "TEE drivers"
1515

1616
source "drivers/tee/optee/Kconfig"
17-
17+
source "drivers/tee/amdtee/Kconfig"
1818
endmenu
1919

2020
endif

drivers/tee/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ tee-objs += tee_core.o
44
tee-objs += tee_shm.o
55
tee-objs += tee_shm_pool.o
66
obj-$(CONFIG_OPTEE) += optee/
7+
obj-$(CONFIG_AMDTEE) += amdtee/

drivers/tee/amdtee/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: MIT
2+
# AMD-TEE Trusted Execution Environment Configuration
3+
config AMDTEE
4+
tristate "AMD-TEE"
5+
default m
6+
depends on CRYPTO_DEV_SP_PSP
7+
help
8+
This implements AMD's Trusted Execution Environment (TEE) driver.

drivers/tee/amdtee/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SPDX-License-Identifier: MIT
2+
obj-$(CONFIG_AMDTEE) += amdtee.o
3+
amdtee-objs += core.o
4+
amdtee-objs += call.o
5+
amdtee-objs += shm_pool.o

drivers/tee/amdtee/amdtee_if.h

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/* SPDX-License-Identifier: MIT */
2+
3+
/*
4+
* Copyright 2019 Advanced Micro Devices, Inc.
5+
*/
6+
7+
/*
8+
* This file has definitions related to Host and AMD-TEE Trusted OS interface.
9+
* These definitions must match the definitions on the TEE side.
10+
*/
11+
12+
#ifndef AMDTEE_IF_H
13+
#define AMDTEE_IF_H
14+
15+
#include <linux/types.h>
16+
17+
/*****************************************************************************
18+
** TEE Param
19+
******************************************************************************/
20+
#define TEE_MAX_PARAMS 4
21+
22+
/**
23+
* struct memref - memory reference structure
24+
* @buf_id: buffer ID of the buffer mapped by TEE_CMD_ID_MAP_SHARED_MEM
25+
* @offset: offset in bytes from beginning of the buffer
26+
* @size: data size in bytes
27+
*/
28+
struct memref {
29+
u32 buf_id;
30+
u32 offset;
31+
u32 size;
32+
};
33+
34+
struct value {
35+
u32 a;
36+
u32 b;
37+
};
38+
39+
/*
40+
* Parameters passed to open_session or invoke_command
41+
*/
42+
union tee_op_param {
43+
struct memref mref;
44+
struct value val;
45+
};
46+
47+
struct tee_operation {
48+
u32 param_types;
49+
union tee_op_param params[TEE_MAX_PARAMS];
50+
};
51+
52+
/* Must be same as in GP TEE specification */
53+
#define TEE_OP_PARAM_TYPE_NONE 0
54+
#define TEE_OP_PARAM_TYPE_VALUE_INPUT 1
55+
#define TEE_OP_PARAM_TYPE_VALUE_OUTPUT 2
56+
#define TEE_OP_PARAM_TYPE_VALUE_INOUT 3
57+
#define TEE_OP_PARAM_TYPE_INVALID 4
58+
#define TEE_OP_PARAM_TYPE_MEMREF_INPUT 5
59+
#define TEE_OP_PARAM_TYPE_MEMREF_OUTPUT 6
60+
#define TEE_OP_PARAM_TYPE_MEMREF_INOUT 7
61+
62+
#define TEE_PARAM_TYPE_GET(t, i) (((t) >> ((i) * 4)) & 0xF)
63+
#define TEE_PARAM_TYPES(t0, t1, t2, t3) \
64+
((t0) | ((t1) << 4) | ((t2) << 8) | ((t3) << 12))
65+
66+
/*****************************************************************************
67+
** TEE Commands
68+
*****************************************************************************/
69+
70+
/*
71+
* The shared memory between rich world and secure world may be physically
72+
* non-contiguous. Below structures are meant to describe a shared memory region
73+
* via scatter/gather (sg) list
74+
*/
75+
76+
/**
77+
* struct tee_sg_desc - sg descriptor for a physically contiguous buffer
78+
* @low_addr: [in] bits[31:0] of buffer's physical address. Must be 4KB aligned
79+
* @hi_addr: [in] bits[63:32] of the buffer's physical address
80+
* @size: [in] size in bytes (must be multiple of 4KB)
81+
*/
82+
struct tee_sg_desc {
83+
u32 low_addr;
84+
u32 hi_addr;
85+
u32 size;
86+
};
87+
88+
/**
89+
* struct tee_sg_list - structure describing a scatter/gather list
90+
* @count: [in] number of sg descriptors
91+
* @size: [in] total size of all buffers in the list. Must be multiple of 4KB
92+
* @buf: [in] list of sg buffer descriptors
93+
*/
94+
#define TEE_MAX_SG_DESC 64
95+
struct tee_sg_list {
96+
u32 count;
97+
u32 size;
98+
struct tee_sg_desc buf[TEE_MAX_SG_DESC];
99+
};
100+
101+
/**
102+
* struct tee_cmd_map_shared_mem - command to map shared memory
103+
* @buf_id: [out] return buffer ID value
104+
* @sg_list: [in] list describing memory to be mapped
105+
*/
106+
struct tee_cmd_map_shared_mem {
107+
u32 buf_id;
108+
struct tee_sg_list sg_list;
109+
};
110+
111+
/**
112+
* struct tee_cmd_unmap_shared_mem - command to unmap shared memory
113+
* @buf_id: [in] buffer ID of memory to be unmapped
114+
*/
115+
struct tee_cmd_unmap_shared_mem {
116+
u32 buf_id;
117+
};
118+
119+
/**
120+
* struct tee_cmd_load_ta - load Trusted Application (TA) binary into TEE
121+
* @low_addr: [in] bits [31:0] of the physical address of the TA binary
122+
* @hi_addr: [in] bits [63:32] of the physical address of the TA binary
123+
* @size: [in] size of TA binary in bytes
124+
* @ta_handle: [out] return handle of the loaded TA
125+
*/
126+
struct tee_cmd_load_ta {
127+
u32 low_addr;
128+
u32 hi_addr;
129+
u32 size;
130+
u32 ta_handle;
131+
};
132+
133+
/**
134+
* struct tee_cmd_unload_ta - command to unload TA binary from TEE environment
135+
* @ta_handle: [in] handle of the loaded TA to be unloaded
136+
*/
137+
struct tee_cmd_unload_ta {
138+
u32 ta_handle;
139+
};
140+
141+
/**
142+
* struct tee_cmd_open_session - command to call TA_OpenSessionEntryPoint in TA
143+
* @ta_handle: [in] handle of the loaded TA
144+
* @session_info: [out] pointer to TA allocated session data
145+
* @op: [in/out] operation parameters
146+
* @return_origin: [out] origin of return code after TEE processing
147+
*/
148+
struct tee_cmd_open_session {
149+
u32 ta_handle;
150+
u32 session_info;
151+
struct tee_operation op;
152+
u32 return_origin;
153+
};
154+
155+
/**
156+
* struct tee_cmd_close_session - command to call TA_CloseSessionEntryPoint()
157+
* in TA
158+
* @ta_handle: [in] handle of the loaded TA
159+
* @session_info: [in] pointer to TA allocated session data
160+
*/
161+
struct tee_cmd_close_session {
162+
u32 ta_handle;
163+
u32 session_info;
164+
};
165+
166+
/**
167+
* struct tee_cmd_invoke_cmd - command to call TA_InvokeCommandEntryPoint() in
168+
* TA
169+
* @ta_handle: [in] handle of the loaded TA
170+
* @cmd_id: [in] TA command ID
171+
* @session_info: [in] pointer to TA allocated session data
172+
* @op: [in/out] operation parameters
173+
* @return_origin: [out] origin of return code after TEE processing
174+
*/
175+
struct tee_cmd_invoke_cmd {
176+
u32 ta_handle;
177+
u32 cmd_id;
178+
u32 session_info;
179+
struct tee_operation op;
180+
u32 return_origin;
181+
};
182+
183+
#endif /*AMDTEE_IF_H*/
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/* SPDX-License-Identifier: MIT */
2+
3+
/*
4+
* Copyright 2019 Advanced Micro Devices, Inc.
5+
*/
6+
7+
#ifndef AMDTEE_PRIVATE_H
8+
#define AMDTEE_PRIVATE_H
9+
10+
#include <linux/mutex.h>
11+
#include <linux/spinlock.h>
12+
#include <linux/tee_drv.h>
13+
#include <linux/kref.h>
14+
#include <linux/types.h>
15+
#include "amdtee_if.h"
16+
17+
#define DRIVER_NAME "amdtee"
18+
#define DRIVER_AUTHOR "AMD-TEE Linux driver team"
19+
20+
/* Some GlobalPlatform error codes used in this driver */
21+
#define TEEC_SUCCESS 0x00000000
22+
#define TEEC_ERROR_GENERIC 0xFFFF0000
23+
#define TEEC_ERROR_BAD_PARAMETERS 0xFFFF0006
24+
#define TEEC_ERROR_COMMUNICATION 0xFFFF000E
25+
26+
#define TEEC_ORIGIN_COMMS 0x00000002
27+
28+
/* Maximum number of sessions which can be opened with a Trusted Application */
29+
#define TEE_NUM_SESSIONS 32
30+
31+
#define TA_LOAD_PATH "/amdtee"
32+
#define TA_PATH_MAX 60
33+
34+
/**
35+
* struct amdtee - main service struct
36+
* @teedev: client device
37+
* @pool: shared memory pool
38+
*/
39+
struct amdtee {
40+
struct tee_device *teedev;
41+
struct tee_shm_pool *pool;
42+
};
43+
44+
/**
45+
* struct amdtee_session - Trusted Application (TA) session related information.
46+
* @ta_handle: handle to Trusted Application (TA) loaded in TEE environment
47+
* @refcount: counter to keep track of sessions opened for the TA instance
48+
* @session_info: an array pointing to TA allocated session data.
49+
* @sess_mask: session usage bit-mask. If a particular bit is set, then the
50+
* corresponding @session_info entry is in use or valid.
51+
*
52+
* Session structure is updated on open_session and this information is used for
53+
* subsequent operations with the Trusted Application.
54+
*/
55+
struct amdtee_session {
56+
struct list_head list_node;
57+
u32 ta_handle;
58+
struct kref refcount;
59+
u32 session_info[TEE_NUM_SESSIONS];
60+
DECLARE_BITMAP(sess_mask, TEE_NUM_SESSIONS);
61+
spinlock_t lock; /* synchronizes access to @sess_mask */
62+
};
63+
64+
/**
65+
* struct amdtee_context_data - AMD-TEE driver context data
66+
* @sess_list: Keeps track of sessions opened in current TEE context
67+
*/
68+
struct amdtee_context_data {
69+
struct list_head sess_list;
70+
};
71+
72+
struct amdtee_driver_data {
73+
struct amdtee *amdtee;
74+
};
75+
76+
struct shmem_desc {
77+
void *kaddr;
78+
u64 size;
79+
};
80+
81+
/**
82+
* struct amdtee_shm_data - Shared memory data
83+
* @kaddr: Kernel virtual address of shared memory
84+
* @buf_id: Buffer id of memory mapped by TEE_CMD_ID_MAP_SHARED_MEM
85+
*/
86+
struct amdtee_shm_data {
87+
struct list_head shm_node;
88+
void *kaddr;
89+
u32 buf_id;
90+
};
91+
92+
struct amdtee_shm_context {
93+
struct list_head shmdata_list;
94+
};
95+
96+
#define LOWER_TWO_BYTE_MASK 0x0000FFFF
97+
98+
/**
99+
* set_session_id() - Sets the session identifier.
100+
* @ta_handle: [in] handle of the loaded Trusted Application (TA)
101+
* @session_index: [in] Session index. Range: 0 to (TEE_NUM_SESSIONS - 1).
102+
* @session: [out] Pointer to session id
103+
*
104+
* Lower two bytes of the session identifier represents the TA handle and the
105+
* upper two bytes is session index.
106+
*/
107+
static inline void set_session_id(u32 ta_handle, u32 session_index,
108+
u32 *session)
109+
{
110+
*session = (session_index << 16) | (LOWER_TWO_BYTE_MASK & ta_handle);
111+
}
112+
113+
static inline u32 get_ta_handle(u32 session)
114+
{
115+
return session & LOWER_TWO_BYTE_MASK;
116+
}
117+
118+
static inline u32 get_session_index(u32 session)
119+
{
120+
return (session >> 16) & LOWER_TWO_BYTE_MASK;
121+
}
122+
123+
int amdtee_open_session(struct tee_context *ctx,
124+
struct tee_ioctl_open_session_arg *arg,
125+
struct tee_param *param);
126+
127+
int amdtee_close_session(struct tee_context *ctx, u32 session);
128+
129+
int amdtee_invoke_func(struct tee_context *ctx,
130+
struct tee_ioctl_invoke_arg *arg,
131+
struct tee_param *param);
132+
133+
int amdtee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session);
134+
135+
int amdtee_map_shmem(struct tee_shm *shm);
136+
137+
void amdtee_unmap_shmem(struct tee_shm *shm);
138+
139+
int handle_load_ta(void *data, u32 size,
140+
struct tee_ioctl_open_session_arg *arg);
141+
142+
int handle_unload_ta(u32 ta_handle);
143+
144+
int handle_open_session(struct tee_ioctl_open_session_arg *arg, u32 *info,
145+
struct tee_param *p);
146+
147+
int handle_close_session(u32 ta_handle, u32 info);
148+
149+
int handle_map_shmem(u32 count, struct shmem_desc *start, u32 *buf_id);
150+
151+
void handle_unmap_shmem(u32 buf_id);
152+
153+
int handle_invoke_cmd(struct tee_ioctl_invoke_arg *arg, u32 sinfo,
154+
struct tee_param *p);
155+
156+
struct tee_shm_pool *amdtee_config_shm(void);
157+
158+
u32 get_buffer_id(struct tee_shm *shm);
159+
#endif /*AMDTEE_PRIVATE_H*/

0 commit comments

Comments
 (0)