From patchwork Fri Dec 23 18:58:12 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej S. Szmigiero" X-Patchwork-Id: 711415 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 3tvVT55kFZz9t1C for ; Fri, 6 Jan 2017 01:30:17 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=sfs-ml-3.v29.ch3.sourceforge.com) by sfs-ml-3.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1cP93R-0008Dj-GW; Thu, 05 Jan 2017 14:30:09 +0000 Received: from sog-mx-1.v43.ch3.sourceforge.com ([172.29.43.191] helo=mx.sourceforge.net) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1cKVKM-0003Kt-5G for tpmdd-devel@lists.sourceforge.net; Fri, 23 Dec 2016 19:16:26 +0000 X-ACL-Warn: Received: from vps-vb.mhejs.net ([37.28.154.113]) by sog-mx-1.v43.ch3.sourceforge.com with esmtps (TLSv1:AES256-SHA:256) (Exim 4.76) id 1cKVKK-00063P-M5 for tpmdd-devel@lists.sourceforge.net; Fri, 23 Dec 2016 19:16:26 +0000 Received: by vps-vb.mhejs.net with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.87) (envelope-from ) id 1cKV2i-0005Wj-Pg; Fri, 23 Dec 2016 19:58:12 +0100 From: "Maciej S. Szmigiero" To: tpmdd-devel@lists.sourceforge.net Message-ID: <4d95e68f-4d6a-ab66-3376-fad075c37cc9@maciej.szmigiero.name> Date: Fri, 23 Dec 2016 19:58:12 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 X-Spam-Score: 0.0 (/) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. X-Headers-End: 1cKVKK-00063P-M5 X-Mailman-Approved-At: Thu, 05 Jan 2017 14:30:07 +0000 Cc: linux-kernel Subject: [tpmdd-devel] tpm_tis: broken on TPMs with a static burst count 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: , Errors-To: tpmdd-devel-bounces@lists.sourceforge.net Hi all, Commit 1107d065fdf1 (tpm_tis: Introduce intermediate layer for TPM access) broke TPM support on ThinkPad X61S (and likely also on other machines which use TPMs with a static burst count). It looks like tpm_tis code before this commit had spun on TPM_STS_DATA_AVAIL | TPM_STS_VALID status bits in the read case and TPM_STS_VALID in the write case when it got a zero burst count. I have attached a patch against current code (linux-tpmdd tree) that brings back this old behavior. With this patch the TPM works again on X61S. However, somebody with more TPM experience should comment whether such behavior was OK or the change brought by commit 1107d065fdf1 was intentional. Maciej Szmigiero ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 7993678954a2..72d365db7c61 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -188,7 +188,9 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) if (rc < 0) return rc; burstcnt = get_burstcount(chip); - if (burstcnt < 0) { + if (burstcnt == -EBUSY) + continue; + else if (burstcnt < 0) { dev_err(&chip->dev, "Unable to read burstcount\n"); return burstcnt; } @@ -282,18 +284,20 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len) while (count < len - 1) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) { + if (burstcnt < 0 && burstcnt != -EBUSY) { dev_err(&chip->dev, "Unable to read burstcount\n"); rc = burstcnt; goto out_err; + } else if (burstcnt > 0) { + burstcnt = min_t(int, burstcnt, len - count - 1); + rc = tpm_tis_write_bytes(priv, + TPM_DATA_FIFO(priv->locality), + burstcnt, buf + count); + if (rc < 0) + goto out_err; + + count += burstcnt; } - burstcnt = min_t(int, burstcnt, len - count - 1); - rc = tpm_tis_write_bytes(priv, TPM_DATA_FIFO(priv->locality), - burstcnt, buf + count); - if (rc < 0) - goto out_err; - - count += burstcnt; if (wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c, &priv->int_queue, false) < 0) {