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

crypto: ccp - Move direct access to some PSP registers out of TEE

With the PSP mailbox registers supporting more than just TEE, access to
them must be maintained and serialized by the PSP device support. Remove
TEE support direct access and create an interface in the PSP support
where the register access can be controlled/serialized.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Reviewed-by: Rijo Thomas <Rijo-john.Thomas@amd.com>
Tested-by: Rijo Thomas <Rijo-john.Thomas@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Tom Lendacky and committed by
Herbert Xu
949a0c8d b58a3600

+104 -58
+60
drivers/crypto/ccp/psp-dev.c
··· 9 9 10 10 #include <linux/kernel.h> 11 11 #include <linux/irqreturn.h> 12 + #include <linux/mutex.h> 13 + #include <linux/bitfield.h> 14 + #include <linux/delay.h> 12 15 13 16 #include "sp-dev.h" 14 17 #include "psp-dev.h" ··· 21 18 #include "dbc.h" 22 19 23 20 struct psp_device *psp_master; 21 + 22 + #define PSP_C2PMSG_17_CMDRESP_CMD GENMASK(19, 16) 23 + 24 + static int psp_mailbox_poll(const void __iomem *cmdresp_reg, unsigned int *cmdresp, 25 + unsigned int timeout_msecs) 26 + { 27 + while (true) { 28 + *cmdresp = ioread32(cmdresp_reg); 29 + if (FIELD_GET(PSP_CMDRESP_RESP, *cmdresp)) 30 + return 0; 31 + 32 + if (!timeout_msecs--) 33 + break; 34 + 35 + usleep_range(1000, 1100); 36 + } 37 + 38 + return -ETIMEDOUT; 39 + } 40 + 41 + int psp_mailbox_command(struct psp_device *psp, enum psp_cmd cmd, void *cmdbuff, 42 + unsigned int timeout_msecs, unsigned int *cmdresp) 43 + { 44 + void __iomem *cmdresp_reg, *cmdbuff_lo_reg, *cmdbuff_hi_reg; 45 + int ret; 46 + 47 + if (!psp || !psp->vdata || !psp->vdata->cmdresp_reg || 48 + !psp->vdata->cmdbuff_addr_lo_reg || !psp->vdata->cmdbuff_addr_hi_reg) 49 + return -ENODEV; 50 + 51 + cmdresp_reg = psp->io_regs + psp->vdata->cmdresp_reg; 52 + cmdbuff_lo_reg = psp->io_regs + psp->vdata->cmdbuff_addr_lo_reg; 53 + cmdbuff_hi_reg = psp->io_regs + psp->vdata->cmdbuff_addr_hi_reg; 54 + 55 + mutex_lock(&psp->mailbox_mutex); 56 + 57 + /* Ensure mailbox is ready for a command */ 58 + ret = -EBUSY; 59 + if (psp_mailbox_poll(cmdresp_reg, cmdresp, 0)) 60 + goto unlock; 61 + 62 + if (cmdbuff) { 63 + iowrite32(lower_32_bits(__psp_pa(cmdbuff)), cmdbuff_lo_reg); 64 + iowrite32(upper_32_bits(__psp_pa(cmdbuff)), cmdbuff_hi_reg); 65 + } 66 + 67 + *cmdresp = FIELD_PREP(PSP_C2PMSG_17_CMDRESP_CMD, cmd); 68 + iowrite32(*cmdresp, cmdresp_reg); 69 + 70 + ret = psp_mailbox_poll(cmdresp_reg, cmdresp, timeout_msecs); 71 + 72 + unlock: 73 + mutex_unlock(&psp->mailbox_mutex); 74 + 75 + return ret; 76 + } 24 77 25 78 static struct psp_device *psp_alloc_struct(struct sp_device *sp) 26 79 { ··· 223 164 } 224 165 225 166 psp->io_regs = sp->io_map; 167 + mutex_init(&psp->mailbox_mutex); 226 168 227 169 ret = psp_get_capability(psp); 228 170 if (ret)
+18
drivers/crypto/ccp/psp-dev.h
··· 14 14 #include <linux/list.h> 15 15 #include <linux/bits.h> 16 16 #include <linux/interrupt.h> 17 + #include <linux/mutex.h> 18 + #include <linux/psp.h> 17 19 18 20 #include "sp-dev.h" 19 21 ··· 35 33 struct sp_device *sp; 36 34 37 35 void __iomem *io_regs; 36 + struct mutex mailbox_mutex; 38 37 39 38 psp_irq_handler_t sev_irq_handler; 40 39 void *sev_irq_data; ··· 73 70 #define PSP_SECURITY_RPMC_SPIROM_AVAILABLE BIT(9) 74 71 #define PSP_SECURITY_HSP_TPM_AVAILABLE BIT(10) 75 72 #define PSP_SECURITY_ROM_ARMOR_ENFORCED BIT(11) 73 + 74 + /** 75 + * enum psp_cmd - PSP mailbox commands 76 + * @PSP_CMD_TEE_RING_INIT: Initialize TEE ring buffer 77 + * @PSP_CMD_TEE_RING_DESTROY: Destroy TEE ring buffer 78 + * @PSP_CMD_MAX: Maximum command id 79 + */ 80 + enum psp_cmd { 81 + PSP_CMD_TEE_RING_INIT = 1, 82 + PSP_CMD_TEE_RING_DESTROY = 2, 83 + PSP_CMD_MAX = 15, 84 + }; 85 + 86 + int psp_mailbox_command(struct psp_device *psp, enum psp_cmd cmd, void *cmdbuff, 87 + unsigned int timeout_msecs, unsigned int *cmdresp); 76 88 77 89 #endif /* __PSP_DEV_H */
+3
drivers/crypto/ccp/sp-dev.h
··· 71 71 const struct sev_vdata *sev; 72 72 const struct tee_vdata *tee; 73 73 const struct platform_access_vdata *platform_access; 74 + const unsigned int cmdresp_reg; 75 + const unsigned int cmdbuff_addr_lo_reg; 76 + const unsigned int cmdbuff_addr_hi_reg; 74 77 const unsigned int feature_reg; 75 78 const unsigned int inten_reg; 76 79 const unsigned int intsts_reg;
+12 -6
drivers/crypto/ccp/sp-pci.c
··· 418 418 }; 419 419 420 420 static const struct tee_vdata teev1 = { 421 - .cmdresp_reg = 0x10544, /* C2PMSG_17 */ 422 - .cmdbuff_addr_lo_reg = 0x10548, /* C2PMSG_18 */ 423 - .cmdbuff_addr_hi_reg = 0x1054c, /* C2PMSG_19 */ 424 421 .ring_wptr_reg = 0x10550, /* C2PMSG_20 */ 425 422 .ring_rptr_reg = 0x10554, /* C2PMSG_21 */ 426 423 .info_reg = 0x109e8, /* C2PMSG_58 */ 427 424 }; 428 425 429 426 static const struct tee_vdata teev2 = { 430 - .cmdresp_reg = 0x10944, /* C2PMSG_17 */ 431 - .cmdbuff_addr_lo_reg = 0x10948, /* C2PMSG_18 */ 432 - .cmdbuff_addr_hi_reg = 0x1094c, /* C2PMSG_19 */ 433 427 .ring_wptr_reg = 0x10950, /* C2PMSG_20 */ 434 428 .ring_rptr_reg = 0x10954, /* C2PMSG_21 */ 435 429 }; ··· 460 466 static const struct psp_vdata pspv3 = { 461 467 .tee = &teev1, 462 468 .platform_access = &pa_v1, 469 + .cmdresp_reg = 0x10544, /* C2PMSG_17 */ 470 + .cmdbuff_addr_lo_reg = 0x10548, /* C2PMSG_18 */ 471 + .cmdbuff_addr_hi_reg = 0x1054c, /* C2PMSG_19 */ 463 472 .bootloader_info_reg = 0x109ec, /* C2PMSG_59 */ 464 473 .feature_reg = 0x109fc, /* C2PMSG_63 */ 465 474 .inten_reg = 0x10690, /* P2CMSG_INTEN */ ··· 473 476 static const struct psp_vdata pspv4 = { 474 477 .sev = &sevv2, 475 478 .tee = &teev1, 479 + .cmdresp_reg = 0x10544, /* C2PMSG_17 */ 480 + .cmdbuff_addr_lo_reg = 0x10548, /* C2PMSG_18 */ 481 + .cmdbuff_addr_hi_reg = 0x1054c, /* C2PMSG_19 */ 476 482 .bootloader_info_reg = 0x109ec, /* C2PMSG_59 */ 477 483 .feature_reg = 0x109fc, /* C2PMSG_63 */ 478 484 .inten_reg = 0x10690, /* P2CMSG_INTEN */ ··· 485 485 static const struct psp_vdata pspv5 = { 486 486 .tee = &teev2, 487 487 .platform_access = &pa_v2, 488 + .cmdresp_reg = 0x10944, /* C2PMSG_17 */ 489 + .cmdbuff_addr_lo_reg = 0x10948, /* C2PMSG_18 */ 490 + .cmdbuff_addr_hi_reg = 0x1094c, /* C2PMSG_19 */ 488 491 .feature_reg = 0x109fc, /* C2PMSG_63 */ 489 492 .inten_reg = 0x10510, /* P2CMSG_INTEN */ 490 493 .intsts_reg = 0x10514, /* P2CMSG_INTSTS */ ··· 496 493 static const struct psp_vdata pspv6 = { 497 494 .sev = &sevv2, 498 495 .tee = &teev2, 496 + .cmdresp_reg = 0x10944, /* C2PMSG_17 */ 497 + .cmdbuff_addr_lo_reg = 0x10948, /* C2PMSG_18 */ 498 + .cmdbuff_addr_hi_reg = 0x1094c, /* C2PMSG_19 */ 499 499 .feature_reg = 0x109fc, /* C2PMSG_63 */ 500 500 .inten_reg = 0x10510, /* P2CMSG_INTEN */ 501 501 .intsts_reg = 0x10514, /* P2CMSG_INTSTS */
+9 -39
drivers/crypto/ccp/tee-dev.c
··· 62 62 mutex_destroy(&rb_mgr->mutex); 63 63 } 64 64 65 - static int tee_wait_cmd_poll(struct psp_tee_device *tee, unsigned int timeout, 66 - unsigned int *reg) 67 - { 68 - /* ~10ms sleep per loop => nloop = timeout * 100 */ 69 - int nloop = timeout * 100; 70 - 71 - while (--nloop) { 72 - *reg = ioread32(tee->io_regs + tee->vdata->cmdresp_reg); 73 - if (FIELD_GET(PSP_CMDRESP_RESP, *reg)) 74 - return 0; 75 - 76 - usleep_range(10000, 10100); 77 - } 78 - 79 - dev_err(tee->dev, "tee: command timed out, disabling PSP\n"); 80 - psp_dead = true; 81 - 82 - return -ETIMEDOUT; 83 - } 84 - 85 65 static 86 66 struct tee_init_ring_cmd *tee_alloc_cmd_buffer(struct psp_tee_device *tee) 87 67 { ··· 90 110 { 91 111 int ring_size = MAX_RING_BUFFER_ENTRIES * sizeof(struct tee_ring_cmd); 92 112 struct tee_init_ring_cmd *cmd; 93 - phys_addr_t cmd_buffer; 94 113 unsigned int reg; 95 114 int ret; 96 115 ··· 109 130 return -ENOMEM; 110 131 } 111 132 112 - cmd_buffer = __psp_pa((void *)cmd); 113 - 114 133 /* Send command buffer details to Trusted OS by writing to 115 134 * CPU-PSP message registers 116 135 */ 117 - 118 - iowrite32(lower_32_bits(cmd_buffer), 119 - tee->io_regs + tee->vdata->cmdbuff_addr_lo_reg); 120 - iowrite32(upper_32_bits(cmd_buffer), 121 - tee->io_regs + tee->vdata->cmdbuff_addr_hi_reg); 122 - iowrite32(TEE_RING_INIT_CMD, 123 - tee->io_regs + tee->vdata->cmdresp_reg); 124 - 125 - ret = tee_wait_cmd_poll(tee, TEE_DEFAULT_TIMEOUT, &reg); 136 + ret = psp_mailbox_command(tee->psp, PSP_CMD_TEE_RING_INIT, cmd, 137 + TEE_DEFAULT_CMD_TIMEOUT, &reg); 126 138 if (ret) { 127 - dev_err(tee->dev, "tee: ring init command timed out\n"); 139 + dev_err(tee->dev, "tee: ring init command timed out, disabling TEE support\n"); 128 140 tee_free_ring(tee); 141 + psp_dead = true; 129 142 goto free_buf; 130 143 } 131 144 ··· 145 174 if (psp_dead) 146 175 goto free_ring; 147 176 148 - iowrite32(TEE_RING_DESTROY_CMD, 149 - tee->io_regs + tee->vdata->cmdresp_reg); 150 - 151 - ret = tee_wait_cmd_poll(tee, TEE_DEFAULT_TIMEOUT, &reg); 177 + ret = psp_mailbox_command(tee->psp, PSP_CMD_TEE_RING_DESTROY, NULL, 178 + TEE_DEFAULT_CMD_TIMEOUT, &reg); 152 179 if (ret) { 153 - dev_err(tee->dev, "tee: ring destroy command timed out\n"); 180 + dev_err(tee->dev, "tee: ring destroy command timed out, disabling TEE support\n"); 181 + psp_dead = true; 154 182 } else if (FIELD_GET(PSP_CMDRESP_STS, reg)) { 155 183 dev_err(tee->dev, "tee: ring destroy command failed (%#010lx)\n", 156 184 FIELD_GET(PSP_CMDRESP_STS, reg)); ··· 340 370 if (ret) 341 371 return ret; 342 372 343 - ret = tee_wait_cmd_completion(tee, resp, TEE_DEFAULT_TIMEOUT); 373 + ret = tee_wait_cmd_completion(tee, resp, TEE_DEFAULT_RING_TIMEOUT); 344 374 if (ret) { 345 375 resp->flag = CMD_RESPONSE_TIMEDOUT; 346 376 return ret;
+2 -13
drivers/crypto/ccp/tee-dev.h
··· 17 17 #include <linux/device.h> 18 18 #include <linux/mutex.h> 19 19 20 - #define TEE_DEFAULT_TIMEOUT 10 20 + #define TEE_DEFAULT_CMD_TIMEOUT (10 * MSEC_PER_SEC) 21 + #define TEE_DEFAULT_RING_TIMEOUT 10 21 22 #define MAX_BUFFER_SIZE 988 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 23 35 24 /** 36 25 * struct tee_init_ring_cmd - Command to init TEE ring buffer