Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: ccp - add TEE support for Raven Ridge

Adds a PCI device entry for Raven Ridge. Raven Ridge is an APU with a
dedicated AMD Secure Processor having Trusted Execution Environment (TEE)
support. The TEE provides a secure environment for running Trusted
Applications (TAs) which implement security-sensitive parts of a feature.

This patch configures AMD Secure Processor's TEE interface by initializing
a ring buffer (shared memory between Rich OS and Trusted OS) which can hold
multiple command buffer entries. The TEE interface is facilitated by a set
of CPU to PSP mailbox registers.

The next patch will address how commands are submitted to the ring buffer.

Cc: Jens Wiklander <jens.wiklander@linaro.org>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Co-developed-by: Devaraj Rangasamy <Devaraj.Rangasamy@amd.com>
Signed-off-by: Devaraj Rangasamy <Devaraj.Rangasamy@amd.com>
Signed-off-by: Rijo Thomas <Rijo-john.Thomas@amd.com>
Acked-by: Gary R Hook <gary.hook@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Rijo Thomas and committed by
Herbert Xu
33960acc f100ab62

+431 -4
+2 -1
drivers/crypto/ccp/Makefile
··· 9 9 ccp-$(CONFIG_CRYPTO_DEV_CCP_DEBUGFS) += ccp-debugfs.o 10 10 ccp-$(CONFIG_PCI) += sp-pci.o 11 11 ccp-$(CONFIG_CRYPTO_DEV_SP_PSP) += psp-dev.o \ 12 - sev-dev.o 12 + sev-dev.o \ 13 + tee-dev.o 13 14 14 15 obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o 15 16 ccp-crypto-objs := ccp-crypto-main.o \
+38 -1
drivers/crypto/ccp/psp-dev.c
··· 13 13 #include "sp-dev.h" 14 14 #include "psp-dev.h" 15 15 #include "sev-dev.h" 16 + #include "tee-dev.h" 16 17 17 18 struct psp_device *psp_master; 18 19 ··· 46 45 if (status) { 47 46 if (psp->sev_irq_handler) 48 47 psp->sev_irq_handler(irq, psp->sev_irq_data, status); 48 + 49 + if (psp->tee_irq_handler) 50 + psp->tee_irq_handler(irq, psp->tee_irq_data, status); 49 51 } 50 52 51 53 /* Clear the interrupt status by writing the same value we read. */ ··· 113 109 return 0; 114 110 } 115 111 112 + static int psp_init(struct psp_device *psp, unsigned int capability) 113 + { 114 + int ret; 115 + 116 + if (!psp_check_sev_support(psp, capability)) { 117 + ret = sev_dev_init(psp); 118 + if (ret) 119 + return ret; 120 + } 121 + 122 + if (!psp_check_tee_support(psp, capability)) { 123 + ret = tee_dev_init(psp); 124 + if (ret) 125 + return ret; 126 + } 127 + 128 + return 0; 129 + } 130 + 116 131 int psp_dev_init(struct sp_device *sp) 117 132 { 118 133 struct device *dev = sp->dev; ··· 174 151 goto e_err; 175 152 } 176 153 177 - ret = sev_dev_init(psp); 154 + ret = psp_init(psp, capability); 178 155 if (ret) 179 156 goto e_irq; 180 157 ··· 212 189 213 190 sev_dev_destroy(psp); 214 191 192 + tee_dev_destroy(psp); 193 + 215 194 sp_free_psp_irq(sp, psp); 216 195 } 217 196 ··· 227 202 void psp_clear_sev_irq_handler(struct psp_device *psp) 228 203 { 229 204 psp_set_sev_irq_handler(psp, NULL, NULL); 205 + } 206 + 207 + void psp_set_tee_irq_handler(struct psp_device *psp, psp_irq_handler_t handler, 208 + void *data) 209 + { 210 + psp->tee_irq_data = data; 211 + psp->tee_irq_handler = handler; 212 + } 213 + 214 + void psp_clear_tee_irq_handler(struct psp_device *psp) 215 + { 216 + psp_set_tee_irq_handler(psp, NULL, NULL); 230 217 } 231 218 232 219 struct psp_device *psp_get_master_device(void)
+8
drivers/crypto/ccp/psp-dev.h
··· 40 40 psp_irq_handler_t sev_irq_handler; 41 41 void *sev_irq_data; 42 42 43 + psp_irq_handler_t tee_irq_handler; 44 + void *tee_irq_data; 45 + 43 46 void *sev_data; 47 + void *tee_data; 44 48 }; 45 49 46 50 void psp_set_sev_irq_handler(struct psp_device *psp, psp_irq_handler_t handler, 47 51 void *data); 48 52 void psp_clear_sev_irq_handler(struct psp_device *psp); 53 + 54 + void psp_set_tee_irq_handler(struct psp_device *psp, psp_irq_handler_t handler, 55 + void *data); 56 + void psp_clear_tee_irq_handler(struct psp_device *psp); 49 57 50 58 struct psp_device *psp_get_master_device(void); 51 59
+10 -1
drivers/crypto/ccp/sp-dev.h
··· 2 2 /* 3 3 * AMD Secure Processor driver 4 4 * 5 - * Copyright (C) 2017-2018 Advanced Micro Devices, Inc. 5 + * Copyright (C) 2017-2019 Advanced Micro Devices, Inc. 6 6 * 7 7 * Author: Tom Lendacky <thomas.lendacky@amd.com> 8 8 * Author: Gary R Hook <gary.hook@amd.com> ··· 45 45 const unsigned int cmdbuff_addr_hi_reg; 46 46 }; 47 47 48 + struct tee_vdata { 49 + const unsigned int cmdresp_reg; 50 + const unsigned int cmdbuff_addr_lo_reg; 51 + const unsigned int cmdbuff_addr_hi_reg; 52 + const unsigned int ring_wptr_reg; 53 + const unsigned int ring_rptr_reg; 54 + }; 55 + 48 56 struct psp_vdata { 49 57 const struct sev_vdata *sev; 58 + const struct tee_vdata *tee; 50 59 const unsigned int feature_reg; 51 60 const unsigned int inten_reg; 52 61 const unsigned int intsts_reg;
+26 -1
drivers/crypto/ccp/sp-pci.c
··· 2 2 /* 3 3 * AMD Secure Processor device driver 4 4 * 5 - * Copyright (C) 2013,2018 Advanced Micro Devices, Inc. 5 + * Copyright (C) 2013,2019 Advanced Micro Devices, Inc. 6 6 * 7 7 * Author: Tom Lendacky <thomas.lendacky@amd.com> 8 8 * Author: Gary R Hook <gary.hook@amd.com> ··· 274 274 .cmdbuff_addr_hi_reg = 0x109e4, 275 275 }; 276 276 277 + static const struct tee_vdata teev1 = { 278 + .cmdresp_reg = 0x10544, 279 + .cmdbuff_addr_lo_reg = 0x10548, 280 + .cmdbuff_addr_hi_reg = 0x1054c, 281 + .ring_wptr_reg = 0x10550, 282 + .ring_rptr_reg = 0x10554, 283 + }; 284 + 277 285 static const struct psp_vdata pspv1 = { 278 286 .sev = &sevv1, 279 287 .feature_reg = 0x105fc, ··· 291 283 292 284 static const struct psp_vdata pspv2 = { 293 285 .sev = &sevv2, 286 + .feature_reg = 0x109fc, 287 + .inten_reg = 0x10690, 288 + .intsts_reg = 0x10694, 289 + }; 290 + 291 + static const struct psp_vdata pspv3 = { 292 + .tee = &teev1, 294 293 .feature_reg = 0x109fc, 295 294 .inten_reg = 0x10690, 296 295 .intsts_reg = 0x10694, ··· 335 320 .psp_vdata = &pspv2, 336 321 #endif 337 322 }, 323 + { /* 4 */ 324 + .bar = 2, 325 + #ifdef CONFIG_CRYPTO_DEV_SP_CCP 326 + .ccp_vdata = &ccpv5a, 327 + #endif 328 + #ifdef CONFIG_CRYPTO_DEV_SP_PSP 329 + .psp_vdata = &pspv3, 330 + #endif 331 + }, 338 332 }; 339 333 static const struct pci_device_id sp_pci_table[] = { 340 334 { PCI_VDEVICE(AMD, 0x1537), (kernel_ulong_t)&dev_vdata[0] }, 341 335 { PCI_VDEVICE(AMD, 0x1456), (kernel_ulong_t)&dev_vdata[1] }, 342 336 { PCI_VDEVICE(AMD, 0x1468), (kernel_ulong_t)&dev_vdata[2] }, 343 337 { PCI_VDEVICE(AMD, 0x1486), (kernel_ulong_t)&dev_vdata[3] }, 338 + { PCI_VDEVICE(AMD, 0x15DF), (kernel_ulong_t)&dev_vdata[4] }, 344 339 /* Last entry must be zero */ 345 340 { 0, } 346 341 };
+238
drivers/crypto/ccp/tee-dev.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 2019 Advanced Micro Devices, Inc. 9 + */ 10 + 11 + #include <linux/types.h> 12 + #include <linux/mutex.h> 13 + #include <linux/delay.h> 14 + #include <linux/slab.h> 15 + #include <linux/gfp.h> 16 + #include <linux/psp-sev.h> 17 + 18 + #include "psp-dev.h" 19 + #include "tee-dev.h" 20 + 21 + static bool psp_dead; 22 + 23 + static int tee_alloc_ring(struct psp_tee_device *tee, int ring_size) 24 + { 25 + struct ring_buf_manager *rb_mgr = &tee->rb_mgr; 26 + void *start_addr; 27 + 28 + if (!ring_size) 29 + return -EINVAL; 30 + 31 + /* We need actual physical address instead of DMA address, since 32 + * Trusted OS running on AMD Secure Processor will map this region 33 + */ 34 + start_addr = (void *)__get_free_pages(GFP_KERNEL, get_order(ring_size)); 35 + if (!start_addr) 36 + return -ENOMEM; 37 + 38 + rb_mgr->ring_start = start_addr; 39 + rb_mgr->ring_size = ring_size; 40 + rb_mgr->ring_pa = __psp_pa(start_addr); 41 + 42 + return 0; 43 + } 44 + 45 + static void tee_free_ring(struct psp_tee_device *tee) 46 + { 47 + struct ring_buf_manager *rb_mgr = &tee->rb_mgr; 48 + 49 + if (!rb_mgr->ring_start) 50 + return; 51 + 52 + free_pages((unsigned long)rb_mgr->ring_start, 53 + get_order(rb_mgr->ring_size)); 54 + 55 + rb_mgr->ring_start = NULL; 56 + rb_mgr->ring_size = 0; 57 + rb_mgr->ring_pa = 0; 58 + } 59 + 60 + static int tee_wait_cmd_poll(struct psp_tee_device *tee, unsigned int timeout, 61 + unsigned int *reg) 62 + { 63 + /* ~10ms sleep per loop => nloop = timeout * 100 */ 64 + int nloop = timeout * 100; 65 + 66 + while (--nloop) { 67 + *reg = ioread32(tee->io_regs + tee->vdata->cmdresp_reg); 68 + if (*reg & PSP_CMDRESP_RESP) 69 + return 0; 70 + 71 + usleep_range(10000, 10100); 72 + } 73 + 74 + dev_err(tee->dev, "tee: command timed out, disabling PSP\n"); 75 + psp_dead = true; 76 + 77 + return -ETIMEDOUT; 78 + } 79 + 80 + static 81 + struct tee_init_ring_cmd *tee_alloc_cmd_buffer(struct psp_tee_device *tee) 82 + { 83 + struct tee_init_ring_cmd *cmd; 84 + 85 + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 86 + if (!cmd) 87 + return NULL; 88 + 89 + cmd->hi_addr = upper_32_bits(tee->rb_mgr.ring_pa); 90 + cmd->low_addr = lower_32_bits(tee->rb_mgr.ring_pa); 91 + cmd->size = tee->rb_mgr.ring_size; 92 + 93 + dev_dbg(tee->dev, "tee: ring address: high = 0x%x low = 0x%x size = %u\n", 94 + cmd->hi_addr, cmd->low_addr, cmd->size); 95 + 96 + return cmd; 97 + } 98 + 99 + static inline void tee_free_cmd_buffer(struct tee_init_ring_cmd *cmd) 100 + { 101 + kfree(cmd); 102 + } 103 + 104 + static int tee_init_ring(struct psp_tee_device *tee) 105 + { 106 + int ring_size = MAX_RING_BUFFER_ENTRIES * sizeof(struct tee_ring_cmd); 107 + struct tee_init_ring_cmd *cmd; 108 + phys_addr_t cmd_buffer; 109 + unsigned int reg; 110 + int ret; 111 + 112 + BUILD_BUG_ON(sizeof(struct tee_ring_cmd) != 1024); 113 + 114 + ret = tee_alloc_ring(tee, ring_size); 115 + if (ret) { 116 + dev_err(tee->dev, "tee: ring allocation failed %d\n", ret); 117 + return ret; 118 + } 119 + 120 + tee->rb_mgr.wptr = 0; 121 + 122 + cmd = tee_alloc_cmd_buffer(tee); 123 + if (!cmd) { 124 + tee_free_ring(tee); 125 + return -ENOMEM; 126 + } 127 + 128 + cmd_buffer = __psp_pa((void *)cmd); 129 + 130 + /* Send command buffer details to Trusted OS by writing to 131 + * CPU-PSP message registers 132 + */ 133 + 134 + iowrite32(lower_32_bits(cmd_buffer), 135 + tee->io_regs + tee->vdata->cmdbuff_addr_lo_reg); 136 + iowrite32(upper_32_bits(cmd_buffer), 137 + tee->io_regs + tee->vdata->cmdbuff_addr_hi_reg); 138 + iowrite32(TEE_RING_INIT_CMD, 139 + tee->io_regs + tee->vdata->cmdresp_reg); 140 + 141 + ret = tee_wait_cmd_poll(tee, TEE_DEFAULT_TIMEOUT, &reg); 142 + if (ret) { 143 + dev_err(tee->dev, "tee: ring init command timed out\n"); 144 + tee_free_ring(tee); 145 + goto free_buf; 146 + } 147 + 148 + if (reg & PSP_CMDRESP_ERR_MASK) { 149 + dev_err(tee->dev, "tee: ring init command failed (%#010x)\n", 150 + reg & PSP_CMDRESP_ERR_MASK); 151 + tee_free_ring(tee); 152 + ret = -EIO; 153 + } 154 + 155 + free_buf: 156 + tee_free_cmd_buffer(cmd); 157 + 158 + return ret; 159 + } 160 + 161 + static void tee_destroy_ring(struct psp_tee_device *tee) 162 + { 163 + unsigned int reg; 164 + int ret; 165 + 166 + if (!tee->rb_mgr.ring_start) 167 + return; 168 + 169 + if (psp_dead) 170 + goto free_ring; 171 + 172 + iowrite32(TEE_RING_DESTROY_CMD, 173 + tee->io_regs + tee->vdata->cmdresp_reg); 174 + 175 + ret = tee_wait_cmd_poll(tee, TEE_DEFAULT_TIMEOUT, &reg); 176 + if (ret) { 177 + dev_err(tee->dev, "tee: ring destroy command timed out\n"); 178 + } else if (reg & PSP_CMDRESP_ERR_MASK) { 179 + dev_err(tee->dev, "tee: ring destroy command failed (%#010x)\n", 180 + reg & PSP_CMDRESP_ERR_MASK); 181 + } 182 + 183 + free_ring: 184 + tee_free_ring(tee); 185 + } 186 + 187 + int tee_dev_init(struct psp_device *psp) 188 + { 189 + struct device *dev = psp->dev; 190 + struct psp_tee_device *tee; 191 + int ret; 192 + 193 + ret = -ENOMEM; 194 + tee = devm_kzalloc(dev, sizeof(*tee), GFP_KERNEL); 195 + if (!tee) 196 + goto e_err; 197 + 198 + psp->tee_data = tee; 199 + 200 + tee->dev = dev; 201 + tee->psp = psp; 202 + 203 + tee->io_regs = psp->io_regs; 204 + 205 + tee->vdata = (struct tee_vdata *)psp->vdata->tee; 206 + if (!tee->vdata) { 207 + ret = -ENODEV; 208 + dev_err(dev, "tee: missing driver data\n"); 209 + goto e_err; 210 + } 211 + 212 + ret = tee_init_ring(tee); 213 + if (ret) { 214 + dev_err(dev, "tee: failed to init ring buffer\n"); 215 + goto e_err; 216 + } 217 + 218 + dev_notice(dev, "tee enabled\n"); 219 + 220 + return 0; 221 + 222 + e_err: 223 + psp->tee_data = NULL; 224 + 225 + dev_notice(dev, "tee initialization failed\n"); 226 + 227 + return ret; 228 + } 229 + 230 + void tee_dev_destroy(struct psp_device *psp) 231 + { 232 + struct psp_tee_device *tee = psp->tee_data; 233 + 234 + if (!tee) 235 + return; 236 + 237 + tee_destroy_ring(tee); 238 + }
+109
drivers/crypto/ccp/tee-dev.h
··· 1 + /* SPDX-License-Identifier: MIT */ 2 + /* 3 + * Copyright 2019 Advanced Micro Devices, Inc. 4 + * 5 + * Author: Rijo Thomas <Rijo-john.Thomas@amd.com> 6 + * Author: Devaraj Rangasamy <Devaraj.Rangasamy@amd.com> 7 + * 8 + */ 9 + 10 + /* This file describes the TEE communication interface between host and AMD 11 + * Secure Processor 12 + */ 13 + 14 + #ifndef __TEE_DEV_H__ 15 + #define __TEE_DEV_H__ 16 + 17 + #include <linux/device.h> 18 + #include <linux/mutex.h> 19 + 20 + #define TEE_DEFAULT_TIMEOUT 10 21 + #define MAX_BUFFER_SIZE 992 22 + 23 + /** 24 + * enum tee_ring_cmd_id - TEE interface commands for ring buffer configuration 25 + * @TEE_RING_INIT_CMD: Initialize ring buffer 26 + * @TEE_RING_DESTROY_CMD: Destroy ring buffer 27 + * @TEE_RING_MAX_CMD: Maximum command id 28 + */ 29 + enum tee_ring_cmd_id { 30 + TEE_RING_INIT_CMD = 0x00010000, 31 + TEE_RING_DESTROY_CMD = 0x00020000, 32 + TEE_RING_MAX_CMD = 0x000F0000, 33 + }; 34 + 35 + /** 36 + * struct tee_init_ring_cmd - Command to init TEE ring buffer 37 + * @low_addr: bits [31:0] of the physical address of ring buffer 38 + * @hi_addr: bits [63:32] of the physical address of ring buffer 39 + * @size: size of ring buffer in bytes 40 + */ 41 + struct tee_init_ring_cmd { 42 + u32 low_addr; 43 + u32 hi_addr; 44 + u32 size; 45 + }; 46 + 47 + #define MAX_RING_BUFFER_ENTRIES 32 48 + 49 + /** 50 + * struct ring_buf_manager - Helper structure to manage ring buffer. 51 + * @ring_start: starting address of ring buffer 52 + * @ring_size: size of ring buffer in bytes 53 + * @ring_pa: physical address of ring buffer 54 + * @wptr: index to the last written entry in ring buffer 55 + */ 56 + struct ring_buf_manager { 57 + void *ring_start; 58 + u32 ring_size; 59 + phys_addr_t ring_pa; 60 + u32 wptr; 61 + }; 62 + 63 + struct psp_tee_device { 64 + struct device *dev; 65 + struct psp_device *psp; 66 + void __iomem *io_regs; 67 + struct tee_vdata *vdata; 68 + struct ring_buf_manager rb_mgr; 69 + }; 70 + 71 + /** 72 + * enum tee_cmd_state - TEE command states for the ring buffer interface 73 + * @TEE_CMD_STATE_INIT: initial state of command when sent from host 74 + * @TEE_CMD_STATE_PROCESS: command being processed by TEE environment 75 + * @TEE_CMD_STATE_COMPLETED: command processing completed 76 + */ 77 + enum tee_cmd_state { 78 + TEE_CMD_STATE_INIT, 79 + TEE_CMD_STATE_PROCESS, 80 + TEE_CMD_STATE_COMPLETED, 81 + }; 82 + 83 + /** 84 + * struct tee_ring_cmd - Structure of the command buffer in TEE ring 85 + * @cmd_id: refers to &enum tee_cmd_id. Command id for the ring buffer 86 + * interface 87 + * @cmd_state: refers to &enum tee_cmd_state 88 + * @status: status of TEE command execution 89 + * @res0: reserved region 90 + * @pdata: private data (currently unused) 91 + * @res1: reserved region 92 + * @buf: TEE command specific buffer 93 + */ 94 + struct tee_ring_cmd { 95 + u32 cmd_id; 96 + u32 cmd_state; 97 + u32 status; 98 + u32 res0[1]; 99 + u64 pdata; 100 + u32 res1[2]; 101 + u8 buf[MAX_BUFFER_SIZE]; 102 + 103 + /* Total size: 1024 bytes */ 104 + } __packed; 105 + 106 + int tee_dev_init(struct psp_device *psp); 107 + void tee_dev_destroy(struct psp_device *psp); 108 + 109 + #endif /* __TEE_DEV_H__ */