File Index
Files and directories
Sign in
FILE

tee-dev.c

File preview with syntax highlighting.

linux-6.19.14/drivers/crypto/ccp/tee-dev.c C
  1// SPDX-License-Identifier: MIT
  2/*
  3 * AMD Trusted Execution Environment (TEE) interface
  4 *
  5 * Author: Rijo Thomas <Rijo-john.Thomas@amd.com>
  6 * Author: Devaraj Rangasamy <Devaraj.Rangasamy@amd.com>
  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
 23static bool psp_dead;
 24
 25static 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
 49static 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
 65static
 66struct 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
 84static inline void tee_free_cmd_buffer(struct tee_init_ring_cmd *cmd)
 85{
 86	kfree(cmd);
 87}
 88
 89static bool tee_send_destroy_cmd(struct psp_tee_device *tee)
 90{
 91	unsigned int reg;
 92	int ret;
 93
 94	ret = psp_mailbox_command(tee->psp, PSP_CMD_TEE_RING_DESTROY, NULL,
 95				  TEE_DEFAULT_CMD_TIMEOUT, &reg);
 96	if (ret) {
 97		dev_err(tee->dev, "tee: ring destroy command timed out, disabling TEE support\n");
 98		psp_dead = true;
 99		return false;
100	}
101
102	if (FIELD_GET(PSP_CMDRESP_STS, reg)) {
103		dev_err(tee->dev, "tee: ring destroy command failed (%#010lx)\n",
104			FIELD_GET(PSP_CMDRESP_STS, reg));
105		psp_dead = true;
106		return false;
107	}
108
109	return true;
110}
111
112static int tee_init_ring(struct psp_tee_device *tee)
113{
114	int ring_size = MAX_RING_BUFFER_ENTRIES * sizeof(struct tee_ring_cmd);
115	struct tee_init_ring_cmd *cmd;
116	bool retry = false;
117	unsigned int reg;
118	int ret;
119
120	BUILD_BUG_ON(sizeof(struct tee_ring_cmd) != 1024);
121
122	ret = tee_alloc_ring(tee, ring_size);
123	if (ret) {
124		dev_err(tee->dev, "tee: ring allocation failed %d\n", ret);
125		return ret;
126	}
127
128	tee->rb_mgr.wptr = 0;
129
130	cmd = tee_alloc_cmd_buffer(tee);
131	if (!cmd) {
132		tee_free_ring(tee);
133		return -ENOMEM;
134	}
135
136	/* Send command buffer details to Trusted OS by writing to
137	 * CPU-PSP message registers
138	 */
139retry_init:
140	ret = psp_mailbox_command(tee->psp, PSP_CMD_TEE_RING_INIT, cmd,
141				  TEE_DEFAULT_CMD_TIMEOUT, &reg);
142	if (ret) {
143		dev_err(tee->dev, "tee: ring init command timed out, disabling TEE support\n");
144		tee_free_ring(tee);
145		psp_dead = true;
146		goto free_buf;
147	}
148
149	if (FIELD_GET(PSP_CMDRESP_STS, reg)) {
150		/*
151		 * During the hibernate resume sequence driver may have gotten loaded
152		 * but the ring not properly destroyed. If the ring doesn't work, try
153		 * to destroy and re-init once.
154		 */
155		if (!retry && FIELD_GET(PSP_CMDRESP_STS, reg) == PSP_TEE_STS_RING_BUSY) {
156			dev_info(tee->dev, "tee: ring init command failed with busy status, retrying\n");
157			if (tee_send_destroy_cmd(tee)) {
158				retry = true;
159				goto retry_init;
160			}
161		}
162		dev_err(tee->dev, "tee: ring init command failed (%#010lx)\n",
163			FIELD_GET(PSP_CMDRESP_STS, reg));
164		tee_free_ring(tee);
165		psp_dead = true;
166		ret = -EIO;
167	}
168
169free_buf:
170	tee_free_cmd_buffer(cmd);
171
172	return ret;
173}
174
175static void tee_destroy_ring(struct psp_tee_device *tee)
176{
177	if (!tee->rb_mgr.ring_start)
178		return;
179
180	if (psp_dead)
181		goto free_ring;
182
183	tee_send_destroy_cmd(tee);
184
185free_ring:
186	tee_free_ring(tee);
187}
188
189int tee_dev_init(struct psp_device *psp)
190{
191	struct device *dev = psp->dev;
192	struct psp_tee_device *tee;
193	int ret;
194
195	ret = -ENOMEM;
196	tee = devm_kzalloc(dev, sizeof(*tee), GFP_KERNEL);
197	if (!tee)
198		goto e_err;
199
200	psp->tee_data = tee;
201
202	tee->dev = dev;
203	tee->psp = psp;
204
205	tee->io_regs = psp->io_regs;
206
207	tee->vdata = (struct tee_vdata *)psp->vdata->tee;
208	if (!tee->vdata) {
209		ret = -ENODEV;
210		dev_err(dev, "tee: missing driver data\n");
211		goto e_err;
212	}
213
214	ret = tee_init_ring(tee);
215	if (ret) {
216		dev_err(dev, "tee: failed to init ring buffer\n");
217		goto e_err;
218	}
219
220	dev_notice(dev, "tee enabled\n");
221
222	return 0;
223
224e_err:
225	psp->tee_data = NULL;
226
227	dev_notice(dev, "tee initialization failed\n");
228
229	return ret;
230}
231
232void tee_dev_destroy(struct psp_device *psp)
233{
234	struct psp_tee_device *tee = psp->tee_data;
235
236	if (!tee)
237		return;
238
239	tee_destroy_ring(tee);
240}
241
242static int tee_submit_cmd(struct psp_tee_device *tee, enum tee_cmd_id cmd_id,
243			  void *buf, size_t len, struct tee_ring_cmd **resp)
244{
245	struct tee_ring_cmd *cmd;
246	int nloop = 1000, ret = 0;
247	u32 rptr;
248
249	*resp = NULL;
250
251	mutex_lock(&tee->rb_mgr.mutex);
252
253	/* Loop until empty entry found in ring buffer */
254	do {
255		/* Get pointer to ring buffer command entry */
256		cmd = (struct tee_ring_cmd *)
257			(tee->rb_mgr.ring_start + tee->rb_mgr.wptr);
258
259		rptr = ioread32(tee->io_regs + tee->vdata->ring_rptr_reg);
260
261		/* Check if ring buffer is full or command entry is waiting
262		 * for response from TEE
263		 */
264		if (!(tee->rb_mgr.wptr + sizeof(struct tee_ring_cmd) == rptr ||
265		      cmd->flag == CMD_WAITING_FOR_RESPONSE))
266			break;
267
268		dev_dbg(tee->dev, "tee: ring buffer full. rptr = %u wptr = %u\n",
269			rptr, tee->rb_mgr.wptr);
270
271		/* Wait if ring buffer is full or TEE is processing data */
272		mutex_unlock(&tee->rb_mgr.mutex);
273		schedule_timeout_interruptible(msecs_to_jiffies(10));
274		mutex_lock(&tee->rb_mgr.mutex);
275
276	} while (--nloop);
277
278	if (!nloop &&
279	    (tee->rb_mgr.wptr + sizeof(struct tee_ring_cmd) == rptr ||
280	     cmd->flag == CMD_WAITING_FOR_RESPONSE)) {
281		dev_err(tee->dev, "tee: ring buffer full. rptr = %u wptr = %u response flag %u\n",
282			rptr, tee->rb_mgr.wptr, cmd->flag);
283		ret = -EBUSY;
284		goto unlock;
285	}
286
287	/* Do not submit command if PSP got disabled while processing any
288	 * command in another thread
289	 */
290	if (psp_dead) {
291		ret = -EBUSY;
292		goto unlock;
293	}
294
295	/* Write command data into ring buffer */
296	cmd->cmd_id = cmd_id;
297	cmd->cmd_state = TEE_CMD_STATE_INIT;
298	memset(&cmd->buf[0], 0, sizeof(cmd->buf));
299	memcpy(&cmd->buf[0], buf, len);
300
301	/* Indicate driver is waiting for response */
302	cmd->flag = CMD_WAITING_FOR_RESPONSE;
303
304	/* Update local copy of write pointer */
305	tee->rb_mgr.wptr += sizeof(struct tee_ring_cmd);
306	if (tee->rb_mgr.wptr >= tee->rb_mgr.ring_size)
307		tee->rb_mgr.wptr = 0;
308
309	/* Trigger interrupt to Trusted OS */
310	iowrite32(tee->rb_mgr.wptr, tee->io_regs + tee->vdata->ring_wptr_reg);
311
312	/* The response is provided by Trusted OS in same
313	 * location as submitted data entry within ring buffer.
314	 */
315	*resp = cmd;
316
317unlock:
318	mutex_unlock(&tee->rb_mgr.mutex);
319
320	return ret;
321}
322
323static int tee_wait_cmd_completion(struct psp_tee_device *tee,
324				   struct tee_ring_cmd *resp,
325				   unsigned int timeout)
326{
327	/* ~1ms sleep per loop => nloop = timeout * 1000 */
328	int nloop = timeout * 1000;
329
330	while (--nloop) {
331		if (resp->cmd_state == TEE_CMD_STATE_COMPLETED)
332			return 0;
333
334		usleep_range(1000, 1100);
335	}
336
337	dev_err(tee->dev, "tee: command 0x%x timed out, disabling PSP\n",
338		resp->cmd_id);
339
340	psp_dead = true;
341
342	return -ETIMEDOUT;
343}
344
345int psp_tee_process_cmd(enum tee_cmd_id cmd_id, void *buf, size_t len,
346			u32 *status)
347{
348	struct psp_device *psp = psp_get_master_device();
349	struct psp_tee_device *tee;
350	struct tee_ring_cmd *resp;
351	int ret;
352
353	if (!buf || !status || !len || len > sizeof(resp->buf))
354		return -EINVAL;
355
356	*status = 0;
357
358	if (!psp || !psp->tee_data)
359		return -ENODEV;
360
361	if (psp_dead)
362		return -EBUSY;
363
364	tee = psp->tee_data;
365
366	ret = tee_submit_cmd(tee, cmd_id, buf, len, &resp);
367	if (ret)
368		return ret;
369
370	ret = tee_wait_cmd_completion(tee, resp, TEE_DEFAULT_RING_TIMEOUT);
371	if (ret) {
372		resp->flag = CMD_RESPONSE_TIMEDOUT;
373		return ret;
374	}
375
376	memcpy(buf, &resp->buf[0], len);
377	*status = resp->status;
378
379	resp->flag = CMD_RESPONSE_COPIED;
380
381	return 0;
382}
383EXPORT_SYMBOL(psp_tee_process_cmd);
384
385int psp_check_tee_status(void)
386{
387	struct psp_device *psp = psp_get_master_device();
388
389	if (!psp || !psp->tee_data)
390		return -ENODEV;
391
392	return 0;
393}
394EXPORT_SYMBOL(psp_check_tee_status);
395
396int tee_restore(struct psp_device *psp)
397{
398	return tee_init_ring(psp->tee_data);
399}
~/ Read-only file preview.