Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/crypto/ccp/tee-dev.c
26282 views
1
// SPDX-License-Identifier: MIT
2
/*
3
* AMD Trusted Execution Environment (TEE) interface
4
*
5
* Author: Rijo Thomas <[email protected]>
6
* Author: Devaraj Rangasamy <[email protected]>
7
*
8
* Copyright (C) 2019,2021 Advanced Micro Devices, Inc.
9
*/
10
11
#include <linux/bitfield.h>
12
#include <linux/types.h>
13
#include <linux/mutex.h>
14
#include <linux/delay.h>
15
#include <linux/slab.h>
16
#include <linux/gfp.h>
17
#include <linux/psp.h>
18
#include <linux/psp-tee.h>
19
20
#include "psp-dev.h"
21
#include "tee-dev.h"
22
23
static bool psp_dead;
24
25
static int tee_alloc_ring(struct psp_tee_device *tee, int ring_size)
26
{
27
struct ring_buf_manager *rb_mgr = &tee->rb_mgr;
28
void *start_addr;
29
30
if (!ring_size)
31
return -EINVAL;
32
33
/* We need actual physical address instead of DMA address, since
34
* Trusted OS running on AMD Secure Processor will map this region
35
*/
36
start_addr = (void *)__get_free_pages(GFP_KERNEL, get_order(ring_size));
37
if (!start_addr)
38
return -ENOMEM;
39
40
memset(start_addr, 0x0, ring_size);
41
rb_mgr->ring_start = start_addr;
42
rb_mgr->ring_size = ring_size;
43
rb_mgr->ring_pa = __psp_pa(start_addr);
44
mutex_init(&rb_mgr->mutex);
45
46
return 0;
47
}
48
49
static void tee_free_ring(struct psp_tee_device *tee)
50
{
51
struct ring_buf_manager *rb_mgr = &tee->rb_mgr;
52
53
if (!rb_mgr->ring_start)
54
return;
55
56
free_pages((unsigned long)rb_mgr->ring_start,
57
get_order(rb_mgr->ring_size));
58
59
rb_mgr->ring_start = NULL;
60
rb_mgr->ring_size = 0;
61
rb_mgr->ring_pa = 0;
62
mutex_destroy(&rb_mgr->mutex);
63
}
64
65
static
66
struct tee_init_ring_cmd *tee_alloc_cmd_buffer(struct psp_tee_device *tee)
67
{
68
struct tee_init_ring_cmd *cmd;
69
70
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
71
if (!cmd)
72
return NULL;
73
74
cmd->hi_addr = upper_32_bits(tee->rb_mgr.ring_pa);
75
cmd->low_addr = lower_32_bits(tee->rb_mgr.ring_pa);
76
cmd->size = tee->rb_mgr.ring_size;
77
78
dev_dbg(tee->dev, "tee: ring address: high = 0x%x low = 0x%x size = %u\n",
79
cmd->hi_addr, cmd->low_addr, cmd->size);
80
81
return cmd;
82
}
83
84
static inline void tee_free_cmd_buffer(struct tee_init_ring_cmd *cmd)
85
{
86
kfree(cmd);
87
}
88
89
static int tee_init_ring(struct psp_tee_device *tee)
90
{
91
int ring_size = MAX_RING_BUFFER_ENTRIES * sizeof(struct tee_ring_cmd);
92
struct tee_init_ring_cmd *cmd;
93
unsigned int reg;
94
int ret;
95
96
BUILD_BUG_ON(sizeof(struct tee_ring_cmd) != 1024);
97
98
ret = tee_alloc_ring(tee, ring_size);
99
if (ret) {
100
dev_err(tee->dev, "tee: ring allocation failed %d\n", ret);
101
return ret;
102
}
103
104
tee->rb_mgr.wptr = 0;
105
106
cmd = tee_alloc_cmd_buffer(tee);
107
if (!cmd) {
108
tee_free_ring(tee);
109
return -ENOMEM;
110
}
111
112
/* Send command buffer details to Trusted OS by writing to
113
* CPU-PSP message registers
114
*/
115
ret = psp_mailbox_command(tee->psp, PSP_CMD_TEE_RING_INIT, cmd,
116
TEE_DEFAULT_CMD_TIMEOUT, &reg);
117
if (ret) {
118
dev_err(tee->dev, "tee: ring init command timed out, disabling TEE support\n");
119
tee_free_ring(tee);
120
psp_dead = true;
121
goto free_buf;
122
}
123
124
if (FIELD_GET(PSP_CMDRESP_STS, reg)) {
125
dev_err(tee->dev, "tee: ring init command failed (%#010lx)\n",
126
FIELD_GET(PSP_CMDRESP_STS, reg));
127
tee_free_ring(tee);
128
ret = -EIO;
129
}
130
131
free_buf:
132
tee_free_cmd_buffer(cmd);
133
134
return ret;
135
}
136
137
static void tee_destroy_ring(struct psp_tee_device *tee)
138
{
139
unsigned int reg;
140
int ret;
141
142
if (!tee->rb_mgr.ring_start)
143
return;
144
145
if (psp_dead)
146
goto free_ring;
147
148
ret = psp_mailbox_command(tee->psp, PSP_CMD_TEE_RING_DESTROY, NULL,
149
TEE_DEFAULT_CMD_TIMEOUT, &reg);
150
if (ret) {
151
dev_err(tee->dev, "tee: ring destroy command timed out, disabling TEE support\n");
152
psp_dead = true;
153
} else if (FIELD_GET(PSP_CMDRESP_STS, reg)) {
154
dev_err(tee->dev, "tee: ring destroy command failed (%#010lx)\n",
155
FIELD_GET(PSP_CMDRESP_STS, reg));
156
}
157
158
free_ring:
159
tee_free_ring(tee);
160
}
161
162
int tee_dev_init(struct psp_device *psp)
163
{
164
struct device *dev = psp->dev;
165
struct psp_tee_device *tee;
166
int ret;
167
168
ret = -ENOMEM;
169
tee = devm_kzalloc(dev, sizeof(*tee), GFP_KERNEL);
170
if (!tee)
171
goto e_err;
172
173
psp->tee_data = tee;
174
175
tee->dev = dev;
176
tee->psp = psp;
177
178
tee->io_regs = psp->io_regs;
179
180
tee->vdata = (struct tee_vdata *)psp->vdata->tee;
181
if (!tee->vdata) {
182
ret = -ENODEV;
183
dev_err(dev, "tee: missing driver data\n");
184
goto e_err;
185
}
186
187
ret = tee_init_ring(tee);
188
if (ret) {
189
dev_err(dev, "tee: failed to init ring buffer\n");
190
goto e_err;
191
}
192
193
dev_notice(dev, "tee enabled\n");
194
195
return 0;
196
197
e_err:
198
psp->tee_data = NULL;
199
200
dev_notice(dev, "tee initialization failed\n");
201
202
return ret;
203
}
204
205
void tee_dev_destroy(struct psp_device *psp)
206
{
207
struct psp_tee_device *tee = psp->tee_data;
208
209
if (!tee)
210
return;
211
212
tee_destroy_ring(tee);
213
}
214
215
static int tee_submit_cmd(struct psp_tee_device *tee, enum tee_cmd_id cmd_id,
216
void *buf, size_t len, struct tee_ring_cmd **resp)
217
{
218
struct tee_ring_cmd *cmd;
219
int nloop = 1000, ret = 0;
220
u32 rptr;
221
222
*resp = NULL;
223
224
mutex_lock(&tee->rb_mgr.mutex);
225
226
/* Loop until empty entry found in ring buffer */
227
do {
228
/* Get pointer to ring buffer command entry */
229
cmd = (struct tee_ring_cmd *)
230
(tee->rb_mgr.ring_start + tee->rb_mgr.wptr);
231
232
rptr = ioread32(tee->io_regs + tee->vdata->ring_rptr_reg);
233
234
/* Check if ring buffer is full or command entry is waiting
235
* for response from TEE
236
*/
237
if (!(tee->rb_mgr.wptr + sizeof(struct tee_ring_cmd) == rptr ||
238
cmd->flag == CMD_WAITING_FOR_RESPONSE))
239
break;
240
241
dev_dbg(tee->dev, "tee: ring buffer full. rptr = %u wptr = %u\n",
242
rptr, tee->rb_mgr.wptr);
243
244
/* Wait if ring buffer is full or TEE is processing data */
245
mutex_unlock(&tee->rb_mgr.mutex);
246
schedule_timeout_interruptible(msecs_to_jiffies(10));
247
mutex_lock(&tee->rb_mgr.mutex);
248
249
} while (--nloop);
250
251
if (!nloop &&
252
(tee->rb_mgr.wptr + sizeof(struct tee_ring_cmd) == rptr ||
253
cmd->flag == CMD_WAITING_FOR_RESPONSE)) {
254
dev_err(tee->dev, "tee: ring buffer full. rptr = %u wptr = %u response flag %u\n",
255
rptr, tee->rb_mgr.wptr, cmd->flag);
256
ret = -EBUSY;
257
goto unlock;
258
}
259
260
/* Do not submit command if PSP got disabled while processing any
261
* command in another thread
262
*/
263
if (psp_dead) {
264
ret = -EBUSY;
265
goto unlock;
266
}
267
268
/* Write command data into ring buffer */
269
cmd->cmd_id = cmd_id;
270
cmd->cmd_state = TEE_CMD_STATE_INIT;
271
memset(&cmd->buf[0], 0, sizeof(cmd->buf));
272
memcpy(&cmd->buf[0], buf, len);
273
274
/* Indicate driver is waiting for response */
275
cmd->flag = CMD_WAITING_FOR_RESPONSE;
276
277
/* Update local copy of write pointer */
278
tee->rb_mgr.wptr += sizeof(struct tee_ring_cmd);
279
if (tee->rb_mgr.wptr >= tee->rb_mgr.ring_size)
280
tee->rb_mgr.wptr = 0;
281
282
/* Trigger interrupt to Trusted OS */
283
iowrite32(tee->rb_mgr.wptr, tee->io_regs + tee->vdata->ring_wptr_reg);
284
285
/* The response is provided by Trusted OS in same
286
* location as submitted data entry within ring buffer.
287
*/
288
*resp = cmd;
289
290
unlock:
291
mutex_unlock(&tee->rb_mgr.mutex);
292
293
return ret;
294
}
295
296
static int tee_wait_cmd_completion(struct psp_tee_device *tee,
297
struct tee_ring_cmd *resp,
298
unsigned int timeout)
299
{
300
/* ~1ms sleep per loop => nloop = timeout * 1000 */
301
int nloop = timeout * 1000;
302
303
while (--nloop) {
304
if (resp->cmd_state == TEE_CMD_STATE_COMPLETED)
305
return 0;
306
307
usleep_range(1000, 1100);
308
}
309
310
dev_err(tee->dev, "tee: command 0x%x timed out, disabling PSP\n",
311
resp->cmd_id);
312
313
psp_dead = true;
314
315
return -ETIMEDOUT;
316
}
317
318
int psp_tee_process_cmd(enum tee_cmd_id cmd_id, void *buf, size_t len,
319
u32 *status)
320
{
321
struct psp_device *psp = psp_get_master_device();
322
struct psp_tee_device *tee;
323
struct tee_ring_cmd *resp;
324
int ret;
325
326
if (!buf || !status || !len || len > sizeof(resp->buf))
327
return -EINVAL;
328
329
*status = 0;
330
331
if (!psp || !psp->tee_data)
332
return -ENODEV;
333
334
if (psp_dead)
335
return -EBUSY;
336
337
tee = psp->tee_data;
338
339
ret = tee_submit_cmd(tee, cmd_id, buf, len, &resp);
340
if (ret)
341
return ret;
342
343
ret = tee_wait_cmd_completion(tee, resp, TEE_DEFAULT_RING_TIMEOUT);
344
if (ret) {
345
resp->flag = CMD_RESPONSE_TIMEDOUT;
346
return ret;
347
}
348
349
memcpy(buf, &resp->buf[0], len);
350
*status = resp->status;
351
352
resp->flag = CMD_RESPONSE_COPIED;
353
354
return 0;
355
}
356
EXPORT_SYMBOL(psp_tee_process_cmd);
357
358
int psp_check_tee_status(void)
359
{
360
struct psp_device *psp = psp_get_master_device();
361
362
if (!psp || !psp->tee_data)
363
return -ENODEV;
364
365
return 0;
366
}
367
EXPORT_SYMBOL(psp_check_tee_status);
368
369