368 lines · c
1// SPDX-License-Identifier: MIT2/*3 * AMD Trusted Execution Environment (TEE) interface4 *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, since34 * Trusted OS running on AMD Secure Processor will map this region35 */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 65static66struct 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 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 to113 * CPU-PSP message registers114 */115 ret = psp_mailbox_command(tee->psp, PSP_CMD_TEE_RING_INIT, cmd,116 TEE_DEFAULT_CMD_TIMEOUT, ®);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 131free_buf:132 tee_free_cmd_buffer(cmd);133 134 return ret;135}136 137static 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, ®);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 158free_ring:159 tee_free_ring(tee);160}161 162int 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 197e_err:198 psp->tee_data = NULL;199 200 dev_notice(dev, "tee initialization failed\n");201 202 return ret;203}204 205void 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 215static 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 waiting235 * for response from TEE236 */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 any261 * command in another thread262 */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 same286 * location as submitted data entry within ring buffer.287 */288 *resp = cmd;289 290unlock:291 mutex_unlock(&tee->rb_mgr.mutex);292 293 return ret;294}295 296static 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 318int 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}356EXPORT_SYMBOL(psp_tee_process_cmd);357 358int 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}367EXPORT_SYMBOL(psp_check_tee_status);368