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

tpm/tpm_ftpm_tee: support TPM_CHIP_FLAG_SYNC

This driver does not support interrupts, and receiving the response is
synchronous with sending the command.

Enable synchronous send() with TPM_CHIP_FLAG_SYNC, which implies that
->send() already fills the provided buffer with a response, and ->recv()
is not implemented.

Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Reviewed-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>

authored by

Stefano Garzarella and committed by
Jarkko Sakkinen
0637c10e 04fe4701

+19 -49
+19 -45
drivers/char/tpm/tpm_ftpm_tee.c
··· 31 31 0x82, 0xCB, 0x34, 0x3F, 0xB7, 0xF3, 0x78, 0x96); 32 32 33 33 /** 34 - * ftpm_tee_tpm_op_recv() - retrieve fTPM response. 35 - * @chip: the tpm_chip description as specified in driver/char/tpm/tpm.h. 36 - * @buf: the buffer to store data. 37 - * @count: the number of bytes to read. 38 - * 39 - * Return: 40 - * In case of success the number of bytes received. 41 - * On failure, -errno. 42 - */ 43 - static int ftpm_tee_tpm_op_recv(struct tpm_chip *chip, u8 *buf, size_t count) 44 - { 45 - struct ftpm_tee_private *pvt_data = dev_get_drvdata(chip->dev.parent); 46 - size_t len; 47 - 48 - len = pvt_data->resp_len; 49 - if (count < len) { 50 - dev_err(&chip->dev, 51 - "%s: Invalid size in recv: count=%zd, resp_len=%zd\n", 52 - __func__, count, len); 53 - return -EIO; 54 - } 55 - 56 - memcpy(buf, pvt_data->resp_buf, len); 57 - pvt_data->resp_len = 0; 58 - 59 - return len; 60 - } 61 - 62 - /** 63 - * ftpm_tee_tpm_op_send() - send TPM commands through the TEE shared memory. 34 + * ftpm_tee_tpm_op_send() - send TPM commands through the TEE shared memory 35 + * and retrieve the response. 64 36 * @chip: the tpm_chip description as specified in driver/char/tpm/tpm.h 65 - * @buf: the buffer to send. 37 + * @buf: the buffer to send and to store the response. 66 38 * @bufsiz: the size of the buffer. 67 - * @len: the number of bytes to send. 39 + * @cmd_len: the number of bytes to send. 68 40 * 69 41 * Return: 70 - * In case of success, returns 0. 42 + * In case of success, returns the number of bytes received. 71 43 * On failure, -errno 72 44 */ 73 45 static int ftpm_tee_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, 74 - size_t len) 46 + size_t cmd_len) 75 47 { 76 48 struct ftpm_tee_private *pvt_data = dev_get_drvdata(chip->dev.parent); 77 49 size_t resp_len; ··· 54 82 struct tee_param command_params[4]; 55 83 struct tee_shm *shm = pvt_data->shm; 56 84 57 - if (len > MAX_COMMAND_SIZE) { 85 + if (cmd_len > MAX_COMMAND_SIZE) { 58 86 dev_err(&chip->dev, 59 87 "%s: len=%zd exceeds MAX_COMMAND_SIZE supported by fTPM TA\n", 60 - __func__, len); 88 + __func__, cmd_len); 61 89 return -EIO; 62 90 } 63 91 64 92 memset(&transceive_args, 0, sizeof(transceive_args)); 65 93 memset(command_params, 0, sizeof(command_params)); 66 - pvt_data->resp_len = 0; 67 94 68 95 /* Invoke FTPM_OPTEE_TA_SUBMIT_COMMAND function of fTPM TA */ 69 96 transceive_args = (struct tee_ioctl_invoke_arg) { ··· 76 105 .attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT, 77 106 .u.memref = { 78 107 .shm = shm, 79 - .size = len, 108 + .size = cmd_len, 80 109 .shm_offs = 0, 81 110 }, 82 111 }; ··· 88 117 return PTR_ERR(temp_buf); 89 118 } 90 119 memset(temp_buf, 0, (MAX_COMMAND_SIZE + MAX_RESPONSE_SIZE)); 91 - memcpy(temp_buf, buf, len); 120 + memcpy(temp_buf, buf, cmd_len); 92 121 93 122 command_params[1] = (struct tee_param) { 94 123 .attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT, ··· 129 158 __func__, resp_len); 130 159 return -EIO; 131 160 } 161 + if (resp_len > bufsiz) { 162 + dev_err(&chip->dev, 163 + "%s: resp_len=%zd exceeds bufsiz=%zd\n", 164 + __func__, resp_len, bufsiz); 165 + return -EIO; 166 + } 132 167 133 - /* sanity checks look good, cache the response */ 134 - memcpy(pvt_data->resp_buf, temp_buf, resp_len); 135 - pvt_data->resp_len = resp_len; 168 + memcpy(buf, temp_buf, resp_len); 136 169 137 - return 0; 170 + return resp_len; 138 171 } 139 172 140 173 static const struct tpm_class_ops ftpm_tee_tpm_ops = { 141 174 .flags = TPM_OPS_AUTO_STARTUP, 142 - .recv = ftpm_tee_tpm_op_recv, 143 175 .send = ftpm_tee_tpm_op_send, 144 176 }; 145 177 ··· 227 253 } 228 254 229 255 pvt_data->chip = chip; 230 - pvt_data->chip->flags |= TPM_CHIP_FLAG_TPM2; 256 + pvt_data->chip->flags |= TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_SYNC; 231 257 232 258 /* Create a character device for the fTPM */ 233 259 rc = tpm_chip_register(pvt_data->chip);
-4
drivers/char/tpm/tpm_ftpm_tee.h
··· 22 22 * struct ftpm_tee_private - fTPM's private data 23 23 * @chip: struct tpm_chip instance registered with tpm framework. 24 24 * @session: fTPM TA session identifier. 25 - * @resp_len: cached response buffer length. 26 - * @resp_buf: cached response buffer. 27 25 * @ctx: TEE context handler. 28 26 * @shm: Memory pool shared with fTPM TA in TEE. 29 27 */ 30 28 struct ftpm_tee_private { 31 29 struct tpm_chip *chip; 32 30 u32 session; 33 - size_t resp_len; 34 - u8 resp_buf[MAX_RESPONSE_SIZE]; 35 31 struct tee_context *ctx; 36 32 struct tee_shm *shm; 37 33 };