From patchwork Fri Dec 8 18:46:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Steffen X-Patchwork-Id: 10103153 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 27222602A0 for ; Fri, 8 Dec 2017 18:50:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 187DA28EB5 for ; Fri, 8 Dec 2017 18:50:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0D13928EC7; Fri, 8 Dec 2017 18:50:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 77B6828EAB for ; Fri, 8 Dec 2017 18:50:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752680AbdLHSuj (ORCPT ); Fri, 8 Dec 2017 13:50:39 -0500 Received: from smtp11.infineon.com ([217.10.52.105]:56905 "EHLO smtp11.infineon.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752338AbdLHSui (ORCPT ); Fri, 8 Dec 2017 13:50:38 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=infineon.com; i=@infineon.com; q=dns/txt; s=IFXMAIL; t=1512759039; x=1544295039; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=b+0F7QoI6PmCSe7hjhUq7TFdZwAgRpBk1WXQOCvf0yM=; b=pp+2CiA0rBJSs9mQ5PAnnECfmR6wwoQTmdah2i1U6jf4jQuORAoUVsam HJdkbUs8eh3FumjQYNqqFmod6LVmuL0MRLcIHNq8JL8XN3GsN1KG8e2Ux sDObqh22lFfWK//SAPry5968xNRM2Up6aAli0A5s00kv1/KpEV4/7yBtm Y=; X-SBRS: None Received: from unknown (HELO mucxv002.muc.infineon.com) ([172.23.11.17]) by smtp11.infineon.com with ESMTP/TLS/AES256-GCM-SHA384; 08 Dec 2017 19:50:38 +0100 Received: from MUCSE708.infineon.com (mucse708.infineon.com [172.23.7.82]) by mucxv002.muc.infineon.com (Postfix) with ESMTPS; Fri, 8 Dec 2017 19:50:37 +0100 (CET) Received: from ABGN5CG4522MQD.eu.infineon.com (172.23.8.247) by MUCSE708.infineon.com (172.23.7.82) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.1.669.32; Fri, 8 Dec 2017 19:50:37 +0100 From: Alexander Steffen To: , , , CC: Alexander Steffen Subject: [RFC][PATCH 4/9] tpm_tis_core: send all data in single operation Date: Fri, 8 Dec 2017 19:46:53 +0100 Message-ID: <20171208184658.9588-5-Alexander.Steffen@infineon.com> X-Mailer: git-send-email 2.11.1.windows.1 In-Reply-To: <20171208184658.9588-1-Alexander.Steffen@infineon.com> References: <20171208184658.9588-1-Alexander.Steffen@infineon.com> MIME-Version: 1.0 X-Originating-IP: [172.23.8.247] X-ClientProxiedBy: MUCSE706.infineon.com (172.23.7.80) To MUCSE708.infineon.com (172.23.7.82) Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP tpm_tis_send_data splits all commands sent to the TPM into at least two transfers, even if the commands are small enough to fit into a single transfer. The intention seems to be to make extra sure that the TPM has received all data correctly by observing the Expect flag flipping from 1 to 0 when writing the last byte. Unfortunately, this does not work as intended, because the Expect flag will change not when the last byte is written to the FIFO, but when the TPM processes the last byte from the FIFO. With a large FIFO and long commands it might well be that there are still many bytes left in the FIFO when the Expect flag is checked. Obviously, the flag will be 1 then, even if the FIFO contains more bytes than expected. Since there is no indication whether the FIFO is already empty or not, there is no way to implement this check reliably. But then again, this check is not necessary at all. The driver already ensures that not more data is sent to the TPM than is announced in the header. In addition, the TPM is required to throw away all extraneous bytes anyway. So if the Expect flag is 0 after all bytes have been sent to the TPM, the TPM has received the command correctly and is ready to execute it. Therefore, remove this intermediary check and send all data in a single operation. This simplifies the code and improves the performance, especially for short commands. Signed-off-by: Alexander Steffen Reviewed-by: Jarkko Sakkinen --- drivers/char/tpm/tpm_tis_core.c | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 0df05b4..1359c52 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -320,7 +320,6 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len) struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); int rc, status, burstcnt; size_t count = 0; - bool itpm = priv->flags & TPM_TIS_ITPM_WORKAROUND; status = tpm_tis_status(chip); if ((status & TPM_STS_COMMAND_READY) == 0) { @@ -333,38 +332,26 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len) } } - while (count < len - 1) { + while (count < len) { burstcnt = get_burstcount(chip); if (burstcnt < 0) { dev_err(&chip->dev, "Unable to read burstcount\n"); rc = burstcnt; goto out_err; } - burstcnt = min_t(int, burstcnt, len - count - 1); + burstcnt = min_t(int, burstcnt, len - count); rc = tpm_tis_write_bytes(priv, TPM_DATA_FIFO(priv->locality), burstcnt, buf + count); if (rc < 0) goto out_err; count += burstcnt; - - if (!itpm && wait_for_tpm_stat - (chip, TPM_STS_DATA_EXPECT | TPM_STS_VALID, - TPM_STS_DATA_EXPECT | TPM_STS_VALID, - chip->timeout_c, &priv->int_queue, false) < 0) { - rc = -EIO; - goto out_err; - } } - /* write last byte */ - rc = tpm_tis_write8(priv, TPM_DATA_FIFO(priv->locality), buf[count]); - if (rc < 0) - goto out_err; - - if (!itpm && wait_for_tpm_stat - (chip, TPM_STS_DATA_EXPECT | TPM_STS_VALID, TPM_STS_VALID, - chip->timeout_c, &priv->int_queue, false) < 0) { + if (!(priv->flags & TPM_TIS_ITPM_WORKAROUND) && + wait_for_tpm_stat(chip, TPM_STS_DATA_EXPECT | TPM_STS_VALID, + TPM_STS_VALID, chip->timeout_c, &priv->int_queue, + false) < 0) { rc = -EIO; goto out_err; }