From patchwork Tue Oct 11 12:01:01 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 680716 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3stbF61VVXz9sC7 for ; Tue, 11 Oct 2016 23:01:30 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=sfs-ml-2.v29.ch3.sourceforge.com) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1btvkL-0007s8-U2; Tue, 11 Oct 2016 12:01:25 +0000 Received: from sog-mx-4.v43.ch3.sourceforge.com ([172.29.43.194] helo=mx.sourceforge.net) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1btvkK-0007s2-Io for tpmdd-devel@lists.sourceforge.net; Tue, 11 Oct 2016 12:01:24 +0000 X-ACL-Warn: Received: from mga14.intel.com ([192.55.52.115]) by sog-mx-4.v43.ch3.sourceforge.com with esmtps (TLSv1:AES256-SHA:256) (Exim 4.76) id 1btvkF-0005BK-Gk for tpmdd-devel@lists.sourceforge.net; Tue, 11 Oct 2016 12:01:24 +0000 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP; 11 Oct 2016 05:01:14 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,329,1473145200"; d="scan'208";a="888856482" Received: from jsakkine-mobl1.tm.intel.com (HELO localhost) ([10.237.50.70]) by orsmga003.jf.intel.com with ESMTP; 11 Oct 2016 05:01:11 -0700 From: Jarkko Sakkinen To: tpmdd-devel@lists.sourceforge.net Date: Tue, 11 Oct 2016 15:01:01 +0300 Message-Id: <1476187261-29027-1-git-send-email-jarkko.sakkinen@linux.intel.com> X-Mailer: git-send-email 2.7.4 X-Spam-Score: -0.3 (/) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.3 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain X-Headers-End: 1btvkF-0005BK-Gk Cc: open list Subject: [tpmdd-devel] [PATCH] char/tpm: Check return code of wait_for_tpm_stat X-BeenThere: tpmdd-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Tpm Device Driver maintainance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: tpmdd-devel-bounces@lists.sourceforge.net From: Peter Huewe In some weird cases it might be possible that the TPM does not set STS.VALID within the given timeout time (or ever) but sets STS.EXPECT (STS=0x0C) In this case the driver gets stuck in the while loop of tpm_tis_send_data and loops endlessly. Checking the return value of wait_for_tpm_stat fixes this and the driver bails out correctly. While at it fixing all other users since if the TPM does not manage to set STS.VALID within the reasonable timeframe something is definitely wrong and the driver should react correctly. Signed-off-by: Peter Huewe Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm_tis_core.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index e3bf31b..73f4c4b 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -180,11 +180,13 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); int size = 0, burstcnt, rc; - while (size < count && - wait_for_tpm_stat(chip, + while (size < count) { + rc = wait_for_tpm_stat(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID, chip->timeout_c, - &priv->read_queue, true) == 0) { + &priv->read_queue, true); + if (rc < 0) + return rc; burstcnt = min_t(int, get_burstcount(chip), count - size); rc = tpm_tis_read_bytes(priv, TPM_DATA_FIFO(priv->locality), @@ -229,8 +231,11 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) goto out; } - wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c, - &priv->int_queue, false); + if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c, + &priv->int_queue, false) < 0) { + size = -ETIME; + goto out; + } status = tpm_tis_status(chip); if (status & TPM_STS_DATA_AVAIL) { /* retry? */ dev_err(&chip->dev, "Error left over data\n"); @@ -279,8 +284,11 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len) count += burstcnt; - wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c, - &priv->int_queue, false); + if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c, + &priv->int_queue, false) < 0) { + rc = -ETIME; + goto out_err; + } status = tpm_tis_status(chip); if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) { rc = -EIO; @@ -293,8 +301,11 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len) if (rc < 0) goto out_err; - wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c, - &priv->int_queue, false); + if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c, + &priv->int_queue, false) < 0) { + rc = -ETIME; + goto out_err; + } status = tpm_tis_status(chip); if (!itpm && (status & TPM_STS_DATA_EXPECT) != 0) { rc = -EIO;