Hi,
This PR has quite a few commits but nothing really that would be worth of spending too much time for, or would want to emphasize in particular. BR, Jarkko -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQRE6pSOnaBC00OEHEIaerohdGur0gUCaIAmHQAKCRAaerohdGur 0pBVAP94mutr2EyDyvJWpzej0fWROHzL1EkJacuKxmabt7HnJgEA9H8Ug6OoAdKq V1v+Z9iL1wrQ3Yfp28vHhdrAQUgDJgA= =cjP7 -----END PGP SIGNATURE----- Merge tag 'tpmdd-next-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd Pull tpm updates from Jarkko Sakkinen: "Quite a few commits but nothing really that would be worth of spending too much time for, or would want to emphasize in particular" * tag 'tpmdd-next-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: tpm_crb_ffa: handle tpm busy return code tpm_crb_ffa: Remove memset usage tpm_crb_ffa: Fix typos in function name tpm: Check for completion after timeout tpm: Use of_reserved_mem_region_to_resource() for "memory-region" tpm: Replace scnprintf() with sysfs_emit() and sysfs_emit_at() in sysfs show functions tpm_crb_ffa: Remove unused export tpm: tpm_crb_ffa: try to probe tpm_crb_ffa when it's built-in firmware: arm_ffa: Change initcall level of ffa_init() to rootfs_initcall tpm/tpm_svsm: support TPM_CHIP_FLAG_SYNC tpm/tpm_ftpm_tee: support TPM_CHIP_FLAG_SYNC tpm: support devices with synchronous send() tpm: add bufsiz parameter in the .send callbackpull/1309/head
commit
4d40b59d8b
|
|
@ -7214,6 +7214,14 @@
|
|||
causing a major performance hit, and the space where
|
||||
machines are deployed is by other means guarded.
|
||||
|
||||
tpm_crb_ffa.busy_timeout_ms= [ARM64,TPM]
|
||||
Maximum time in milliseconds to retry sending a message
|
||||
to the TPM service before giving up. This parameter controls
|
||||
how long the system will continue retrying when the TPM
|
||||
service is busy.
|
||||
Format: <unsigned int>
|
||||
Default: 2000 (2 seconds)
|
||||
|
||||
tpm_suspend_pcr=[HW,TPM]
|
||||
Format: integer pcr id
|
||||
Specify that at suspend time, the tpm driver
|
||||
|
|
|
|||
|
|
@ -24,16 +24,10 @@
|
|||
|
||||
static int tpm_read_log_memory_region(struct tpm_chip *chip)
|
||||
{
|
||||
struct device_node *node;
|
||||
struct resource res;
|
||||
int rc;
|
||||
|
||||
node = of_parse_phandle(chip->dev.parent->of_node, "memory-region", 0);
|
||||
if (!node)
|
||||
return -ENODEV;
|
||||
|
||||
rc = of_address_to_resource(node, 0, &res);
|
||||
of_node_put(node);
|
||||
rc = of_reserved_mem_region_to_resource(chip->dev.parent->of_node, 0, &res);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
|
|||
* send TPM commands through the I2C bus.
|
||||
*/
|
||||
static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
|
||||
size_t len)
|
||||
size_t bufsiz, size_t len)
|
||||
{
|
||||
struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
|
||||
u32 status, i, size, ordinal;
|
||||
|
|
|
|||
|
|
@ -82,6 +82,13 @@ static bool tpm_chip_req_canceled(struct tpm_chip *chip, u8 status)
|
|||
return chip->ops->req_canceled(chip, status);
|
||||
}
|
||||
|
||||
static bool tpm_transmit_completed(u8 status, struct tpm_chip *chip)
|
||||
{
|
||||
u8 status_masked = status & chip->ops->req_complete_mask;
|
||||
|
||||
return status_masked == chip->ops->req_complete_val;
|
||||
}
|
||||
|
||||
static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz)
|
||||
{
|
||||
struct tpm_header *header = buf;
|
||||
|
|
@ -106,7 +113,7 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz)
|
|||
return -E2BIG;
|
||||
}
|
||||
|
||||
rc = chip->ops->send(chip, buf, count);
|
||||
rc = chip->ops->send(chip, buf, bufsiz, count);
|
||||
if (rc < 0) {
|
||||
if (rc != -EPIPE)
|
||||
dev_err(&chip->dev,
|
||||
|
|
@ -114,8 +121,19 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* A sanity check. send() should just return zero on success e.g.
|
||||
* not the command length.
|
||||
/*
|
||||
* Synchronous devices return the response directly during the send()
|
||||
* call in the same buffer.
|
||||
*/
|
||||
if (chip->flags & TPM_CHIP_FLAG_SYNC) {
|
||||
len = rc;
|
||||
rc = 0;
|
||||
goto out_sync;
|
||||
}
|
||||
|
||||
/*
|
||||
* A sanity check. send() of asynchronous devices should just return
|
||||
* zero on success e.g. not the command length.
|
||||
*/
|
||||
if (rc > 0) {
|
||||
dev_warn(&chip->dev,
|
||||
|
|
@ -129,8 +147,7 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz)
|
|||
stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
|
||||
do {
|
||||
u8 status = tpm_chip_status(chip);
|
||||
if ((status & chip->ops->req_complete_mask) ==
|
||||
chip->ops->req_complete_val)
|
||||
if (tpm_transmit_completed(status, chip))
|
||||
goto out_recv;
|
||||
|
||||
if (tpm_chip_req_canceled(chip, status)) {
|
||||
|
|
@ -142,6 +159,13 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz)
|
|||
rmb();
|
||||
} while (time_before(jiffies, stop));
|
||||
|
||||
/*
|
||||
* Check for completion one more time, just in case the device reported
|
||||
* it while the driver was sleeping in the busy loop above.
|
||||
*/
|
||||
if (tpm_transmit_completed(tpm_chip_status(chip), chip))
|
||||
goto out_recv;
|
||||
|
||||
tpm_chip_cancel(chip);
|
||||
dev_err(&chip->dev, "Operation Timed out\n");
|
||||
return -ETIME;
|
||||
|
|
@ -151,7 +175,10 @@ out_recv:
|
|||
if (len < 0) {
|
||||
rc = len;
|
||||
dev_err(&chip->dev, "tpm_transmit: tpm_recv: error %d\n", rc);
|
||||
} else if (len < TPM_HEADER_SIZE || len != be32_to_cpu(header->length))
|
||||
return rc;
|
||||
}
|
||||
out_sync:
|
||||
if (len < TPM_HEADER_SIZE || len != be32_to_cpu(header->length))
|
||||
rc = -EFAULT;
|
||||
|
||||
return rc ? rc : len;
|
||||
|
|
|
|||
|
|
@ -148,7 +148,8 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
|||
return size;
|
||||
}
|
||||
|
||||
static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||
static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t count)
|
||||
{
|
||||
struct tpm_atmel_priv *priv = dev_get_drvdata(&chip->dev);
|
||||
int i;
|
||||
|
|
|
|||
|
|
@ -426,7 +426,7 @@ static int tpm_crb_smc_start(struct device *dev, unsigned long func_id)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len)
|
||||
static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
|
||||
{
|
||||
struct crb_priv *priv = dev_get_drvdata(&chip->dev);
|
||||
int rc = 0;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,16 @@
|
|||
#define pr_fmt(fmt) "CRB_FFA: " fmt
|
||||
|
||||
#include <linux/arm_ffa.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include "tpm_crb_ffa.h"
|
||||
|
||||
static unsigned int busy_timeout_ms = 2000;
|
||||
|
||||
module_param(busy_timeout_ms, uint, 0644);
|
||||
MODULE_PARM_DESC(busy_timeout_ms,
|
||||
"Maximum time in ms to retry before giving up on busy");
|
||||
|
||||
/* TPM service function status codes */
|
||||
#define CRB_FFA_OK 0x05000001
|
||||
#define CRB_FFA_OK_RESULTS_RETURNED 0x05000002
|
||||
|
|
@ -115,6 +123,7 @@ struct tpm_crb_ffa {
|
|||
};
|
||||
|
||||
static struct tpm_crb_ffa *tpm_crb_ffa;
|
||||
static struct ffa_driver tpm_crb_ffa_driver;
|
||||
|
||||
static int tpm_crb_ffa_to_linux_errno(int errno)
|
||||
{
|
||||
|
|
@ -168,50 +177,51 @@ static int tpm_crb_ffa_to_linux_errno(int errno)
|
|||
*/
|
||||
int tpm_crb_ffa_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!IS_MODULE(CONFIG_TCG_ARM_CRB_FFA)) {
|
||||
ret = ffa_register(&tpm_crb_ffa_driver);
|
||||
if (ret) {
|
||||
tpm_crb_ffa = ERR_PTR(-ENODEV);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tpm_crb_ffa)
|
||||
return -ENOENT;
|
||||
ret = -ENOENT;
|
||||
|
||||
if (IS_ERR_VALUE(tpm_crb_ffa))
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tpm_crb_ffa_init);
|
||||
|
||||
static int __tpm_crb_ffa_send_recieve(unsigned long func_id,
|
||||
unsigned long a0,
|
||||
unsigned long a1,
|
||||
unsigned long a2)
|
||||
static int __tpm_crb_ffa_try_send_receive(unsigned long func_id,
|
||||
unsigned long a0, unsigned long a1,
|
||||
unsigned long a2)
|
||||
{
|
||||
const struct ffa_msg_ops *msg_ops;
|
||||
int ret;
|
||||
|
||||
if (!tpm_crb_ffa)
|
||||
return -ENOENT;
|
||||
|
||||
msg_ops = tpm_crb_ffa->ffa_dev->ops->msg_ops;
|
||||
|
||||
if (ffa_partition_supports_direct_req2_recv(tpm_crb_ffa->ffa_dev)) {
|
||||
memset(&tpm_crb_ffa->direct_msg_data2, 0x00,
|
||||
sizeof(struct ffa_send_direct_data2));
|
||||
|
||||
tpm_crb_ffa->direct_msg_data2.data[0] = func_id;
|
||||
tpm_crb_ffa->direct_msg_data2.data[1] = a0;
|
||||
tpm_crb_ffa->direct_msg_data2.data[2] = a1;
|
||||
tpm_crb_ffa->direct_msg_data2.data[3] = a2;
|
||||
tpm_crb_ffa->direct_msg_data2 = (struct ffa_send_direct_data2){
|
||||
.data = { func_id, a0, a1, a2 },
|
||||
};
|
||||
|
||||
ret = msg_ops->sync_send_receive2(tpm_crb_ffa->ffa_dev,
|
||||
&tpm_crb_ffa->direct_msg_data2);
|
||||
if (!ret)
|
||||
ret = tpm_crb_ffa_to_linux_errno(tpm_crb_ffa->direct_msg_data2.data[0]);
|
||||
} else {
|
||||
memset(&tpm_crb_ffa->direct_msg_data, 0x00,
|
||||
sizeof(struct ffa_send_direct_data));
|
||||
|
||||
tpm_crb_ffa->direct_msg_data.data1 = func_id;
|
||||
tpm_crb_ffa->direct_msg_data.data2 = a0;
|
||||
tpm_crb_ffa->direct_msg_data.data3 = a1;
|
||||
tpm_crb_ffa->direct_msg_data.data4 = a2;
|
||||
tpm_crb_ffa->direct_msg_data = (struct ffa_send_direct_data){
|
||||
.data1 = func_id,
|
||||
.data2 = a0,
|
||||
.data3 = a1,
|
||||
.data4 = a2,
|
||||
};
|
||||
|
||||
ret = msg_ops->sync_send_receive(tpm_crb_ffa->ffa_dev,
|
||||
&tpm_crb_ffa->direct_msg_data);
|
||||
|
|
@ -219,6 +229,33 @@ static int __tpm_crb_ffa_send_recieve(unsigned long func_id,
|
|||
ret = tpm_crb_ffa_to_linux_errno(tpm_crb_ffa->direct_msg_data.data1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __tpm_crb_ffa_send_receive(unsigned long func_id, unsigned long a0,
|
||||
unsigned long a1, unsigned long a2)
|
||||
{
|
||||
ktime_t start, stop;
|
||||
int ret;
|
||||
|
||||
if (!tpm_crb_ffa)
|
||||
return -ENOENT;
|
||||
|
||||
start = ktime_get();
|
||||
stop = ktime_add(start, ms_to_ktime(busy_timeout_ms));
|
||||
|
||||
for (;;) {
|
||||
ret = __tpm_crb_ffa_try_send_receive(func_id, a0, a1, a2);
|
||||
if (ret != -EBUSY)
|
||||
break;
|
||||
|
||||
usleep_range(50, 100);
|
||||
if (ktime_after(ktime_get(), stop)) {
|
||||
dev_warn(&tpm_crb_ffa->ffa_dev->dev,
|
||||
"Busy retry timed out\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -236,7 +273,7 @@ static int __tpm_crb_ffa_send_recieve(unsigned long func_id,
|
|||
*
|
||||
* Return: 0 on success, negative error code on failure.
|
||||
*/
|
||||
int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor)
|
||||
static int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor)
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
|
@ -251,7 +288,7 @@ int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor)
|
|||
|
||||
guard(mutex)(&tpm_crb_ffa->msg_data_lock);
|
||||
|
||||
rc = __tpm_crb_ffa_send_recieve(CRB_FFA_GET_INTERFACE_VERSION, 0x00, 0x00, 0x00);
|
||||
rc = __tpm_crb_ffa_send_receive(CRB_FFA_GET_INTERFACE_VERSION, 0x00, 0x00, 0x00);
|
||||
if (!rc) {
|
||||
if (ffa_partition_supports_direct_req2_recv(tpm_crb_ffa->ffa_dev)) {
|
||||
*major = CRB_FFA_MAJOR_VERSION(tpm_crb_ffa->direct_msg_data2.data[1]);
|
||||
|
|
@ -264,7 +301,6 @@ int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor)
|
|||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tpm_crb_ffa_get_interface_version);
|
||||
|
||||
/**
|
||||
* tpm_crb_ffa_start() - signals the TPM that a field has changed in the CRB
|
||||
|
|
@ -289,7 +325,7 @@ int tpm_crb_ffa_start(int request_type, int locality)
|
|||
|
||||
guard(mutex)(&tpm_crb_ffa->msg_data_lock);
|
||||
|
||||
return __tpm_crb_ffa_send_recieve(CRB_FFA_START, request_type, locality, 0x00);
|
||||
return __tpm_crb_ffa_send_receive(CRB_FFA_START, request_type, locality, 0x00);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tpm_crb_ffa_start);
|
||||
|
||||
|
|
@ -369,7 +405,9 @@ static struct ffa_driver tpm_crb_ffa_driver = {
|
|||
.id_table = tpm_crb_ffa_device_id,
|
||||
};
|
||||
|
||||
#ifdef MODULE
|
||||
module_ffa_driver(tpm_crb_ffa_driver);
|
||||
#endif
|
||||
|
||||
MODULE_AUTHOR("Arm");
|
||||
MODULE_DESCRIPTION("TPM CRB FFA driver");
|
||||
|
|
|
|||
|
|
@ -11,11 +11,9 @@
|
|||
|
||||
#if IS_REACHABLE(CONFIG_TCG_ARM_CRB_FFA)
|
||||
int tpm_crb_ffa_init(void);
|
||||
int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor);
|
||||
int tpm_crb_ffa_start(int request_type, int locality);
|
||||
#else
|
||||
static inline int tpm_crb_ffa_init(void) { return 0; }
|
||||
static inline int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor) { return 0; }
|
||||
static inline int tpm_crb_ffa_start(int request_type, int locality) { return 0; }
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -31,45 +31,19 @@ static const uuid_t ftpm_ta_uuid =
|
|||
0x82, 0xCB, 0x34, 0x3F, 0xB7, 0xF3, 0x78, 0x96);
|
||||
|
||||
/**
|
||||
* ftpm_tee_tpm_op_recv() - retrieve fTPM response.
|
||||
* @chip: the tpm_chip description as specified in driver/char/tpm/tpm.h.
|
||||
* @buf: the buffer to store data.
|
||||
* @count: the number of bytes to read.
|
||||
*
|
||||
* Return:
|
||||
* In case of success the number of bytes received.
|
||||
* On failure, -errno.
|
||||
*/
|
||||
static int ftpm_tee_tpm_op_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||
{
|
||||
struct ftpm_tee_private *pvt_data = dev_get_drvdata(chip->dev.parent);
|
||||
size_t len;
|
||||
|
||||
len = pvt_data->resp_len;
|
||||
if (count < len) {
|
||||
dev_err(&chip->dev,
|
||||
"%s: Invalid size in recv: count=%zd, resp_len=%zd\n",
|
||||
__func__, count, len);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
memcpy(buf, pvt_data->resp_buf, len);
|
||||
pvt_data->resp_len = 0;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* ftpm_tee_tpm_op_send() - send TPM commands through the TEE shared memory.
|
||||
* ftpm_tee_tpm_op_send() - send TPM commands through the TEE shared memory
|
||||
* and retrieve the response.
|
||||
* @chip: the tpm_chip description as specified in driver/char/tpm/tpm.h
|
||||
* @buf: the buffer to send.
|
||||
* @len: the number of bytes to send.
|
||||
* @buf: the buffer to send and to store the response.
|
||||
* @bufsiz: the size of the buffer.
|
||||
* @cmd_len: the number of bytes to send.
|
||||
*
|
||||
* Return:
|
||||
* In case of success, returns 0.
|
||||
* In case of success, returns the number of bytes received.
|
||||
* On failure, -errno
|
||||
*/
|
||||
static int ftpm_tee_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t len)
|
||||
static int ftpm_tee_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t cmd_len)
|
||||
{
|
||||
struct ftpm_tee_private *pvt_data = dev_get_drvdata(chip->dev.parent);
|
||||
size_t resp_len;
|
||||
|
|
@ -80,16 +54,15 @@ static int ftpm_tee_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t len)
|
|||
struct tee_param command_params[4];
|
||||
struct tee_shm *shm = pvt_data->shm;
|
||||
|
||||
if (len > MAX_COMMAND_SIZE) {
|
||||
if (cmd_len > MAX_COMMAND_SIZE) {
|
||||
dev_err(&chip->dev,
|
||||
"%s: len=%zd exceeds MAX_COMMAND_SIZE supported by fTPM TA\n",
|
||||
__func__, len);
|
||||
__func__, cmd_len);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
memset(&transceive_args, 0, sizeof(transceive_args));
|
||||
memset(command_params, 0, sizeof(command_params));
|
||||
pvt_data->resp_len = 0;
|
||||
|
||||
/* Invoke FTPM_OPTEE_TA_SUBMIT_COMMAND function of fTPM TA */
|
||||
transceive_args = (struct tee_ioctl_invoke_arg) {
|
||||
|
|
@ -103,7 +76,7 @@ static int ftpm_tee_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t len)
|
|||
.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT,
|
||||
.u.memref = {
|
||||
.shm = shm,
|
||||
.size = len,
|
||||
.size = cmd_len,
|
||||
.shm_offs = 0,
|
||||
},
|
||||
};
|
||||
|
|
@ -115,7 +88,7 @@ static int ftpm_tee_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t len)
|
|||
return PTR_ERR(temp_buf);
|
||||
}
|
||||
memset(temp_buf, 0, (MAX_COMMAND_SIZE + MAX_RESPONSE_SIZE));
|
||||
memcpy(temp_buf, buf, len);
|
||||
memcpy(temp_buf, buf, cmd_len);
|
||||
|
||||
command_params[1] = (struct tee_param) {
|
||||
.attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT,
|
||||
|
|
@ -156,17 +129,20 @@ static int ftpm_tee_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t len)
|
|||
__func__, resp_len);
|
||||
return -EIO;
|
||||
}
|
||||
if (resp_len > bufsiz) {
|
||||
dev_err(&chip->dev,
|
||||
"%s: resp_len=%zd exceeds bufsiz=%zd\n",
|
||||
__func__, resp_len, bufsiz);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* sanity checks look good, cache the response */
|
||||
memcpy(pvt_data->resp_buf, temp_buf, resp_len);
|
||||
pvt_data->resp_len = resp_len;
|
||||
memcpy(buf, temp_buf, resp_len);
|
||||
|
||||
return 0;
|
||||
return resp_len;
|
||||
}
|
||||
|
||||
static const struct tpm_class_ops ftpm_tee_tpm_ops = {
|
||||
.flags = TPM_OPS_AUTO_STARTUP,
|
||||
.recv = ftpm_tee_tpm_op_recv,
|
||||
.send = ftpm_tee_tpm_op_send,
|
||||
};
|
||||
|
||||
|
|
@ -251,7 +227,7 @@ static int ftpm_tee_probe(struct device *dev)
|
|||
}
|
||||
|
||||
pvt_data->chip = chip;
|
||||
pvt_data->chip->flags |= TPM_CHIP_FLAG_TPM2;
|
||||
pvt_data->chip->flags |= TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_SYNC;
|
||||
|
||||
/* Create a character device for the fTPM */
|
||||
rc = tpm_chip_register(pvt_data->chip);
|
||||
|
|
|
|||
|
|
@ -22,16 +22,12 @@
|
|||
* struct ftpm_tee_private - fTPM's private data
|
||||
* @chip: struct tpm_chip instance registered with tpm framework.
|
||||
* @session: fTPM TA session identifier.
|
||||
* @resp_len: cached response buffer length.
|
||||
* @resp_buf: cached response buffer.
|
||||
* @ctx: TEE context handler.
|
||||
* @shm: Memory pool shared with fTPM TA in TEE.
|
||||
*/
|
||||
struct ftpm_tee_private {
|
||||
struct tpm_chip *chip;
|
||||
u32 session;
|
||||
size_t resp_len;
|
||||
u8 resp_buf[MAX_RESPONSE_SIZE];
|
||||
struct tee_context *ctx;
|
||||
struct tee_shm *shm;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ struct priv_data {
|
|||
u8 buffer[sizeof(struct tpm_header) + 25];
|
||||
};
|
||||
|
||||
static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t len)
|
||||
static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t len)
|
||||
{
|
||||
struct priv_data *priv = dev_get_drvdata(&chip->dev);
|
||||
struct i2c_client *client = to_i2c_client(chip->dev.parent);
|
||||
|
|
|
|||
|
|
@ -514,7 +514,8 @@ out:
|
|||
return size;
|
||||
}
|
||||
|
||||
static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
|
||||
static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t len)
|
||||
{
|
||||
int rc, status;
|
||||
ssize_t burstcnt;
|
||||
|
|
|
|||
|
|
@ -350,7 +350,8 @@ static int i2c_nuvoton_recv(struct tpm_chip *chip, u8 *buf, size_t count)
|
|||
* tpm.c can skip polling for the data to be available as the interrupt is
|
||||
* waited for here
|
||||
*/
|
||||
static int i2c_nuvoton_send(struct tpm_chip *chip, u8 *buf, size_t len)
|
||||
static int i2c_nuvoton_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t len)
|
||||
{
|
||||
struct priv_data *priv = dev_get_drvdata(&chip->dev);
|
||||
struct device *dev = chip->dev.parent;
|
||||
|
|
|
|||
|
|
@ -191,13 +191,15 @@ static int tpm_ibmvtpm_resume(struct device *dev)
|
|||
* tpm_ibmvtpm_send() - Send a TPM command
|
||||
* @chip: tpm chip struct
|
||||
* @buf: buffer contains data to send
|
||||
* @count: size of buffer
|
||||
* @bufsiz: size of the buffer
|
||||
* @count: length of the command
|
||||
*
|
||||
* Return:
|
||||
* 0 on success,
|
||||
* -errno on error
|
||||
*/
|
||||
static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||
static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t count)
|
||||
{
|
||||
struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
|
||||
bool retry = true;
|
||||
|
|
|
|||
|
|
@ -312,7 +312,8 @@ recv_begin:
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
|
||||
static int tpm_inf_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t count)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -178,7 +178,8 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
|
|||
return size;
|
||||
}
|
||||
|
||||
static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
|
||||
static int tpm_nsc_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t count)
|
||||
{
|
||||
struct tpm_nsc_priv *priv = dev_get_drvdata(&chip->dev);
|
||||
u8 data;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ static ssize_t tpm_show_ppi_version(struct device *dev,
|
|||
{
|
||||
struct tpm_chip *chip = to_tpm_chip(dev);
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%s\n", chip->ppi_version);
|
||||
return sysfs_emit(buf, "%s\n", chip->ppi_version);
|
||||
}
|
||||
|
||||
static ssize_t tpm_show_ppi_request(struct device *dev,
|
||||
|
|
@ -87,12 +87,10 @@ static ssize_t tpm_show_ppi_request(struct device *dev,
|
|||
else {
|
||||
req = obj->package.elements[1].integer.value;
|
||||
if (tpm_ppi_req_has_parameter(req))
|
||||
size = scnprintf(buf, PAGE_SIZE,
|
||||
"%llu %llu\n", req,
|
||||
obj->package.elements[2].integer.value);
|
||||
size = sysfs_emit(buf, "%llu %llu\n", req,
|
||||
obj->package.elements[2].integer.value);
|
||||
else
|
||||
size = scnprintf(buf, PAGE_SIZE,
|
||||
"%llu\n", req);
|
||||
size = sysfs_emit(buf, "%llu\n", req);
|
||||
}
|
||||
} else if (obj->package.count == 2 &&
|
||||
obj->package.elements[0].type == ACPI_TYPE_INTEGER &&
|
||||
|
|
@ -100,8 +98,8 @@ static ssize_t tpm_show_ppi_request(struct device *dev,
|
|||
if (obj->package.elements[0].integer.value)
|
||||
size = -EFAULT;
|
||||
else
|
||||
size = scnprintf(buf, PAGE_SIZE, "%llu\n",
|
||||
obj->package.elements[1].integer.value);
|
||||
size = sysfs_emit(buf, "%llu\n",
|
||||
obj->package.elements[1].integer.value);
|
||||
}
|
||||
|
||||
ACPI_FREE(obj);
|
||||
|
|
@ -211,10 +209,10 @@ static ssize_t tpm_show_ppi_transition_action(struct device *dev,
|
|||
}
|
||||
|
||||
if (ret < ARRAY_SIZE(info) - 1)
|
||||
status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret, info[ret]);
|
||||
status = sysfs_emit(buf, "%d: %s\n", ret, info[ret]);
|
||||
else
|
||||
status = scnprintf(buf, PAGE_SIZE, "%d: %s\n", ret,
|
||||
info[ARRAY_SIZE(info)-1]);
|
||||
status = sysfs_emit(buf, "%d: %s\n", ret,
|
||||
info[ARRAY_SIZE(info) - 1]);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -255,23 +253,23 @@ static ssize_t tpm_show_ppi_response(struct device *dev,
|
|||
res = ret_obj[2].integer.value;
|
||||
if (req) {
|
||||
if (res == 0)
|
||||
status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req,
|
||||
"0: Success");
|
||||
status = sysfs_emit(buf, "%llu %s\n", req,
|
||||
"0: Success");
|
||||
else if (res == 0xFFFFFFF0)
|
||||
status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req,
|
||||
"0xFFFFFFF0: User Abort");
|
||||
status = sysfs_emit(buf, "%llu %s\n", req,
|
||||
"0xFFFFFFF0: User Abort");
|
||||
else if (res == 0xFFFFFFF1)
|
||||
status = scnprintf(buf, PAGE_SIZE, "%llu %s\n", req,
|
||||
"0xFFFFFFF1: BIOS Failure");
|
||||
status = sysfs_emit(buf, "%llu %s\n", req,
|
||||
"0xFFFFFFF1: BIOS Failure");
|
||||
else if (res >= 1 && res <= 0x00000FFF)
|
||||
status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n",
|
||||
req, res, "Corresponding TPM error");
|
||||
status = sysfs_emit(buf, "%llu %llu: %s\n",
|
||||
req, res, "Corresponding TPM error");
|
||||
else
|
||||
status = scnprintf(buf, PAGE_SIZE, "%llu %llu: %s\n",
|
||||
req, res, "Error");
|
||||
status = sysfs_emit(buf, "%llu %llu: %s\n",
|
||||
req, res, "Error");
|
||||
} else {
|
||||
status = scnprintf(buf, PAGE_SIZE, "%llu: %s\n",
|
||||
req, "No Recent Request");
|
||||
status = sysfs_emit(buf, "%llu: %s\n",
|
||||
req, "No Recent Request");
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
|
@ -284,7 +282,7 @@ static ssize_t show_ppi_operations(acpi_handle dev_handle, char *buf, u32 start,
|
|||
{
|
||||
int i;
|
||||
u32 ret;
|
||||
char *str = buf;
|
||||
int len = 0;
|
||||
union acpi_object *obj, tmp;
|
||||
union acpi_object argv = ACPI_INIT_DSM_ARGV4(1, &tmp);
|
||||
|
||||
|
|
@ -314,11 +312,11 @@ static ssize_t show_ppi_operations(acpi_handle dev_handle, char *buf, u32 start,
|
|||
}
|
||||
|
||||
if (ret > 0 && ret < ARRAY_SIZE(info))
|
||||
str += scnprintf(str, PAGE_SIZE, "%d %d: %s\n",
|
||||
i, ret, info[ret]);
|
||||
len += sysfs_emit_at(buf, len, "%d %d: %s\n",
|
||||
i, ret, info[ret]);
|
||||
}
|
||||
|
||||
return str - buf;
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t tpm_show_ppi_tcg_operations(struct device *dev,
|
||||
|
|
|
|||
|
|
@ -25,37 +25,32 @@ struct tpm_svsm_priv {
|
|||
void *buffer;
|
||||
};
|
||||
|
||||
static int tpm_svsm_send(struct tpm_chip *chip, u8 *buf, size_t len)
|
||||
static int tpm_svsm_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t cmd_len)
|
||||
{
|
||||
struct tpm_svsm_priv *priv = dev_get_drvdata(&chip->dev);
|
||||
int ret;
|
||||
|
||||
ret = svsm_vtpm_cmd_request_fill(priv->buffer, 0, buf, len);
|
||||
ret = svsm_vtpm_cmd_request_fill(priv->buffer, 0, buf, cmd_len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* The SVSM call uses the same buffer for the command and for the
|
||||
* response, so after this call, the buffer will contain the response
|
||||
* that can be used by .recv() op.
|
||||
* response, so after this call, the buffer will contain the response.
|
||||
*
|
||||
* Note: we have to use an internal buffer because the device in SVSM
|
||||
* expects the svsm_vtpm header + data to be physically contiguous.
|
||||
*/
|
||||
return snp_svsm_vtpm_send_command(priv->buffer);
|
||||
}
|
||||
ret = snp_svsm_vtpm_send_command(priv->buffer);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
static int tpm_svsm_recv(struct tpm_chip *chip, u8 *buf, size_t len)
|
||||
{
|
||||
struct tpm_svsm_priv *priv = dev_get_drvdata(&chip->dev);
|
||||
|
||||
/*
|
||||
* The internal buffer contains the response after we send the command
|
||||
* to SVSM.
|
||||
*/
|
||||
return svsm_vtpm_cmd_response_parse(priv->buffer, buf, len);
|
||||
return svsm_vtpm_cmd_response_parse(priv->buffer, buf, bufsiz);
|
||||
}
|
||||
|
||||
static struct tpm_class_ops tpm_chip_ops = {
|
||||
.flags = TPM_OPS_AUTO_STARTUP,
|
||||
.recv = tpm_svsm_recv,
|
||||
.send = tpm_svsm_send,
|
||||
};
|
||||
|
||||
|
|
@ -84,6 +79,7 @@ static int __init tpm_svsm_probe(struct platform_device *pdev)
|
|||
|
||||
dev_set_drvdata(&chip->dev, priv);
|
||||
|
||||
chip->flags |= TPM_CHIP_FLAG_SYNC;
|
||||
err = tpm2_probe(chip);
|
||||
if (err)
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -580,7 +580,8 @@ out_err:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
|
||||
static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t len)
|
||||
{
|
||||
int rc, irq;
|
||||
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
|
||||
|
|
|
|||
|
|
@ -546,13 +546,15 @@ out_err:
|
|||
* tpm_cr50_i2c_tis_send() - TPM transmission callback.
|
||||
* @chip: A TPM chip.
|
||||
* @buf: Buffer to send.
|
||||
* @len: Buffer length.
|
||||
* @bufsiz: Buffer size.
|
||||
* @len: Command length.
|
||||
*
|
||||
* Return:
|
||||
* - 0: Success.
|
||||
* - -errno: A POSIX error code.
|
||||
*/
|
||||
static int tpm_cr50_i2c_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
|
||||
static int tpm_cr50_i2c_tis_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t len)
|
||||
{
|
||||
size_t burstcnt, limit, sent = 0;
|
||||
u8 tpm_go[4] = { TPM_STS_GO };
|
||||
|
|
|
|||
|
|
@ -321,12 +321,14 @@ static int vtpm_proxy_is_driver_command(struct tpm_chip *chip,
|
|||
*
|
||||
* @chip: tpm chip to use
|
||||
* @buf: send buffer
|
||||
* @bufsiz: size of the buffer
|
||||
* @count: bytes to send
|
||||
*
|
||||
* Return:
|
||||
* 0 in case of success, negative error value otherwise.
|
||||
*/
|
||||
static int vtpm_proxy_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||
static int vtpm_proxy_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t count)
|
||||
{
|
||||
struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
|
||||
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@ static size_t shr_data_offset(struct vtpm_shared_page *shr)
|
|||
return struct_size(shr, extra_pages, shr->nr_extra_pages);
|
||||
}
|
||||
|
||||
static int vtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||
static int vtpm_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t count)
|
||||
{
|
||||
struct tpm_private *priv = dev_get_drvdata(&chip->dev);
|
||||
struct vtpm_shared_page *shr = priv->shr;
|
||||
|
|
|
|||
|
|
@ -2059,7 +2059,7 @@ free_drv_info:
|
|||
kfree(drv_info);
|
||||
return ret;
|
||||
}
|
||||
module_init(ffa_init);
|
||||
rootfs_initcall(ffa_init);
|
||||
|
||||
static void __exit ffa_exit(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -87,7 +87,8 @@ struct tpm_class_ops {
|
|||
const u8 req_complete_val;
|
||||
bool (*req_canceled)(struct tpm_chip *chip, u8 status);
|
||||
int (*recv) (struct tpm_chip *chip, u8 *buf, size_t len);
|
||||
int (*send) (struct tpm_chip *chip, u8 *buf, size_t len);
|
||||
int (*send)(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
|
||||
size_t cmd_len);
|
||||
void (*cancel) (struct tpm_chip *chip);
|
||||
u8 (*status) (struct tpm_chip *chip);
|
||||
void (*update_timeouts)(struct tpm_chip *chip,
|
||||
|
|
@ -350,6 +351,7 @@ enum tpm_chip_flags {
|
|||
TPM_CHIP_FLAG_SUSPENDED = BIT(8),
|
||||
TPM_CHIP_FLAG_HWRNG_DISABLED = BIT(9),
|
||||
TPM_CHIP_FLAG_DISABLE = BIT(10),
|
||||
TPM_CHIP_FLAG_SYNC = BIT(11),
|
||||
};
|
||||
|
||||
#define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
|
||||
|
|
|
|||
Loading…
Reference in New Issue