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 callback
pull/1309/head
Linus Torvalds 2025-07-28 18:18:16 -07:00
commit 4d40b59d8b
24 changed files with 199 additions and 152 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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

View File

@ -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);

View File

@ -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;
};

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -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 };

View File

@ -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);

View File

@ -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;

View File

@ -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)
{

View File

@ -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)