From patchwork Sat May 1 13:57:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lino Sanfilippo X-Patchwork-Id: 12234773 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.0 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,MIME_BASE64_TEXT,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C08A9C433ED for ; Sat, 1 May 2021 14:01:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 85B1F61613 for ; Sat, 1 May 2021 14:01:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232178AbhEAOC3 (ORCPT ); Sat, 1 May 2021 10:02:29 -0400 Received: from mout.gmx.net ([212.227.17.20]:56987 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232135AbhEAOC2 (ORCPT ); Sat, 1 May 2021 10:02:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1619877685; bh=AzZ1AEuOXzDeEZImjz7dTO6fuYvDAouQw4LSy2qtRfc=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=cJEtwcMT/jtmDGDmnOkPUOtDVMz5XKQVsLanP9GkzkU9SZxla1Bje4xAU2i1Fyoq/ bq6YQmiHdDOyTgK5+dLiYPYtUEsVP6rITBpHEcknK0mUX4OLS8GREa4U7nZhA0c2Ss MCz7VdZQefZZhle4OVDs88b8W+fVaF2JyHmQby3g= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from Venus.fritz.box ([78.42.220.31]) by mail.gmx.net (mrgmx105 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MwQTF-1lJvmq2RYj-00sQci; Sat, 01 May 2021 16:01:25 +0200 From: Lino Sanfilippo To: peterhuewe@gmx.de, jarkko@kernel.org, jgg@ziepe.ca Cc: stefanb@linux.vnet.ibm.com, James.Bottomley@hansenpartnership.com, keescook@chromium.org, jsnitsel@redhat.com, ml.linux@elloe.vision, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, LinoSanfilippo@gmx.de, Stefan Berger Subject: [PATCH v3 1/4] tpm: Use a threaded interrupt handler Date: Sat, 1 May 2021 15:57:24 +0200 Message-Id: <20210501135727.17747-2-LinoSanfilippo@gmx.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210501135727.17747-1-LinoSanfilippo@gmx.de> References: <20210501135727.17747-1-LinoSanfilippo@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:NrTXl/opWW/qgKoUTHBe+9UNDrooth7BL558pzu02XlAoFZ2mXR uBepUu9IrF0futHiWZ0QtkjV68QuieCkwEvgeHsuk+/4KXVZI5SHlyGHG9eh2TvXGwRxaTP tEqlXh4APLVE2GLSxocC5hN80O4Q8+JLX+jA+gBi0JkrcxGu8eIP73wEiPPXxEDYeiKGQJA 42G5Uf/V4JM4tgjCMfkbQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:6LPgizRyedI=:Cx2O9SlAsQqEtSKq11bB/w 9ca9OY5wg+eP48gfddI1w8wJCKHxv8WlKx4ulGaDdY6EXbCtipijSJ3Is+wLMiMhLUBucnU94 dITVMESvGCOHjiGxWovFRx6m3dd2TmGMdpo0WX6ogYQOKUZTPb691+dttuTPJtuaFB4sKNbRp 4YWJ/pnmlaWVec915D0eW0Qmp9LhL4M2/icYoQIY1svc6nW/uLSSaEYoxZeSEEyWMggLV0zdT iEZBJzWF58oOsoqzw98UIiGukGxDqz2zWfIXjl8cteMfSMU8iVMDbEq9+juuR/wTgxgDI2aNF JZP+MMJ1XFQTHneMKDNQMOAMWo7tznfE5CCT2mnMcji0Q6o/obNsgiWj2VYevtHIime5J7Qtf gA+aMM5u9Q2Q+tTZCnRRbYtF5v9XKR9V72SRxpmW4EKs6cG2f2I4Lz/1fURRuVUbewAB82ts+ WLgsNcnKD6uOLUwizTyxP6+bnZoZFv+Oruv18KrP3o8UuJ1MfCUFhMgB9SEbJV5k9Aom7tiRv R1YDt9IlIvu4bSDY52DUtUHUl9j+36KkiGLnZIkXk3bwrqzpsBwGNKOT3Z6ZdXaR0WeG4Bk6w VzzzVwcNbyvJWEz7yzVQAjNYDycOEyRPJLii9zItQU61dGujOL3irqbLqIqAuS0QyhDAFIQ41 ujMDGbtJQppYOdEeZC/q5hxvWon55VYk8zgoTn8BeThfxBboWJ0Dten5Q4MPFz7jw0hNyQoMe Dic7A82abklmPAu9MVhTPyvtZduqhfZOKokeWvg8MLy0qzAYB1Yj2vGlANKxqs2/rP1DyujTc 8nSRUyOk6R78lCXwAgcJTyEw3F1BFFTCWVr/TGBZzy0fct5zXCuce2b7jcMu4tooLkG9i9NwN 4R+MHeqNBYDcUgEP43CKoN0qj50VS5FC0kHEgQQreQg0rTqi6IgbkxVoXpKWq/se14bv81dOv n7ILwMMVHMf7g9aIY7+RN23d6k6inGeLxL+NEucTeUvR5us+VoElDtH8eWRtMmN9Qm6zcTkf2 qqs99vxYN+Iz7GuoIwPUEtpt2GEjxJh+2J01xEP3uaSguEDLbP9lx9Ek8ng3y1FbSR3Zz97+B SoE/+Mz39+jnI7/OhXRQCWWjZJmFoay9HtXWcWW0aCR6TlYkAqbjKnDjcFRH5NAR+ULHDEpYO 70tytwQcCH/jNUNYEbb116YfLpQNOhBMfiVW03W7X5Qmy0LQREUKJzXcEs4RK5d2PnL1S4mpC IGN9pCdXypWwke3sU Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org The interrupt handler uses tpm_tis_read32() and tpm_tis_write32() to access the interrupt status register. In case of SPI those accesses are done with the spi_bus_lock mutex held. This means that the status register cannot be read or written in interrupt context. For this reason request a threaded interrupt handler so that the required accesses can be done in process context. Reviewed-by: Stefan Berger Signed-off-by: Lino Sanfilippo --- drivers/char/tpm/tpm_tis_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index a2e0395cbe61..a12992ae2a3e 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -737,8 +737,10 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask, int rc; u32 int_status; - if (devm_request_irq(chip->dev.parent, irq, tis_int_handler, flags, - dev_name(&chip->dev), chip) != 0) { + + if (devm_request_threaded_irq(chip->dev.parent, irq, NULL, + tis_int_handler, IRQF_ONESHOT | flags, + dev_name(&chip->dev), chip) != 0) { dev_info(&chip->dev, "Unable to request irq: %d for probe\n", irq); return -1; From patchwork Sat May 1 13:57:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lino Sanfilippo X-Patchwork-Id: 12234775 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.0 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,MIME_BASE64_TEXT,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C8C6C433B4 for ; Sat, 1 May 2021 14:01:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D791C61490 for ; Sat, 1 May 2021 14:01:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232165AbhEAOC2 (ORCPT ); Sat, 1 May 2021 10:02:28 -0400 Received: from mout.gmx.net ([212.227.17.20]:52391 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232136AbhEAOC2 (ORCPT ); Sat, 1 May 2021 10:02:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1619877686; bh=T0Fd1bzwcjESFjSMFc7M/35dAUEogjYlT/6DN2d89Vs=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=KDzslDkqJFJBL33wfwg3hQfu918SHPcViLDdoMlZHYa6dy5NfvLBTRoHoj9QsnlS6 7BjnBhIhLf7yq+/Ff/KOQh5wAcH4iWLPVXMYkPSaQDN/NE0R+u5/VBoRJZYGkWxCO5 r0ETN0LQHupyWUdRAECUgPVIFM2PWJhA1/yhmSyo= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from Venus.fritz.box ([78.42.220.31]) by mail.gmx.net (mrgmx105 [212.227.17.168]) with ESMTPSA (Nemesis) id 1Mlw3X-1lCt1B09AJ-00iyze; Sat, 01 May 2021 16:01:26 +0200 From: Lino Sanfilippo To: peterhuewe@gmx.de, jarkko@kernel.org, jgg@ziepe.ca Cc: stefanb@linux.vnet.ibm.com, James.Bottomley@hansenpartnership.com, keescook@chromium.org, jsnitsel@redhat.com, ml.linux@elloe.vision, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, LinoSanfilippo@gmx.de Subject: [PATCH v3 2/4] tpm: Simplify locality handling Date: Sat, 1 May 2021 15:57:25 +0200 Message-Id: <20210501135727.17747-3-LinoSanfilippo@gmx.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210501135727.17747-1-LinoSanfilippo@gmx.de> References: <20210501135727.17747-1-LinoSanfilippo@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:OvJNB7A4vqxmwwT+wqDxULsbp48SDBs1Byb6p5U0IpGzb/5vC3C 462n/fSPbZKIL9NdmCy5li4QbQfp6nQifBfJPO2OhZdpVmzJiB4CmIha2PlN8RrZHbM+OJJ JwHA/K1WsFdB20a6qCdJV9wu0MhPi6v16HZSqpBXlACqaU+wUBxSqy6qeGP/foM95N5hrlu 6Bi/3mNQBXfB/1r+BAAXA== X-UI-Out-Filterresults: notjunk:1;V03:K0:czHwvHrGdNg=:761gljfEtc4Bpa1OQfFZ65 n4EiFkRYP7DhlWakUatNxx+KOxlaLABgBoImASRoikSH5mMiafIwUKY5olPciircUIwPc7mbK eFxwXmqiI1M8/y9AUUmctMBnPP7zP43hcFx1wKBQ5CtYiDcioG3Wd+wnWW9FDQ//6GSzT9wTu VArnB4QP5ftPyKxzNVX1983TrSahW73Atl3IMV7vBlDvXZEP4GbJVFfDO7G0y1wVP3dQyF19F uzxBFg18e/gLsLFdmIGFIRtoMW3b3ectxyfyXn/7+34ZwMvDNyPPJhCdY0iqFI3DNXjOagk4i AlTUnXZ5aAQXizWhU3F6zxSoGKgHP8QX0f9qCnU5wMi+ze7I/QpAKIu6m+inP7u+CbLpQBQWF S8RGQUug/PzsQwunhDivaIxSYe/otn9AX/UStHSrdz2nEsJ/KBilKtu0rHVWwIuDOWjZbJN8H 268bPTOCrpBPBe3wDMlhpB+hJauXcQssNWIPvg1F2AT/Nc9oJ/s8Nr0bFqswbt4JDydGytG92 TVYOad+7i6dw8uaoNXl9/QAjcNQEMeVy305dHnc+EiCDOnbe9RGgXg9sGVbVaxroIZB44UqzJ 4gPbzMQYdcFATFx5B9Ipiym/WcrsINlGkR1I9Q8sBT7/3Aq5oslMBwTBCaiq9hkB14Nt6VmXf aK6+KlQNlqh6BqlYrcauByWSd5yyTvY/0z2rOjfPf/d7vul1RLpDrLQ1bEKJA0HomeQSqRSXv Ozxi+1Ag0S0YOtWqkv+i+c1HEjYYyJk+08OuTPVLzCB0LRAibi34a4/Tn+9jvOBAsst6ySdda gpmDZWqkZlb30PHPwhIF9D3fSKwCVTetnvSmMXdHJqVSr8WPDW99F5aaQcHP103rQay2iHRsm o0M80UYjeBLwybvochPcKm0ACJ1S1eBe5ZtHWmf+Kkw+3wg8fAWudqt5b0oQU+ZPSSp8+wcwu 5Mu/ln1+4MJ01+Hdck2MiAUr5Ntgn+tqKcySpnio76o7UfQfqfYH6Hy6sBJX3qDzePBrv42KC 9gBrICozavneJYDvDriU9FS8/74ply0/A4vF2p4/pqBUtoQ9Tt/rVzXasuxdk0GVnT3f2YIl1 o4Nxtmh1DvfxA/O1+QHP50J6XdmbKVIVbiZemqAoVk4Uvy61U9S23UX/fHBO5WoT3JQQ8is6X lQ/hK4Qq1E/6F2H+K8//KJjr3lWFagLl9nAex/doQQJXU2lc1O6miesC8Bkkcn+IxCPOOIC8/ Rw6cbLC2DRRzLNC3V Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org Currently the TPM (default) locality is claimed and released for each access to the TPM registers which require a claimed locality. This results in locality claim/release combos at various code places. For interrupt handling we also need such a combo in the interrupt handler (for clearing the interrupts) which makes the locality handling even more complicated since now we also have to synchronize concurrent accesses in process and in interrupt context. Since currently the driver uses only one locality anyway, avoid the increasing complexity by claiming it once at driver startup and only releasing it at driver shutdown. Due to the simplifications the functions tpm_request_locality() and tpm_relinquish_locality() are not needed any more an can be removed. As a side-effect these modifications fix a bug which results in the following warning when using TPM 2: TPM returned invalid status WARNING: CPU: 0 PID: 874 at drivers/char/tpm/tpm_tis_core.c:249 tpm_tis_status+0xbc/0xc8 [tpm_tis_core] Modules linked in: tpm_tis_spi tpm_tis_core tpm sha256_generic cfg80211 rfkill 8021q garp stp llc spidev v3d gpu_sched vc4 bcm2835_codec(C) cec raspberrypi_hwmon drm_kms_helper drm bcm2835_isp(C) v4l2_mem2mem bcm2835_v4l2(C) bcm2835_mmal_vchiq(C) videobuf2_vmalloc videobuf2_dma_contig snd_bcm2835(C) videobuf2_memops drm_panel_orientation_quirks videobuf2_v4l2 videobuf2_common snd_soc_core snd_compress videodev snd_pcm_dmaengine spi_bcm2835 snd_pcm mc vc_sm_cma(C) snd_timer snd syscopyarea rpivid_mem sysfillrect sysimgblt fb_sys_fops backlight uio_pdrv_genirq uio ip_tables x_tables ipv6 [last unloaded: tpm] CPU: 0 PID: 874 Comm: kworker/u8:1 Tainted: G WC 5.11.0-rc2-LS-HOME+ #1 Hardware name: Raspberry Pi Compute Module 4 Rev 1.0 (DT) Workqueue: events_unbound async_run_entry_fn pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--) pc : tpm_tis_status+0xbc/0xc8 [tpm_tis_core] lr : tpm_tis_status+0xbc/0xc8 [tpm_tis_core] sp : ffffffc0127e38f0 x29: ffffffc0127e38f0 x28: ffffffc011238000 x27: 0000000000000016 x26: 000000000000017a x25: 0000000000000014 x24: ffffff8047f60000 x23: 0000000000000000 x22: 0000000000000016 x21: ffffff8044e8a480 x20: 0000000000000000 x19: ffffffc011238000 x18: ffffffc011238948 x17: 0000000000000000 x16: 0000000000000000 x15: ffffffc01141be81 x14: ffffffffffffffff x13: ffffffc01141be7e x12: ffffffffffffffff x11: ffffff807fb797f0 x10: 00000000000019b0 x9 : ffffffc0127e38f0 x8 : 766e692064656e72 x7 : 0000000000000000 x6 : ffffffc011239000 x5 : ffffff807fb628b8 x4 : 0000000000000000 x3 : 0000000000000027 x2 : 0000000000000000 x1 : 6818b6f22fdef800 x0 : 0000000000000000 Call trace: tpm_tis_status+0xbc/0xc8 [tpm_tis_core] tpm_tis_send_data+0x58/0x250 [tpm_tis_core] tpm_tis_send_main+0x50/0x128 [tpm_tis_core] tpm_tis_send+0x4c/0xe0 [tpm_tis_core] tpm_transmit+0xd0/0x350 [tpm] tpm_transmit_cmd+0x3c/0xc0 [tpm] tpm2_get_tpm_pt+0x124/0x1e8 [tpm] tpm_tis_probe_irq_single+0x198/0x364 [tpm_tis_core] tpm_tis_core_init+0x304/0x520 [tpm_tis_core] tpm_tis_spi_init+0x5c/0x78 [tpm_tis_spi] tpm_tis_spi_probe+0x80/0x98 [tpm_tis_spi] tpm_tis_spi_driver_probe+0x4c/0x60 [tpm_tis_spi] spi_probe+0x84/0xf0 really_probe+0x118/0x420 driver_probe_device+0x5c/0xc0 __driver_attach_async_helper+0x64/0x68 async_run_entry_fn+0x48/0x150 process_one_work+0x15c/0x4d0 worker_thread+0x50/0x490 kthread+0x118/0x150 ret_from_fork+0x10/0x1c The reason for this issue is that in case of TPM 2 function tpm2_get_timeouts() which executes a TPM command is called without a claimed locality. Since with this patch the locality is taken once at driver startup and never released before shutdown the issue does not occur any more. Fixes: a3fbfae82b4c ("tpm: take TPM chip power gating out of tpm_transmit()") Signed-off-by: Lino Sanfilippo --- drivers/char/tpm/tpm-chip.c | 40 --------------------------------- drivers/char/tpm/tpm_tis_core.c | 35 +++++++++-------------------- include/linux/tpm.h | 3 --- 3 files changed, 10 insertions(+), 68 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index ddaeceb7e109..a09b6523261e 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -32,35 +32,6 @@ struct class *tpm_class; struct class *tpmrm_class; dev_t tpm_devt; -static int tpm_request_locality(struct tpm_chip *chip) -{ - int rc; - - if (!chip->ops->request_locality) - return 0; - - rc = chip->ops->request_locality(chip, 0); - if (rc < 0) - return rc; - - chip->locality = rc; - return 0; -} - -static void tpm_relinquish_locality(struct tpm_chip *chip) -{ - int rc; - - if (!chip->ops->relinquish_locality) - return; - - rc = chip->ops->relinquish_locality(chip, chip->locality); - if (rc) - dev_err(&chip->dev, "%s: : error %d\n", __func__, rc); - - chip->locality = -1; -} - static int tpm_cmd_ready(struct tpm_chip *chip) { if (!chip->ops->cmd_ready) @@ -103,17 +74,8 @@ int tpm_chip_start(struct tpm_chip *chip) tpm_clk_enable(chip); - if (chip->locality == -1) { - ret = tpm_request_locality(chip); - if (ret) { - tpm_clk_disable(chip); - return ret; - } - } - ret = tpm_cmd_ready(chip); if (ret) { - tpm_relinquish_locality(chip); tpm_clk_disable(chip); return ret; } @@ -133,7 +95,6 @@ EXPORT_SYMBOL_GPL(tpm_chip_start); void tpm_chip_stop(struct tpm_chip *chip) { tpm_go_idle(chip); - tpm_relinquish_locality(chip); tpm_clk_disable(chip); } EXPORT_SYMBOL_GPL(tpm_chip_stop); @@ -392,7 +353,6 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev, goto out; } - chip->locality = -1; return chip; out: diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index a12992ae2a3e..f892b1ae46f2 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -626,9 +626,6 @@ static int probe_itpm(struct tpm_chip *chip) if (vendor != TPM_VID_INTEL) return 0; - if (request_locality(chip, 0) != 0) - return -EBUSY; - rc = tpm_tis_send_data(chip, cmd_getticks, len); if (rc == 0) goto out; @@ -647,7 +644,6 @@ static int probe_itpm(struct tpm_chip *chip) out: tpm_tis_ready(chip); - release_locality(chip, priv->locality); return rc; } @@ -707,22 +703,13 @@ static int tpm_tis_gen_interrupt(struct tpm_chip *chip) const char *desc = "attempting to generate an interrupt"; u32 cap2; cap_t cap; - int ret; /* TPM 2.0 */ if (chip->flags & TPM_CHIP_FLAG_TPM2) return tpm2_get_tpm_pt(chip, 0x100, &cap2, desc); /* TPM 1.2 */ - ret = request_locality(chip, 0); - if (ret < 0) - return ret; - - ret = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, 0); - - release_locality(chip, 0); - - return ret; + return tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, 0); } /* Register the IRQ and issue a command that will cause an interrupt. If an @@ -836,6 +823,7 @@ void tpm_tis_remove(struct tpm_chip *chip) tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt); + release_locality(chip, 0); tpm_tis_clkrun_enable(chip, false); if (priv->ilb_base_addr) @@ -963,6 +951,14 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, goto out_err; } + rc = request_locality(chip, 0); + if (rc) + goto out_err; + + rc = tpm_chip_start(chip); + if (rc) + goto out_err; + /* Take control of the TPM's interrupt hardware and shut it off */ rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); if (rc < 0) @@ -973,9 +969,6 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, intmask &= ~TPM_GLOBAL_INT_ENABLE; tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); - rc = tpm_chip_start(chip); - if (rc) - goto out_err; rc = tpm2_probe(chip); tpm_chip_stop(chip); if (rc) @@ -1036,15 +1029,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, * to make sure it works. May as well use that command to set the * proper timeouts for the driver. */ - - rc = request_locality(chip, 0); - if (rc < 0) - goto out_err; - rc = tpm_get_timeouts(chip); - - release_locality(chip, 0); - if (rc) { dev_err(dev, "Could not get TPM timeouts and durations\n"); rc = -ENODEV; diff --git a/include/linux/tpm.h b/include/linux/tpm.h index aa11fe323c56..7a68832b14bb 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -167,9 +167,6 @@ struct tpm_chip { u32 last_cc; u32 nr_commands; u32 *cc_attrs_tbl; - - /* active locality */ - int locality; }; #define TPM_HEADER_SIZE 10 From patchwork Sat May 1 13:57:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lino Sanfilippo X-Patchwork-Id: 12234779 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.0 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,MIME_BASE64_TEXT,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6BE05C43462 for ; Sat, 1 May 2021 14:01:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4778161490 for ; Sat, 1 May 2021 14:01:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232221AbhEAOCa (ORCPT ); Sat, 1 May 2021 10:02:30 -0400 Received: from mout.gmx.net ([212.227.17.20]:49087 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232140AbhEAOC2 (ORCPT ); Sat, 1 May 2021 10:02:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1619877686; bh=lEnhpjZ+znlO1ZnV5MAE8GdtbsR6C94Oj7Iakb1AGyI=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=ExRfJTjfDxQ3Ko70K9QAc1UgVn9LnPFZTjxLIEWAMnnxuU3bdlX+wDJ5XkEjH/n5o wgGwQWMJq7PTH/XBP+rfVdZwb+2/27jJhkACuj5NpoD2/nDE6SCXXcBv5lXtv8mj5M rTCf5iNtd2BOt27lYuhAnYdkK79dFu1dkFsMflcg= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from Venus.fritz.box ([78.42.220.31]) by mail.gmx.net (mrgmx105 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MIdeX-1log0R1qE9-00EZeS; Sat, 01 May 2021 16:01:26 +0200 From: Lino Sanfilippo To: peterhuewe@gmx.de, jarkko@kernel.org, jgg@ziepe.ca Cc: stefanb@linux.vnet.ibm.com, James.Bottomley@hansenpartnership.com, keescook@chromium.org, jsnitsel@redhat.com, ml.linux@elloe.vision, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, LinoSanfilippo@gmx.de Subject: [PATCH v3 3/4] tpm: Fix test for interrupts Date: Sat, 1 May 2021 15:57:26 +0200 Message-Id: <20210501135727.17747-4-LinoSanfilippo@gmx.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210501135727.17747-1-LinoSanfilippo@gmx.de> References: <20210501135727.17747-1-LinoSanfilippo@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:pkJ6n0bxD0cRXPv3x5vyWUrjX+bK8V5NwyJdidUorOLurXXTtwW Hc5+7gF7h0asbnD2LngG7dbEq3vL6Hs809eI4ZAFr1VJA4K7yQ4trtQ7liZEKLHAU8fS8Uq YNT/ImGl3yqqnrb57j8zeW7XA2RHpiGia7y3BfWNWhQA06gOA+QdwViUhs53Z552CunSdce SavIyyt9DZpXSdPbCv2gw== X-UI-Out-Filterresults: notjunk:1;V03:K0:HMRyxnvOXWM=:VMDRj4WKl8rVBIvmbwEhbs z4r8YeBHCHLKlKql5nCbL5VPV8lj2AiJbmnQHAJG803b/y2T0SDHKd+RklbapRSERr/w8Grvl 2GaLNtRqpCKPaRGldCyCLwTtQ3fXP41yjJOuokGz8T35hZiYR9uMdo3HK8HFjkk5m2eyM/icW m1JMYRWqNRJaI1dw54Qxm18BAD09tD/eETSH4y2QLdn/yfmKXVACWjcuXtuKwKB5yTSTx3vi5 hmm5eX1NB0sji075CT7zRl5jvzTaxjmG2xwAH3RzI04Su0SjLxuKXzzq19h0obt+pjo1PuxbW C6lSFNhaHtSMDlTZjzFGtbhmOX83ApW9+ZMvlmZBnMBXYBMmK5RnXx5C5k4Jo+3b/JwDq6tiz Z3oLcx9YUILyQ4urqrQyBLy6VI7wiiXSlS0bNUb757xAq5G/gg998EZlEIG7ArnqRtJTunzMn Ui/kBQ4eMsvtEEJ4aejwP0cFM4wFqHsVW8P5MqFLpv52OGYewks2Aas0Afs0KAGKVOjgwB0Sv RIPhiiYax5Qrcf7+zz0bGlHgUMNaAjv/5/+EpunT4KER5iYAo5WTHkMAcPKYPNWJn0haftyba AQbqgze6DdjdjNG2yevsPVcAyPXodUMfXmj5S60WdjRNadNCj4UEItYw7bI2B5yA3yTi4YPTR oUpk+Ftn54mXL2kYgWaJHgBn3xhZ6B6CVgdEFqOyP9EIfTPC1Zed1/Ge73CZs9b1Hjwqivvu+ kaX0KtqyfbKia/AN7I6vNEZabPY1Kn2zikN02La8LD4i1ZDaeamXXb6N2jdu9RqCroX0MlVRJ yIlgXvvQtHHITY6BsNmkr3N3tWj6H4IcmdFr8oYXo0l0viUhSeB7/C6qvrP3nHjzP80uZnHTA yPBnW8ZyutKNpe0SGKmlXvFYiK9QYXnzHSmH41C7ObMcXwnXs3pGwHedXdHJ7+w+OsUoA90OZ jkfIBwIzdyN4trDFpYULuq02Jp49Pl109NOJiWb9xqdfPS7+sAS/7f8/ZPHnIAs5aNf5axUbT AjMhh0yD4mjr0dbULQu8y5IVmlcemsErz4EeSvCPjyTQ20XhIbSxpgfwRSoiVQvQ0mPo5AJ4d CjWjDFv70gfKw9OtWvB+fBefN283ca5QdWlIN6Ja+uSZL5Nez2D6wxzL1wNWJ72Yh+CBmQrLb z1XCj8tR1RDtUfbRwKBcIMGJ0l4CiDMWEiEZgo4ibU/qJrgRChJXVaFDXN2sntMvvH9WZh3Vy ZsQZ/eKf9ijopVVoI Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org The current test for functional interrupts is broken in multiple ways: 1. The needed flag TPM_CHIP_FLAG_IRQ is never set, so the test is never executed. 2. The test includes the check for two variables and the check is done for each transmission which is unnecessarily complicated. 3. Part of the test is setting a bool variable in an interrupt handler and then check the value in the main thread. However there is nothing that guarantees the visibility of the value set in the interrupt handler for any other thread. Some kind of synchronization primitive is required for this purpose. Fix all these issues by a reimplementation: Instead of doing the test in tpm_tis_send() which is called for each transmission do it only once in tpm_tis_probe_irq_single(). Furthermore use proper accessor functions like get_bit()/set_bit() which include the required synchronization primitives to guarantee visibility between the interrupt handler and threads. Finally remove one function which is no longer needed. Signed-off-by: Lino Sanfilippo --- drivers/char/tpm/tpm_tis_core.c | 61 ++++++++++----------------------- drivers/char/tpm/tpm_tis_core.h | 1 - include/linux/tpm.h | 2 +- 3 files changed, 20 insertions(+), 44 deletions(-) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index f892b1ae46f2..9615234054aa 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -420,7 +420,7 @@ static void disable_interrupts(struct tpm_chip *chip) * tpm.c can skip polling for the data to be available as the interrupt is * waited for here */ -static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len) +static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) { struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); int rc; @@ -453,29 +453,6 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len) return rc; } -static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) -{ - int rc, irq; - struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); - - if (!(chip->flags & TPM_CHIP_FLAG_IRQ) || priv->irq_tested) - return tpm_tis_send_main(chip, buf, len); - - /* Verify receipt of the expected IRQ */ - irq = priv->irq; - priv->irq = 0; - chip->flags &= ~TPM_CHIP_FLAG_IRQ; - rc = tpm_tis_send_main(chip, buf, len); - priv->irq = irq; - chip->flags |= TPM_CHIP_FLAG_IRQ; - if (!priv->irq_tested) - tpm_msleep(1); - if (!priv->irq_tested) - disable_interrupts(chip); - priv->irq_tested = true; - return rc; -} - struct tis_vendor_durations_override { u32 did_vid; struct tpm1_version version; @@ -677,7 +654,8 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id) if (interrupt == 0) return IRQ_NONE; - priv->irq_tested = true; + set_bit(TPM_CHIP_FLAG_IRQ, &chip->flags); + if (interrupt & TPM_INTF_DATA_AVAIL_INT) wake_up_interruptible(&priv->read_queue); if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT) @@ -734,45 +712,44 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask, } priv->irq = irq; + clear_bit(TPM_CHIP_FLAG_IRQ, &chip->flags); + rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality), &original_int_vec); if (rc < 0) - return rc; + goto out; rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), irq); if (rc < 0) - return rc; + goto out; rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status); if (rc < 0) - return rc; + goto out; /* Clear all existing */ rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status); if (rc < 0) - return rc; + goto out; /* Turn on */ rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask | TPM_GLOBAL_INT_ENABLE); if (rc < 0) - return rc; - - priv->irq_tested = false; + goto out; - /* Generate an interrupt by having the core call through to - * tpm_tis_send - */ + /* Generate an interrupt by transmitting a command to the chip */ rc = tpm_tis_gen_interrupt(chip); if (rc < 0) - return rc; + goto out; + + tpm_msleep(1); +out: + if (!test_bit(TPM_CHIP_FLAG_IRQ, &chip->flags)) { + disable_interrupts(chip); - /* tpm_tis_send will either confirm the interrupt is working or it - * will call disable_irq which undoes all of the above. - */ - if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) { rc = tpm_tis_write8(priv, original_int_vec, - TPM_INT_VECTOR(priv->locality)); + TPM_INT_VECTOR(priv->locality)); if (rc < 0) return rc; @@ -1039,7 +1016,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, if (irq) { tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED, irq); - if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) { + if (!test_bit(TPM_CHIP_FLAG_IRQ, &chip->flags)) { dev_err(&chip->dev, FW_BUG "TPM interrupt not working, polling instead\n"); diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h index 9b2d32a59f67..dc5f92b18dca 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h @@ -89,7 +89,6 @@ struct tpm_tis_data { u16 manufacturer_id; int locality; int irq; - bool irq_tested; unsigned int flags; void __iomem *ilb_base_addr; u16 clkrun_enabled; diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 7a68832b14bb..c57d0f0395f0 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -133,7 +133,7 @@ struct tpm_chip { struct tpm_chip_seqops bin_log_seqops; struct tpm_chip_seqops ascii_log_seqops; - unsigned int flags; + unsigned long flags; int dev_num; /* /dev/tpm# */ unsigned long is_open; /* only one allowed */ From patchwork Sat May 1 13:57:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lino Sanfilippo X-Patchwork-Id: 12234781 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.0 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,MIME_BASE64_TEXT,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9AB4AC43470 for ; Sat, 1 May 2021 14:01:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 758BC61490 for ; Sat, 1 May 2021 14:01:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231876AbhEAOCa (ORCPT ); Sat, 1 May 2021 10:02:30 -0400 Received: from mout.gmx.net ([212.227.17.20]:52145 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232138AbhEAOC2 (ORCPT ); Sat, 1 May 2021 10:02:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1619877687; bh=bdgo8J4TivRhaCR1yMOLb0GbU9YLD5pDkm2mF7GPaks=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=FUnpwhDN0gy0rPzqdmRT8cm82auiNAPkUBlJrN7Al9fLpJEqrPPfRrM9s7zaqCVeA UyINw8uNkbl2askCsqW9QHmi6WSpD4/t9ko07je8Y9qkjs6wUy2plyI+yklz7utNaC JCOlBTLrggeon6DR6pO+2AYSxB5CPfMFybVEMKZ0= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from Venus.fritz.box ([78.42.220.31]) by mail.gmx.net (mrgmx105 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MRmjq-1m1XnY3dBy-00TFYd; Sat, 01 May 2021 16:01:26 +0200 From: Lino Sanfilippo To: peterhuewe@gmx.de, jarkko@kernel.org, jgg@ziepe.ca Cc: stefanb@linux.vnet.ibm.com, James.Bottomley@hansenpartnership.com, keescook@chromium.org, jsnitsel@redhat.com, ml.linux@elloe.vision, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, LinoSanfilippo@gmx.de Subject: [PATCH v3 4/4] tpm: Only enable supported irqs Date: Sat, 1 May 2021 15:57:27 +0200 Message-Id: <20210501135727.17747-5-LinoSanfilippo@gmx.de> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210501135727.17747-1-LinoSanfilippo@gmx.de> References: <20210501135727.17747-1-LinoSanfilippo@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:7jLZxRXA8T/g7l9AnnNL9N15FTgU/ED0fMkRffZPiEVIKMk8H6l 4X2OqvLjhjaG6s6fkYNfNuWQww3zrkZzde7/xLfUaMhWVaAAMXPDnzgo4XjVsoY0kwMJfy0 NH5GvynI8/dbk306ZAKprQ9K2YdEQMevdCHxvbCa2wfqCCSXJfS/eMjc4/wb3Ia9j+tZBsk 7k0X1iOL+32wdxXWq78lg== X-UI-Out-Filterresults: notjunk:1;V03:K0:I/0z9n93ojk=:J5OZzIFHBaL8NZeZJPq1dZ 3tQ3reOr3iY1hWsl1oOWQmxMqY0YfTbkogEN/dRtlI7uzyVGuXojb7CYV/dQlGUY9kfzKy0Z4 F2XmICtP3T9B02wEdCk5yy0T/N5ELxdf0TSCtRToNJDpMbShdhBS7j9/bapJndZpLWzb8oZKg SG62ZTkrNYmp7bYlkOcg82WrvTYv9i4g8mYyByxUoWCpmL5wR0QOoK/Zqk0GSwVDFrUyTzJSx 6ciZe1ibX/Uva6BTpR/At4WSqvY5SULs5s03vdH2dnqZJnfNacVjcH4fwjkD1OM90R8uC3aXn KtdW8HW/ow1HclaEK4kHrGi1N16GeykltbNvOp/50BgvAU+bzoiRpHvOHJPP14glhEJfq+2pD xW2HcEqzGiIc4GM9JvLIKN4aBfHYSbbUd+kDjjQxXw/i8USXIC057QMtTIyV6urwKRbCrqKhG WPpLRaRNVldBXbW60Mfq7lC8TgMglGuY5+x3yyAeF7Zvrc5O31vG1XxbaTva1kKXk+dfudZFT JSboEEjKeNoiNPhsIlKmWxUyKdBfECbDfsc3+3T9+IFZfJKwpe+7eITO304K5Xhl2jiy0tRul gr3WQek7A+WrLQzuRCnDmMM/trN+5OxK3z5/NA9F2+tggNP+YT20MkMmkRY5c7A6rdIJusB/e R4LFdR9bHKYNqo/ALK6hzHEO4qCcAnWRwyO4izQRktnb+OeI2HYbjxIQMZ/jXoOL6BYBpco6+ 51tmg5G8OD80Lt2vO4eh6HPW2YOrMH6LVlrmvJAikPAurrtEZezf0BKAXPmiUzm+2EDU7it8+ Mj8Fogv4z00AXAgCLi42s/TXjt2J77/SKPF8A0EYGKYhxvP2bfRP/yt23N6rweuyHWw4LVgSp pWt+3y4i/rzYsF8Ox6QEV87X9qyIoEy4mzv3FA2s003PKKXeg03J0srjU9Jb+HP63ngONvduF /VluQqV/TZVyBc6TT2bCFvVKh6TWA4lvJ4eWuymkBZVOpK3PPdCWygAczxNlWyFvGMElS0xgE aDMef8KWJpXs/ac0D7ahZGcHh3rc1UIgPGxHltPTJemZZoTn0bUQR43IwnzdVKhijNv7kKzVe J+p2DT+zpKlyi2Lz1pWFFZ2fWwmF3qiFCIp/VOSK0tABB1ERTw9xZPWG5NoCp47NeLSi0ZPzZ XEGzMOduJhdlgqvfMtNksXx3a+e8xSrde3hLw43UuWV/9w8kuev6lQPynMs1A97DCcdyCZpUD 2i7F79qOcEWbTzarb Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org Do not set interrupts which are not supported by the hardware. Instead use the information from the capability query and activate only the reported interrupts. Signed-off-by: Lino Sanfilippo Reviewed-by: Stefan Berger --- drivers/char/tpm/tpm_tis_core.c | 68 ++++++++++++++++++--------------- drivers/char/tpm/tpm_tis_core.h | 1 + 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 9615234054aa..757498a63f57 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -936,13 +936,47 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, if (rc) 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) { + priv->supported_irqs |= 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) { + priv->supported_irqs |= TPM_INTF_LOCALITY_CHANGE_INT; + dev_dbg(dev, "\tLocality Change Int Support\n"); + } + if (intfcaps & TPM_INTF_STS_VALID_INT) { + priv->supported_irqs |= TPM_INTF_STS_VALID_INT; + dev_dbg(dev, "\tSts Valid Int Support\n"); + } + if (intfcaps & TPM_INTF_DATA_AVAIL_INT) { + priv->supported_irqs |= TPM_INTF_DATA_AVAIL_INT; + dev_dbg(dev, "\tData Avail Int Support\n"); + } + /* Take control of the TPM's interrupt hardware and shut it off */ rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); 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; + intmask |= priv->supported_irqs; + intmask &= ~TPM_GLOBAL_INT_ENABLE; tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); @@ -971,32 +1005,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); @@ -1066,9 +1074,7 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) 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->supported_irqs | 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 dc5f92b18dca..8ff62213d8fc 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h @@ -89,6 +89,7 @@ struct tpm_tis_data { u16 manufacturer_id; int locality; int irq; + unsigned int supported_irqs; unsigned int flags; void __iomem *ilb_base_addr; u16 clkrun_enabled;