From patchwork Mon Oct 17 23:57:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lino Sanfilippo X-Patchwork-Id: 3847 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp1696242wrs; Mon, 17 Oct 2022 16:59:50 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6R7pjjD1QfgghEeRgx6PCx5peL2znJVi77/hD+iuQgm58tbdal7ggbJp9ZxznMGMPkG8Jf X-Received: by 2002:a17:906:eec1:b0:782:6384:76be with SMTP id wu1-20020a170906eec100b00782638476bemr179018ejb.756.1666051190386; Mon, 17 Oct 2022 16:59:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666051190; cv=none; d=google.com; s=arc-20160816; b=S01hsOtqR/QtNcKauvakfjH/D3hzpa/AFAQJEz3Tcn9RxjSGCSz5+qXBPDjxZURtG6 tox7gBMOeP0ojcdIBSdzzlWGwE4WBpdDovrEelZS4s+NHWiCQ4XVWp5+Kg8msItpsBzS dnIz1MrmJSOoG71nI2HPnNmJ1NpKR9adLfXpvIvWVM8NjQiNNIB65jM1mK1tUA1a9nJT 7JfXiBnETIslGVCtRaY8m1n69eW1zsYglq6xaCK7qRbMZ9sseHWCe1PAKuxbg9GbNDSo 173AuM47y3YVHbMyU3pfnmfYYUixS5yUiY+CuSeTFabgAv0Xk2URXcKGSzCNBI0rqiPF MB6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=aGoHsAcDuhhqSpkLQAxXzsC5Nh/HzN5f5Q02AEnI5+I=; b=rNm39bmnfFcpvN/aC9mb6vW144DnDbj8qgtpg/Jq8m96TJlYTRpn4HuWd+ApnpGG5l OK+rSjIGLx3Bm85KzDMRkAOseq0mq1HndfyClGapv77VzhuGULSXLHmtWXpjUYBiuyV0 H0ltdGxqR7HJ4jLVusHfP2mx8G7pHOJo0LdtXxcKOvFQiaDzjVEJadfx7iJzjupXJhr8 WlwpmeCxyLxO6i4vtwtnkPdEqprkHJURQOPoN7wLdcZMzqD4tky5HZMXK5Cffu1FWsQU +sZWKtwH0RInobTw9lBTfwhbXlrkJQLf+zK7cCWYgkZ6Gocc0O2zJss0TQCHKUjTMSne PBpg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmx.net header.s=badeba3b8450 header.b=CQnw5FNr; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmx.de Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id oz39-20020a1709077da700b0073d581b0906si11842509ejc.278.2022.10.17.16.59.25; Mon, 17 Oct 2022 16:59:50 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@gmx.net header.s=badeba3b8450 header.b=CQnw5FNr; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmx.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231276AbiJQX6a (ORCPT + 99 others); Mon, 17 Oct 2022 19:58:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230254AbiJQX6O (ORCPT ); Mon, 17 Oct 2022 19:58:14 -0400 Received: from mout.gmx.net (mout.gmx.net [212.227.17.21]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C7617E320; Mon, 17 Oct 2022 16:58:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1666051072; bh=aGoHsAcDuhhqSpkLQAxXzsC5Nh/HzN5f5Q02AEnI5+I=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=CQnw5FNrGJNnfwbeZ1tCNB1MFkNeGujM/NnltvNvJFZ+3HE68JAsYfdnHlrbJFaYt ITQouyu0X5vBCOMrTTjL7yYz1FAT4lQk5gn4PxAS9CK21sZkSiYqyReuI7WPue98TO jUBoYujT8tC6ibZMa0tpPKVZNq07e+oJd9XPXQ0U= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from Venus.speedport.ip ([84.162.5.241]) by mail.gmx.net (mrgmx105 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MF3HU-1ovYKl4Awa-00FQ7i; Tue, 18 Oct 2022 01:57:52 +0200 From: Lino Sanfilippo To: peterhuewe@gmx.de, jarkko@kernel.org, jgg@ziepe.ca Cc: stefanb@linux.vnet.ibm.com, linux@mniewoehner.de, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, jandryuk@gmail.com, pmenzel@molgen.mpg.de, l.sanfilippo@kunbus.com, LinoSanfilippo@gmx.de, lukas@wunner.de, p.rosenberger@kunbus.com Subject: [PATCH v8 05/11] tpm, tpm_tis: Only handle supported interrupts Date: Tue, 18 Oct 2022 01:57:26 +0200 Message-Id: <20221017235732.10145-6-LinoSanfilippo@gmx.de> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20221017235732.10145-1-LinoSanfilippo@gmx.de> References: <20221017235732.10145-1-LinoSanfilippo@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:nUbU4NRPZD5rhgOWoMvN+mlSIdLkSir1mw9uGxYDN1Ie3MUq4bE b9JdPFI1/+DemG7CeEmSXQXUrvg6FGea8VUVDHIWTSheUhkUuTjydUf1DgwkBig3Il+8Gq2 snTZ6Bbv/sP4Bgk3lvGcl3hZJ9j2Qoa8g9g+qTY9L36LI/JqK98AjWxm6WBkIzYqW3U/hW5 0Whp5kZD342S6FwgL/uIg== X-UI-Out-Filterresults: notjunk:1;V03:K0:EkqpYWXdsdo=:3kQz8APDD0Ord+K1eyK1j1 fgUdmtsx0UJNG2isqOZnZmQB/DvZx3IQSm8pRoewuJ9Ay4uj86XACRw+yN/C1k3w0Aek9TSpp rUjVM/vHinU51WDQdrCvLR427oAh5wawwcJ3ifRpDapopc6JFqrD1gGAuVdBaCWEUArD959VY f5GxxyFlHw8VymMlOS/ggpuOfmXk/VxV5RQ+3kCkzs7tOzGp3G8YVMDS40R4qFPKB/HTPLLnC nF21JKEG2rdMMOfZrDm7aAbvO/O3x4Pm/fg0gaByF2BOm3r+E1kj0KrOZCo3SlredNYChs3Mt WDyKs7sXETYFQT2pMKxkSRSbfaGoe0NA+BzoFrlk/eaWohBj3+iiL7XhzxJtRXUE82atk3hE6 Wj2hvZFaAdwFZ0Td6S7nBAAJWEk6kdaKIICy31H8DsFu1Zmg94/+lBEbAuCwCAB6OgIpvJ+gM dM3qwhKuIGqI0fp+ZXRcD6uRoUHaafjNr+PvHaVdhcJ/pQ/Y3zMSs8HiFVo29yKG21CVaNaL2 O8bncCvQ1IdfBBhGmm2Y//8BDSMI6DDgEgqci/YDocXghvh8J8duixvfdlqFkNacgHAs9yLZO Hhr23lN1/sSbP9JhcwBBB2iHXHbzRJV9GflcEKyw/4KiJ9Er6h3VLKwSXg+XMpuy2Vz8Wa3r1 kF1ZW0jRpzdvrvc6MuePFFQkN0bO28BwsxqRdJJ77qlKv+/YysHN5wQ06LUXCPu01GjU8OVA2 JUR1MH9d3/89k+MCUvu3D/pBBa4BeXMixvuyq8ZnAjpvEN1ydZoOfstMpYDqhcGM8fsZLSy6V eJB6pEpXWWQaVkcY1iWWM5hfqrxtMs++MrA7m3VMpvYw5LBSHtGXD8p9GrUVtQeiL1BjC89fl Xxh6Jv/uSvKO5l16apTiFiFtunEiTUkSaA9Wm2bKoapMap0eTmLhOgRTEVsBY9VVET1FdTzbW 6GtpQKb8qR0sQfY5YTLd/zqLyvemAQzJk15uk2uG01wurqaglLqAGb//PImT+QU51nC/5T712 rBLxu4AyVT2zv/xTfdpGdJ/CkJNmEU7w8HFm/bvHkBxR4nAJ7IzKmGD6o0BuZWC34N48Tf9R6 0qKgrt/S6zCe6ZLD/D/xPPJqE7cgjbPLJetfqRFo4ArArBR9ySypL9ynkn3GAjrMMCiu6Fa/q kHYSxFYAvmh6MCz2tQw5MLGzgJwkemjaOwlXydgARqbILtPqgxOuSgMbWUIKcwW0BFcMhKBRg Y9Sj44bR0I6f0j8Q5vqn4drbGHdPK2xFvI+X51IRx7vY3M0a3ORjAdz3pU4y9wS2/lpl0eVjA 4Nt47s23yteUS3FEqS7lBCq77oREHTCwPEMWUu0Ip/p3ZezxcjJar6Uq/lCqLRbFbVwQSywT6 MnaPmeYx9J1sA6Ts6vlGq3LREvxC9vmOdCSt4qqlKfs0xlIQD1SqP0LL5Z0UkYuPjMNDANweK +zVSnSyhh4VFvm8pcIcCN/m22FyUCWZ2Z22GZ5roGPe8CefVRtz0TvU8nurFEv2YHVY0lIKVl Tn1avMzuHtlCtOmzugKA4KFxlsa4XZrDPpOAAPchMjtwP X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746981293396429635?= X-GMAIL-MSGID: =?utf-8?q?1746981293396429635?= From: Lino Sanfilippo According to the TPM Interface Specification (TIS) support for "stsValid" and "commandReady" interrupts is only optional. This has to be taken into account when handling the interrupts in functions like wait_for_tpm_stat(). To determine the supported interrupts use the capability query. Also adjust wait_for_tpm_stat() to only wait for interrupt reported status changes. After that process all the remaining status changes by polling the status register. Signed-off-by: Lino Sanfilippo Tested-by: Michael Niewöhner Reviewed-by: Jarkko Sakkinen --- drivers/char/tpm/tpm_tis_core.c | 120 +++++++++++++++++++------------- drivers/char/tpm/tpm_tis_core.h | 1 + 2 files changed, 73 insertions(+), 48 deletions(-) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 52205a1fee9e..d07debc3182c 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -53,41 +53,63 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, long rc; u8 status; bool canceled = false; + u8 sts_mask = 0; + int ret = 0; /* check current status */ status = chip->ops->status(chip); if ((status & mask) == mask) return 0; - stop = jiffies + timeout; + /* check what status changes can be handled by irqs */ + if (priv->int_mask & TPM_INTF_STS_VALID_INT) + sts_mask |= TPM_STS_VALID; - if (chip->flags & TPM_CHIP_FLAG_IRQ) { + if (priv->int_mask & TPM_INTF_DATA_AVAIL_INT) + sts_mask |= TPM_STS_DATA_AVAIL; + + if (priv->int_mask & TPM_INTF_CMD_READY_INT) + sts_mask |= TPM_STS_COMMAND_READY; + + sts_mask &= mask; + + stop = jiffies + timeout; + /* process status changes with irq support */ + if (sts_mask) { + ret = -ETIME; again: timeout = stop - jiffies; if ((long)timeout <= 0) return -ETIME; rc = wait_event_interruptible_timeout(*queue, - wait_for_tpm_stat_cond(chip, mask, check_cancel, + wait_for_tpm_stat_cond(chip, sts_mask, check_cancel, &canceled), timeout); if (rc > 0) { if (canceled) return -ECANCELED; - return 0; + ret = 0; } if (rc == -ERESTARTSYS && freezing(current)) { clear_thread_flag(TIF_SIGPENDING); goto again; } - } else { - do { - usleep_range(priv->timeout_min, - priv->timeout_max); - status = chip->ops->status(chip); - if ((status & mask) == mask) - return 0; - } while (time_before(jiffies, stop)); } + + if (ret) + return ret; + + mask &= ~sts_mask; + if (!mask) /* all done */ + return 0; + /* process status changes without irq support */ + do { + status = chip->ops->status(chip); + if ((status & mask) == mask) + return 0; + usleep_range(priv->timeout_min, + priv->timeout_max); + } while (time_before(jiffies, stop)); return -ETIME; } @@ -1021,8 +1043,40 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, if (rc < 0) goto out_err; - intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | - TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; + /* Figure out the capabilities */ + rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps); + if (rc < 0) + goto out_err; + + dev_dbg(dev, "TPM interface capabilities (0x%x):\n", + intfcaps); + if (intfcaps & TPM_INTF_BURST_COUNT_STATIC) + dev_dbg(dev, "\tBurst Count Static\n"); + if (intfcaps & TPM_INTF_CMD_READY_INT) { + intmask |= TPM_INTF_CMD_READY_INT; + dev_dbg(dev, "\tCommand Ready Int Support\n"); + } + if (intfcaps & TPM_INTF_INT_EDGE_FALLING) + dev_dbg(dev, "\tInterrupt Edge Falling\n"); + if (intfcaps & TPM_INTF_INT_EDGE_RISING) + dev_dbg(dev, "\tInterrupt Edge Rising\n"); + if (intfcaps & TPM_INTF_INT_LEVEL_LOW) + dev_dbg(dev, "\tInterrupt Level Low\n"); + if (intfcaps & TPM_INTF_INT_LEVEL_HIGH) + dev_dbg(dev, "\tInterrupt Level High\n"); + if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT) { + intmask |= TPM_INTF_LOCALITY_CHANGE_INT; + dev_dbg(dev, "\tLocality Change Int Support\n"); + } + if (intfcaps & TPM_INTF_STS_VALID_INT) { + intmask |= TPM_INTF_STS_VALID_INT; + dev_dbg(dev, "\tSts Valid Int Support\n"); + } + if (intfcaps & TPM_INTF_DATA_AVAIL_INT) { + intmask |= TPM_INTF_DATA_AVAIL_INT; + dev_dbg(dev, "\tData Avail Int Support\n"); + } + intmask &= ~TPM_GLOBAL_INT_ENABLE; rc = request_locality(chip, 0); @@ -1056,32 +1110,6 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, goto out_err; } - /* Figure out the capabilities */ - rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps); - if (rc < 0) - goto out_err; - - dev_dbg(dev, "TPM interface capabilities (0x%x):\n", - intfcaps); - if (intfcaps & TPM_INTF_BURST_COUNT_STATIC) - dev_dbg(dev, "\tBurst Count Static\n"); - if (intfcaps & TPM_INTF_CMD_READY_INT) - dev_dbg(dev, "\tCommand Ready Int Support\n"); - if (intfcaps & TPM_INTF_INT_EDGE_FALLING) - dev_dbg(dev, "\tInterrupt Edge Falling\n"); - if (intfcaps & TPM_INTF_INT_EDGE_RISING) - dev_dbg(dev, "\tInterrupt Edge Rising\n"); - if (intfcaps & TPM_INTF_INT_LEVEL_LOW) - dev_dbg(dev, "\tInterrupt Level Low\n"); - if (intfcaps & TPM_INTF_INT_LEVEL_HIGH) - dev_dbg(dev, "\tInterrupt Level High\n"); - if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT) - dev_dbg(dev, "\tLocality Change Int Support\n"); - if (intfcaps & TPM_INTF_STS_VALID_INT) - dev_dbg(dev, "\tSts Valid Int Support\n"); - if (intfcaps & TPM_INTF_DATA_AVAIL_INT) - dev_dbg(dev, "\tData Avail Int Support\n"); - /* INTERRUPT Setup */ init_waitqueue_head(&priv->read_queue); init_waitqueue_head(&priv->int_queue); @@ -1112,7 +1140,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, else tpm_tis_probe_irq(chip, intmask); - if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) { + if (chip->flags & TPM_CHIP_FLAG_IRQ) { + priv->int_mask = intmask; + } else { dev_err(&chip->dev, FW_BUG "TPM interrupt not working, polling instead\n"); @@ -1159,13 +1189,7 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) if (rc < 0) goto out; - rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); - if (rc < 0) - goto out; - - intmask |= TPM_INTF_CMD_READY_INT - | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT - | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE; + intmask = priv->int_mask | TPM_GLOBAL_INT_ENABLE; tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h index 695a2516dce0..2deef11c88db 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h @@ -93,6 +93,7 @@ struct tpm_tis_data { u16 manufacturer_id; int locality; int irq; + unsigned int int_mask; unsigned long flags; void __iomem *ilb_base_addr; u16 clkrun_enabled;