Skip to content

Commit b61f7ff

Browse files
committed
Merge tag 'tpmdd-next-20200421' of git://git.infradead.org/users/jjs/linux-tpmdd
Pull tpm fixes from Jarkko Sakkinen: "A few bug fixes" * tag 'tpmdd-next-20200421' of git://git.infradead.org/users/jjs/linux-tpmdd: tpm/tpm_tis: Free IRQ if probing fails tpm: fix wrong return value in tpm_pcr_extend tpm: ibmvtpm: retry on H_CLOSED in tpm_ibmvtpm_send() tpm: Export tpm2_get_cc_attrs_tbl for ibmvtpm driver as module
2 parents 20f1648 + b160c94 commit b61f7ff

File tree

4 files changed

+82
-65
lines changed

4 files changed

+82
-65
lines changed

drivers/char/tpm/tpm-interface.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
323323

324324
for (i = 0; i < chip->nr_allocated_banks; i++) {
325325
if (digests[i].alg_id != chip->allocated_banks[i].alg_id) {
326-
rc = EINVAL;
326+
rc = -EINVAL;
327327
goto out;
328328
}
329329
}

drivers/char/tpm/tpm2-cmd.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,7 @@ int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip)
681681
rc = -ENODEV;
682682
return rc;
683683
}
684+
EXPORT_SYMBOL_GPL(tpm2_get_cc_attrs_tbl);
684685

685686
/**
686687
* tpm2_startup - turn on the TPM

drivers/char/tpm/tpm_ibmvtpm.c

Lines changed: 73 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: GPL-2.0-only
22
/*
3-
* Copyright (C) 2012 IBM Corporation
3+
* Copyright (C) 2012-2020 IBM Corporation
44
*
55
* Author: Ashley Lai <[email protected]>
66
*
@@ -134,6 +134,64 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
134134
return len;
135135
}
136136

137+
/**
138+
* ibmvtpm_crq_send_init - Send a CRQ initialize message
139+
* @ibmvtpm: vtpm device struct
140+
*
141+
* Return:
142+
* 0 on success.
143+
* Non-zero on failure.
144+
*/
145+
static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm)
146+
{
147+
int rc;
148+
149+
rc = ibmvtpm_send_crq_word(ibmvtpm->vdev, INIT_CRQ_CMD);
150+
if (rc != H_SUCCESS)
151+
dev_err(ibmvtpm->dev,
152+
"%s failed rc=%d\n", __func__, rc);
153+
154+
return rc;
155+
}
156+
157+
/**
158+
* tpm_ibmvtpm_resume - Resume from suspend
159+
*
160+
* @dev: device struct
161+
*
162+
* Return: Always 0.
163+
*/
164+
static int tpm_ibmvtpm_resume(struct device *dev)
165+
{
166+
struct tpm_chip *chip = dev_get_drvdata(dev);
167+
struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
168+
int rc = 0;
169+
170+
do {
171+
if (rc)
172+
msleep(100);
173+
rc = plpar_hcall_norets(H_ENABLE_CRQ,
174+
ibmvtpm->vdev->unit_address);
175+
} while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc));
176+
177+
if (rc) {
178+
dev_err(dev, "Error enabling ibmvtpm rc=%d\n", rc);
179+
return rc;
180+
}
181+
182+
rc = vio_enable_interrupts(ibmvtpm->vdev);
183+
if (rc) {
184+
dev_err(dev, "Error vio_enable_interrupts rc=%d\n", rc);
185+
return rc;
186+
}
187+
188+
rc = ibmvtpm_crq_send_init(ibmvtpm);
189+
if (rc)
190+
dev_err(dev, "Error send_init rc=%d\n", rc);
191+
192+
return rc;
193+
}
194+
137195
/**
138196
* tpm_ibmvtpm_send() - Send a TPM command
139197
* @chip: tpm chip struct
@@ -147,6 +205,7 @@ static int tpm_ibmvtpm_recv(struct tpm_chip *chip, u8 *buf, size_t count)
147205
static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
148206
{
149207
struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
208+
bool retry = true;
150209
int rc, sig;
151210

152211
if (!ibmvtpm->rtce_buf) {
@@ -180,18 +239,27 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count)
180239
*/
181240
ibmvtpm->tpm_processing_cmd = true;
182241

242+
again:
183243
rc = ibmvtpm_send_crq(ibmvtpm->vdev,
184244
IBMVTPM_VALID_CMD, VTPM_TPM_COMMAND,
185245
count, ibmvtpm->rtce_dma_handle);
186246
if (rc != H_SUCCESS) {
247+
/*
248+
* H_CLOSED can be returned after LPM resume. Call
249+
* tpm_ibmvtpm_resume() to re-enable the CRQ then retry
250+
* ibmvtpm_send_crq() once before failing.
251+
*/
252+
if (rc == H_CLOSED && retry) {
253+
tpm_ibmvtpm_resume(ibmvtpm->dev);
254+
retry = false;
255+
goto again;
256+
}
187257
dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc);
188-
rc = 0;
189258
ibmvtpm->tpm_processing_cmd = false;
190-
} else
191-
rc = 0;
259+
}
192260

193261
spin_unlock(&ibmvtpm->rtce_lock);
194-
return rc;
262+
return 0;
195263
}
196264

197265
static void tpm_ibmvtpm_cancel(struct tpm_chip *chip)
@@ -269,26 +337,6 @@ static int ibmvtpm_crq_send_init_complete(struct ibmvtpm_dev *ibmvtpm)
269337
return rc;
270338
}
271339

272-
/**
273-
* ibmvtpm_crq_send_init - Send a CRQ initialize message
274-
* @ibmvtpm: vtpm device struct
275-
*
276-
* Return:
277-
* 0 on success.
278-
* Non-zero on failure.
279-
*/
280-
static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm)
281-
{
282-
int rc;
283-
284-
rc = ibmvtpm_send_crq_word(ibmvtpm->vdev, INIT_CRQ_CMD);
285-
if (rc != H_SUCCESS)
286-
dev_err(ibmvtpm->dev,
287-
"ibmvtpm_crq_send_init failed rc=%d\n", rc);
288-
289-
return rc;
290-
}
291-
292340
/**
293341
* tpm_ibmvtpm_remove - ibm vtpm remove entry point
294342
* @vdev: vio device struct
@@ -401,44 +449,6 @@ static int ibmvtpm_reset_crq(struct ibmvtpm_dev *ibmvtpm)
401449
ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE);
402450
}
403451

404-
/**
405-
* tpm_ibmvtpm_resume - Resume from suspend
406-
*
407-
* @dev: device struct
408-
*
409-
* Return: Always 0.
410-
*/
411-
static int tpm_ibmvtpm_resume(struct device *dev)
412-
{
413-
struct tpm_chip *chip = dev_get_drvdata(dev);
414-
struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev);
415-
int rc = 0;
416-
417-
do {
418-
if (rc)
419-
msleep(100);
420-
rc = plpar_hcall_norets(H_ENABLE_CRQ,
421-
ibmvtpm->vdev->unit_address);
422-
} while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc));
423-
424-
if (rc) {
425-
dev_err(dev, "Error enabling ibmvtpm rc=%d\n", rc);
426-
return rc;
427-
}
428-
429-
rc = vio_enable_interrupts(ibmvtpm->vdev);
430-
if (rc) {
431-
dev_err(dev, "Error vio_enable_interrupts rc=%d\n", rc);
432-
return rc;
433-
}
434-
435-
rc = ibmvtpm_crq_send_init(ibmvtpm);
436-
if (rc)
437-
dev_err(dev, "Error send_init rc=%d\n", rc);
438-
439-
return rc;
440-
}
441-
442452
static bool tpm_ibmvtpm_req_canceled(struct tpm_chip *chip, u8 status)
443453
{
444454
return (status == 0);

drivers/char/tpm/tpm_tis_core.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,9 @@ static void disable_interrupts(struct tpm_chip *chip)
433433
u32 intmask;
434434
int rc;
435435

436+
if (priv->irq == 0)
437+
return;
438+
436439
rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
437440
if (rc < 0)
438441
intmask = 0;
@@ -1062,9 +1065,12 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
10621065
if (irq) {
10631066
tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
10641067
irq);
1065-
if (!(chip->flags & TPM_CHIP_FLAG_IRQ))
1068+
if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) {
10661069
dev_err(&chip->dev, FW_BUG
10671070
"TPM interrupt not working, polling instead\n");
1071+
1072+
disable_interrupts(chip);
1073+
}
10681074
} else {
10691075
tpm_tis_probe_irq(chip, intmask);
10701076
}

0 commit comments

Comments
 (0)