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

tpm: ibmvtpm: Avoid error message when process gets signal while waiting

When rngd is run as root then lots of these types of message will appear
in the kernel log if the TPM has been configured to provide random bytes:

[ 7406.275163] tpm tpm0: tpm_transmit: tpm_recv: error -4

The issue is caused by the following call that is interrupted while
waiting for the TPM's response.

sig = wait_event_interruptible(ibmvtpm->wq, !ibmvtpm->tpm_processing_cmd);

Rather than waiting for the response in the low level driver, have it use
the polling loop in tpm_try_transmit() that uses a command's duration to
poll until a result has been returned by the TPM, thus ending when the
timeout has occurred but not responding to signals and ctrl-c anymore. To
stay in this polling loop extend tpm_ibmvtpm_status() to return
'true' for as long as the vTPM is indicated as being busy in
tpm_processing_cmd. Since the loop requires the TPM's timeouts, get them
now using tpm_get_timeouts() after setting the TPM2 version flag on the
chip.

To recreat the resolved issue start rngd like this:

sudo rngd -r /dev/hwrng -t
sudo rngd -r /dev/tpm0 -t

Link: https://bugzilla.redhat.com/show_bug.cgi?id=1981473
Fixes: 6674ff145eef ("tpm_ibmvtpm: properly handle interrupted packet receptions")
Cc: Nayna Jain <nayna@linux.ibm.com>
Cc: George Wilson <gcwilson@linux.ibm.com>
Reported-by: Nageswara R Sastry <rnsastry@linux.ibm.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Tested-by: Nageswara R Sastry <rnsastry@linux.ibm.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>

authored by

Stefan Berger and committed by
Jarkko Sakkinen
047d4226 a4aed36e

+16 -12
+15 -11
drivers/char/tpm/tpm_ibmvtpm.c
··· 106 106 { 107 107 struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev); 108 108 u16 len; 109 - int sig; 110 109 111 110 if (!ibmvtpm->rtce_buf) { 112 111 dev_err(ibmvtpm->dev, "ibmvtpm device is not ready\n"); 113 112 return 0; 114 113 } 115 - 116 - sig = wait_event_interruptible(ibmvtpm->wq, !ibmvtpm->tpm_processing_cmd); 117 - if (sig) 118 - return -EINTR; 119 114 120 115 len = ibmvtpm->res_len; 121 116 ··· 232 237 * set the processing flag before the Hcall, since we may get the 233 238 * result (interrupt) before even being able to check rc. 234 239 */ 235 - ibmvtpm->tpm_processing_cmd = true; 240 + ibmvtpm->tpm_processing_cmd = 1; 236 241 237 242 again: 238 243 rc = ibmvtpm_send_crq(ibmvtpm->vdev, ··· 250 255 goto again; 251 256 } 252 257 dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); 253 - ibmvtpm->tpm_processing_cmd = false; 258 + ibmvtpm->tpm_processing_cmd = 0; 254 259 } 255 260 256 261 spin_unlock(&ibmvtpm->rtce_lock); ··· 264 269 265 270 static u8 tpm_ibmvtpm_status(struct tpm_chip *chip) 266 271 { 267 - return 0; 272 + struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev); 273 + 274 + return ibmvtpm->tpm_processing_cmd; 268 275 } 269 276 270 277 /** ··· 454 457 .send = tpm_ibmvtpm_send, 455 458 .cancel = tpm_ibmvtpm_cancel, 456 459 .status = tpm_ibmvtpm_status, 457 - .req_complete_mask = 0, 460 + .req_complete_mask = 1, 458 461 .req_complete_val = 0, 459 462 .req_canceled = tpm_ibmvtpm_req_canceled, 460 463 }; ··· 547 550 case VTPM_TPM_COMMAND_RES: 548 551 /* len of the data in rtce buffer */ 549 552 ibmvtpm->res_len = be16_to_cpu(crq->len); 550 - ibmvtpm->tpm_processing_cmd = false; 553 + ibmvtpm->tpm_processing_cmd = 0; 551 554 wake_up_interruptible(&ibmvtpm->wq); 552 555 return; 553 556 default: ··· 685 688 goto init_irq_cleanup; 686 689 } 687 690 688 - if (!strcmp(id->compat, "IBM,vtpm20")) { 691 + 692 + if (!strcmp(id->compat, "IBM,vtpm20")) 689 693 chip->flags |= TPM_CHIP_FLAG_TPM2; 694 + 695 + rc = tpm_get_timeouts(chip); 696 + if (rc) 697 + goto init_irq_cleanup; 698 + 699 + if (chip->flags & TPM_CHIP_FLAG_TPM2) { 690 700 rc = tpm2_get_cc_attrs_tbl(chip); 691 701 if (rc) 692 702 goto init_irq_cleanup;
+1 -1
drivers/char/tpm/tpm_ibmvtpm.h
··· 41 41 wait_queue_head_t wq; 42 42 u16 res_len; 43 43 u32 vtpm_version; 44 - bool tpm_processing_cmd; 44 + u8 tpm_processing_cmd; 45 45 }; 46 46 47 47 #define CRQ_RES_BUF_SIZE PAGE_SIZE