Skip to content

Commit 4d40b59

Browse files
committed
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
2 parents 283564a + 7f0c667 commit 4d40b59

24 files changed

Lines changed: 199 additions & 152 deletions

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7214,6 +7214,14 @@
72147214
causing a major performance hit, and the space where
72157215
machines are deployed is by other means guarded.
72167216

7217+
tpm_crb_ffa.busy_timeout_ms= [ARM64,TPM]
7218+
Maximum time in milliseconds to retry sending a message
7219+
to the TPM service before giving up. This parameter controls
7220+
how long the system will continue retrying when the TPM
7221+
service is busy.
7222+
Format: <unsigned int>
7223+
Default: 2000 (2 seconds)
7224+
72177225
tpm_suspend_pcr=[HW,TPM]
72187226
Format: integer pcr id
72197227
Specify that at suspend time, the tpm driver

drivers/char/tpm/eventlog/of.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,10 @@
2424

2525
static int tpm_read_log_memory_region(struct tpm_chip *chip)
2626
{
27-
struct device_node *node;
2827
struct resource res;
2928
int rc;
3029

31-
node = of_parse_phandle(chip->dev.parent->of_node, "memory-region", 0);
32-
if (!node)
33-
return -ENODEV;
34-
35-
rc = of_address_to_resource(node, 0, &res);
36-
of_node_put(node);
30+
rc = of_reserved_mem_region_to_resource(chip->dev.parent->of_node, 0, &res);
3731
if (rc)
3832
return rc;
3933

drivers/char/tpm/st33zp24/st33zp24.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
300300
* send TPM commands through the I2C bus.
301301
*/
302302
static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
303-
size_t len)
303+
size_t bufsiz, size_t len)
304304
{
305305
struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
306306
u32 status, i, size, ordinal;

drivers/char/tpm/tpm-interface.c

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ static bool tpm_chip_req_canceled(struct tpm_chip *chip, u8 status)
8282
return chip->ops->req_canceled(chip, status);
8383
}
8484

85+
static bool tpm_transmit_completed(u8 status, struct tpm_chip *chip)
86+
{
87+
u8 status_masked = status & chip->ops->req_complete_mask;
88+
89+
return status_masked == chip->ops->req_complete_val;
90+
}
91+
8592
static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz)
8693
{
8794
struct tpm_header *header = buf;
@@ -106,16 +113,27 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz)
106113
return -E2BIG;
107114
}
108115

109-
rc = chip->ops->send(chip, buf, count);
116+
rc = chip->ops->send(chip, buf, bufsiz, count);
110117
if (rc < 0) {
111118
if (rc != -EPIPE)
112119
dev_err(&chip->dev,
113120
"%s: send(): error %d\n", __func__, rc);
114121
return rc;
115122
}
116123

117-
/* A sanity check. send() should just return zero on success e.g.
118-
* not the command length.
124+
/*
125+
* Synchronous devices return the response directly during the send()
126+
* call in the same buffer.
127+
*/
128+
if (chip->flags & TPM_CHIP_FLAG_SYNC) {
129+
len = rc;
130+
rc = 0;
131+
goto out_sync;
132+
}
133+
134+
/*
135+
* A sanity check. send() of asynchronous devices should just return
136+
* zero on success e.g. not the command length.
119137
*/
120138
if (rc > 0) {
121139
dev_warn(&chip->dev,
@@ -129,8 +147,7 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz)
129147
stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
130148
do {
131149
u8 status = tpm_chip_status(chip);
132-
if ((status & chip->ops->req_complete_mask) ==
133-
chip->ops->req_complete_val)
150+
if (tpm_transmit_completed(status, chip))
134151
goto out_recv;
135152

136153
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)
142159
rmb();
143160
} while (time_before(jiffies, stop));
144161

162+
/*
163+
* Check for completion one more time, just in case the device reported
164+
* it while the driver was sleeping in the busy loop above.
165+
*/
166+
if (tpm_transmit_completed(tpm_chip_status(chip), chip))
167+
goto out_recv;
168+
145169
tpm_chip_cancel(chip);
146170
dev_err(&chip->dev, "Operation Timed out\n");
147171
return -ETIME;
@@ -151,7 +175,10 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz)
151175
if (len < 0) {
152176
rc = len;
153177
dev_err(&chip->dev, "tpm_transmit: tpm_recv: error %d\n", rc);
154-
} else if (len < TPM_HEADER_SIZE || len != be32_to_cpu(header->length))
178+
return rc;
179+
}
180+
out_sync:
181+
if (len < TPM_HEADER_SIZE || len != be32_to_cpu(header->length))
155182
rc = -EFAULT;
156183

157184
return rc ? rc : len;

drivers/char/tpm/tpm_atmel.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
148148
return size;
149149
}
150150

151-
static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
151+
static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
152+
size_t count)
152153
{
153154
struct tpm_atmel_priv *priv = dev_get_drvdata(&chip->dev);
154155
int i;

drivers/char/tpm/tpm_crb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ static int tpm_crb_smc_start(struct device *dev, unsigned long func_id)
426426
}
427427
#endif
428428

429-
static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len)
429+
static int crb_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz, size_t len)
430430
{
431431
struct crb_priv *priv = dev_get_drvdata(&chip->dev);
432432
int rc = 0;

drivers/char/tpm/tpm_crb_ffa.c

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,16 @@
1010
#define pr_fmt(fmt) "CRB_FFA: " fmt
1111

1212
#include <linux/arm_ffa.h>
13+
#include <linux/delay.h>
14+
#include <linux/moduleparam.h>
1315
#include "tpm_crb_ffa.h"
1416

17+
static unsigned int busy_timeout_ms = 2000;
18+
19+
module_param(busy_timeout_ms, uint, 0644);
20+
MODULE_PARM_DESC(busy_timeout_ms,
21+
"Maximum time in ms to retry before giving up on busy");
22+
1523
/* TPM service function status codes */
1624
#define CRB_FFA_OK 0x05000001
1725
#define CRB_FFA_OK_RESULTS_RETURNED 0x05000002
@@ -115,6 +123,7 @@ struct tpm_crb_ffa {
115123
};
116124

117125
static struct tpm_crb_ffa *tpm_crb_ffa;
126+
static struct ffa_driver tpm_crb_ffa_driver;
118127

119128
static int tpm_crb_ffa_to_linux_errno(int errno)
120129
{
@@ -168,57 +177,85 @@ static int tpm_crb_ffa_to_linux_errno(int errno)
168177
*/
169178
int tpm_crb_ffa_init(void)
170179
{
180+
int ret = 0;
181+
182+
if (!IS_MODULE(CONFIG_TCG_ARM_CRB_FFA)) {
183+
ret = ffa_register(&tpm_crb_ffa_driver);
184+
if (ret) {
185+
tpm_crb_ffa = ERR_PTR(-ENODEV);
186+
return ret;
187+
}
188+
}
189+
171190
if (!tpm_crb_ffa)
172-
return -ENOENT;
191+
ret = -ENOENT;
173192

174193
if (IS_ERR_VALUE(tpm_crb_ffa))
175-
return -ENODEV;
194+
ret = -ENODEV;
176195

177-
return 0;
196+
return ret;
178197
}
179198
EXPORT_SYMBOL_GPL(tpm_crb_ffa_init);
180199

181-
static int __tpm_crb_ffa_send_recieve(unsigned long func_id,
182-
unsigned long a0,
183-
unsigned long a1,
184-
unsigned long a2)
200+
static int __tpm_crb_ffa_try_send_receive(unsigned long func_id,
201+
unsigned long a0, unsigned long a1,
202+
unsigned long a2)
185203
{
186204
const struct ffa_msg_ops *msg_ops;
187205
int ret;
188206

189-
if (!tpm_crb_ffa)
190-
return -ENOENT;
191-
192207
msg_ops = tpm_crb_ffa->ffa_dev->ops->msg_ops;
193208

194209
if (ffa_partition_supports_direct_req2_recv(tpm_crb_ffa->ffa_dev)) {
195-
memset(&tpm_crb_ffa->direct_msg_data2, 0x00,
196-
sizeof(struct ffa_send_direct_data2));
197-
198-
tpm_crb_ffa->direct_msg_data2.data[0] = func_id;
199-
tpm_crb_ffa->direct_msg_data2.data[1] = a0;
200-
tpm_crb_ffa->direct_msg_data2.data[2] = a1;
201-
tpm_crb_ffa->direct_msg_data2.data[3] = a2;
210+
tpm_crb_ffa->direct_msg_data2 = (struct ffa_send_direct_data2){
211+
.data = { func_id, a0, a1, a2 },
212+
};
202213

203214
ret = msg_ops->sync_send_receive2(tpm_crb_ffa->ffa_dev,
204215
&tpm_crb_ffa->direct_msg_data2);
205216
if (!ret)
206217
ret = tpm_crb_ffa_to_linux_errno(tpm_crb_ffa->direct_msg_data2.data[0]);
207218
} else {
208-
memset(&tpm_crb_ffa->direct_msg_data, 0x00,
209-
sizeof(struct ffa_send_direct_data));
210-
211-
tpm_crb_ffa->direct_msg_data.data1 = func_id;
212-
tpm_crb_ffa->direct_msg_data.data2 = a0;
213-
tpm_crb_ffa->direct_msg_data.data3 = a1;
214-
tpm_crb_ffa->direct_msg_data.data4 = a2;
219+
tpm_crb_ffa->direct_msg_data = (struct ffa_send_direct_data){
220+
.data1 = func_id,
221+
.data2 = a0,
222+
.data3 = a1,
223+
.data4 = a2,
224+
};
215225

216226
ret = msg_ops->sync_send_receive(tpm_crb_ffa->ffa_dev,
217227
&tpm_crb_ffa->direct_msg_data);
218228
if (!ret)
219229
ret = tpm_crb_ffa_to_linux_errno(tpm_crb_ffa->direct_msg_data.data1);
220230
}
221231

232+
return ret;
233+
}
234+
235+
static int __tpm_crb_ffa_send_receive(unsigned long func_id, unsigned long a0,
236+
unsigned long a1, unsigned long a2)
237+
{
238+
ktime_t start, stop;
239+
int ret;
240+
241+
if (!tpm_crb_ffa)
242+
return -ENOENT;
243+
244+
start = ktime_get();
245+
stop = ktime_add(start, ms_to_ktime(busy_timeout_ms));
246+
247+
for (;;) {
248+
ret = __tpm_crb_ffa_try_send_receive(func_id, a0, a1, a2);
249+
if (ret != -EBUSY)
250+
break;
251+
252+
usleep_range(50, 100);
253+
if (ktime_after(ktime_get(), stop)) {
254+
dev_warn(&tpm_crb_ffa->ffa_dev->dev,
255+
"Busy retry timed out\n");
256+
break;
257+
}
258+
}
222259

223260
return ret;
224261
}
@@ -236,7 +273,7 @@ static int __tpm_crb_ffa_send_recieve(unsigned long func_id,
236273
*
237274
* Return: 0 on success, negative error code on failure.
238275
*/
239-
int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor)
276+
static int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor)
240277
{
241278
int rc;
242279

@@ -251,7 +288,7 @@ int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor)
251288

252289
guard(mutex)(&tpm_crb_ffa->msg_data_lock);
253290

254-
rc = __tpm_crb_ffa_send_recieve(CRB_FFA_GET_INTERFACE_VERSION, 0x00, 0x00, 0x00);
291+
rc = __tpm_crb_ffa_send_receive(CRB_FFA_GET_INTERFACE_VERSION, 0x00, 0x00, 0x00);
255292
if (!rc) {
256293
if (ffa_partition_supports_direct_req2_recv(tpm_crb_ffa->ffa_dev)) {
257294
*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)
264301

265302
return rc;
266303
}
267-
EXPORT_SYMBOL_GPL(tpm_crb_ffa_get_interface_version);
268304

269305
/**
270306
* 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)
289325

290326
guard(mutex)(&tpm_crb_ffa->msg_data_lock);
291327

292-
return __tpm_crb_ffa_send_recieve(CRB_FFA_START, request_type, locality, 0x00);
328+
return __tpm_crb_ffa_send_receive(CRB_FFA_START, request_type, locality, 0x00);
293329
}
294330
EXPORT_SYMBOL_GPL(tpm_crb_ffa_start);
295331

@@ -369,7 +405,9 @@ static struct ffa_driver tpm_crb_ffa_driver = {
369405
.id_table = tpm_crb_ffa_device_id,
370406
};
371407

408+
#ifdef MODULE
372409
module_ffa_driver(tpm_crb_ffa_driver);
410+
#endif
373411

374412
MODULE_AUTHOR("Arm");
375413
MODULE_DESCRIPTION("TPM CRB FFA driver");

drivers/char/tpm/tpm_crb_ffa.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@
1111

1212
#if IS_REACHABLE(CONFIG_TCG_ARM_CRB_FFA)
1313
int tpm_crb_ffa_init(void);
14-
int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor);
1514
int tpm_crb_ffa_start(int request_type, int locality);
1615
#else
1716
static inline int tpm_crb_ffa_init(void) { return 0; }
18-
static inline int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor) { return 0; }
1917
static inline int tpm_crb_ffa_start(int request_type, int locality) { return 0; }
2018
#endif
2119

0 commit comments

Comments
 (0)