From patchwork Thu Jul 13 19:01:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lino Sanfilippo X-Patchwork-Id: 13312583 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AF2D1C001B0 for ; Thu, 13 Jul 2023 19:01:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232735AbjGMTBa (ORCPT ); Thu, 13 Jul 2023 15:01:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53012 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229949AbjGMTB3 (ORCPT ); Thu, 13 Jul 2023 15:01:29 -0400 Received: from EUR04-HE1-obe.outbound.protection.outlook.com (mail-he1eur04on2047.outbound.protection.outlook.com [40.107.7.47]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 126062D57; Thu, 13 Jul 2023 12:01:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=a1t3dlcly8kaqNNfdCEM9zt8QUgtD43JKguFyD0jjt9SBj11yP4dOG4PjYbV0BSEUJLsXNcUfqguLI2z9jVBiyUIo/N+enNYp1miY0YrhN7QVa0oI3FeX5MeYZk/TUhv6RXthXhdgzaVbe4ZvmCQXsilVi2Tst6+/0lW9enHzfQfo2/OF49tx8MBrWsT8wWlhuuBAjmnKe5IQIAJH77vuEIzEL9OdkJTaA8srQL4vfIKAGWcLN0dFEZFugYXPM0hHA+z8jCFN7LbjXMRhyxwMbgWWZtyJ6bjTNQ2XVVgwBZWG1F0m/KQpWI8SLcnecah8+mhz8L7hTk5jXmPgAA/SQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=PLbBhGQ7XQST2BkZU7eX/+ZZ4ZPOscFyubd3rVtKgkc=; b=g2tKWn438G8ciT/fdVWYKkskOq+5PAQ8LEi4+R8Yd6e/C05qG6vJC6BpxUQe37+bw0a2Pso82LiMzVOC/1VYzWzHlo8VLSCixqnz8XaSg1cyysaFysz4Zaz7a+UzFCaHrZu7gDoA5kWa8vespJLpEcQTd5pw4Y2mLGL8JhXYod4H/yOawSnkptz+aIFuH30Go3j3uCs9Fk9ja+2u1ZwFaHHDiwPjnE7c1lOuDj656mui2teG11lc0kufILd3RoqbNeP+cIYCuNK4ezHYnZKgTcsUI+56b7ZpmdBNuKk7l4B85m6dSQGfAcyd9XzSMEFZ1hNXe4BD+dKfEF1MR9ybRA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=kunbus.com; dmarc=pass action=none header.from=kunbus.com; dkim=pass header.d=kunbus.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kunbus.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=PLbBhGQ7XQST2BkZU7eX/+ZZ4ZPOscFyubd3rVtKgkc=; b=GOELfHLxOFKU1zwvVAqUimoDewu/aLZn4n/UvvZgUJDEfFDUHiZwp5ZVUfqvH6zg6k2eP+6QJW8ZmHW6PI7LIePx+h48xuNAxudMGQWcUR3FHdz51bYrlABY+gmsSSzRms810rwFHdoIWcooSuiT589RZKZLI7AZ6aQ5TGKPhRk= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=kunbus.com; Received: from VI1P193MB0413.EURP193.PROD.OUTLOOK.COM (2603:10a6:803:4e::14) by AM9P193MB1956.EURP193.PROD.OUTLOOK.COM (2603:10a6:20b:302::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6588.26; Thu, 13 Jul 2023 19:01:20 +0000 Received: from VI1P193MB0413.EURP193.PROD.OUTLOOK.COM ([fe80::33e5:1608:50a0:38a7]) by VI1P193MB0413.EURP193.PROD.OUTLOOK.COM ([fe80::33e5:1608:50a0:38a7%3]) with mapi id 15.20.6588.024; Thu, 13 Jul 2023 19:01:20 +0000 Message-ID: <144f1c66-499e-2da9-c4c1-b5f26cb8841f@kunbus.com> Date: Thu, 13 Jul 2023 21:01:08 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 Content-Language: en-US From: Lino Sanfilippo Subject: [PATCH v4 RESEND] tpm,tpm_tis: Disable interrupts after 1000 unhandled IRQs To: Peter Huewe , Jarkko Sakkinen , Jason Gunthorpe Cc: jsnitsel@redhat.com, hdegoede@redhat.com, oe-lkp@lists.linux.dev, lkp@intel.com, =?utf-8?q?P=C3=A9ter_Ujfalusi?= , peterz@infradead.org, =?utf-8?q?Michael_Niew=C3=B6hner?= , Linux Kernel Integrity , LKML , Lino Sanfilippo , Lino Sanfilippo , Lukas Wunner , Philipp Rosenberger X-ClientProxiedBy: KL1P15301CA0063.APCP153.PROD.OUTLOOK.COM (2603:1096:820:3d::21) To VI1P193MB0413.EURP193.PROD.OUTLOOK.COM (2603:10a6:803:4e::14) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: VI1P193MB0413:EE_|AM9P193MB1956:EE_ X-MS-Office365-Filtering-Correlation-Id: 42f15737-6c76-4525-f16a-08db83d38b2f X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: C9T+3ngRczgmdEBUyZYwspRb2zGfV9PYcuCpCqBkvAUMLL4NNvEu6Ey0Oth+NwyLJl4AuRCuu6Eg/FiT8SfmUudJncjnw8AHKAycc+s/eNEoCpPrmLatVFzL29DZbbT8nY/29RmPR5OUzo8H+CUufJzMKQO5KoXe3B5Tj/Ty6rg+ZBYkrPVTWvCvW75zDinll4/EkI0kx40nz58B6y1xAo9r9rxLkkdoDeaZr0IWfyp+v6nG4W5vMarDfmR7aCDVZAHpc9GE42ZbMWk7aUxpfMfFIkD3GsPtHVi4575gjjEh6Of7inmP7iLF3IP4R/fm56D0B9aRbPFxbf4CzYE0+gJJq8VicNxS645OWerc4gUcdDSoKT0HI7ds+eRRHKiUJ2oFoh/suprbWyO9V1KQLj1JZPRoXBpeWNLCElUKTovuWu6FmYB2q8PuxZFM2h1BDbRZJvZ1G0G7AylmKJPclicTBmu2ZaaSJ2AG4rCPzE+d/vyQb4b5xe2Uehi3mMGk+nPj0EnhSRevDu6sOWcqkMP7stNJOCCa1WXLmRDnqsYWsoeXPWQ7yF5PSfiAzelhjaiD0YrGEJNGabWyXuWI7iGpX7hor2fyaKqOB+ooazMfq0S6q6BbHr2hEdTWKeuSmh2jTaTO8pqRE3VbwLQikeTHPfSWUM6d6Ovc8geTvS1oM4k0gouHWBy1c5v90Iz3 X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:VI1P193MB0413.EURP193.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230028)(4636009)(396003)(366004)(39840400004)(346002)(376002)(136003)(451199021)(83380400001)(2906002)(2616005)(66476007)(6486002)(4326008)(66556008)(66946007)(316002)(966005)(6512007)(52116002)(478600001)(6666004)(110136005)(54906003)(5660300002)(26005)(6506007)(107886003)(186003)(7416002)(8676002)(41300700001)(8936002)(38100700002)(38350700002)(31696002)(86362001)(36756003)(31686004)(221023011)(45980500001)(43740500002);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?z5QE/xC7oIB4vrYN+UfeVKkz3GW+?= =?utf-8?q?9PC0Sdm3Qv6VRC6RW6l2MhvYaAEvfLOLiiAFTJdcWz6IcudKoGB5vKIhwBSEJieR1?= =?utf-8?q?yNOfg9y493EC+87HD4GawSI/QTU5HlVO9OJ8fxY0w3uYZHuLYm3zIK+J8jdjABfgk?= =?utf-8?q?n5RqvR5P6oPbELv2dzlM2C6RWHtTOjR8Xc/6cku+28N3LssZGsP3NB2DbaZHpXFvK?= =?utf-8?q?tKQ+fdWUBa89jPllM+qpzXltN7iCWu98sQgPhb/8eCxDFxVnpv4Ol6k7HMtkU7EaU?= =?utf-8?q?FaIhjGCmt3It/5NUxXfknDRMGZ+1vhZmFisDJZb5SkDoJ1v+5TjuemIfTR3iz65WS?= =?utf-8?q?RjyCZ1RLDIlv9HdDHbtKxjGeWJctmcg2+vnslhKZD87z+YptGo7exrXf9VH54yzak?= =?utf-8?q?cIKYAUWU/s3LCoEcIGut3VeV6XYgixWLpx7fu6zJNRXF4voiemrXpOw2V9ayBDqtC?= =?utf-8?q?V0vAspGRgJJ5jlN2kFK9SlorrxxufyN7Ygpq7q80hF/iRKwVHULyHsQAVaodaIxcH?= =?utf-8?q?FlF/QGc0bxAE630pr9FBY3qgkC8Pi9xlzhWNUhENrN+1NAytjTTn56Ixf1kTC7qR6?= =?utf-8?q?cnHAa7jN70F2EmThOlEtV3lUIEQjTgjAfzxjK+YMzLwSuUGjKq6bGJdWUY/VOxhe2?= =?utf-8?q?aVYwYsKvtxYnLW+LQ1+7CHAJEhqVMgqpNuf8/IzlaIOLX+Tf42n4jThMMJAmH9fNy?= =?utf-8?q?Xw3EOxUcnvt7HVf2j5YyQkn4OwysnbREbHvywjkyuzH6j2dW/ai57F2MTxog8tmg5?= =?utf-8?q?ZN5YFeTJhl+FYd/I4yqbjka7BgCusATI3PXdRF7BJaDnlWl3Wt9cY43C0nVkP+pn+?= =?utf-8?q?Bc0Pc/xkn+xYZVrygYE++AlogPvv549KUIfkVp42PI7o3FqVNpHjCB55PIXjUpzdI?= =?utf-8?q?ewkMUtg9M+xRk93KbXS0753XgOJXPh48VdCK+3+UmFY0cgub/U1+ZTs4I7vliNxii?= =?utf-8?q?9pxonubScua6sdNY49O5lgRxXJuMd1jzkVmJz9NcyYYJ6N4if0SvxbE+gYo8d708x?= =?utf-8?q?q8qX9mJScE5ahqnVnenWxXcA41xqtDx57+p3uYaJEUC8gB3zlQetujVkS59SCrxHE?= =?utf-8?q?ZBQ0OIqpBNOa/DMF0iP+7DC9OLVOLgeQYz6xs8t3oPjacVGZAXDrEJ+UQG1LzxNOx?= =?utf-8?q?AqsXkH3lImpMG2AAak8KNXMtmoIkWv1L0QJkzZIil98fiulW2x/sQctB6UBWMr/I3?= =?utf-8?q?5yJaSS8AslMlsSPzbR31qt/2tPsvWDCILsX/2749ZffGfIRuucE4Thefml9ldMJgd?= =?utf-8?q?i3WdixX7FT4UUNCOhJT6Zac/E0v58c5pIgwRCJO5tz6bdtFy0/+qJE9QJaponht5Q?= =?utf-8?q?he3vyxUtYTDoUeArJdPYhToklZKrJESf95Vyv6Y4bfhEFsqk25b8CoXi3RbAmQR4k?= =?utf-8?q?qAy3gUUxDLrHvHEqb8D9bTUDXEiC7zEYeYeb46v7MnmPSVG5CRggoawpCifWLW6AS?= =?utf-8?q?OYmkVe5ZWCIiaNVZwB/EmH9GLx0KpBY1eAYNHLPCCS2B4hOGxq6HVq2Wf0GyLteLA?= =?utf-8?q?mCmvT1uqc771oaZG89GjQkWLOVZsQX+UhQ=3D=3D?= X-OriginatorOrg: kunbus.com X-MS-Exchange-CrossTenant-Network-Message-Id: 42f15737-6c76-4525-f16a-08db83d38b2f X-MS-Exchange-CrossTenant-AuthSource: VI1P193MB0413.EURP193.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Jul 2023 19:01:20.1808 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: aaa4d814-e659-4b0a-9698-1c671f11520b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 5s4YgOTV/tdeH3/4xGSxDjlLEcxj4lAy+KkhIiYcoZG6qk0Y5hwvr8DtYwmHpcJT3eSXVLvKZzR1DsTo4v0kjQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM9P193MB1956 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org After activation of interrupts for TPM TIS drivers 0-day reports an interrupt storm on an Inspur NF5180M6 server. Fix this by detecting the storm and falling back to polling: Count the number of unhandled interrupts within a 10 ms time interval. In case that more than 1000 were unhandled deactivate interrupts entirely, deregister the handler and use polling instead. Also print a note to point to the tpm_tis_dmi_table. Since the interrupt deregistration function devm_free_irq() waits for all interrupt handlers to finish, only trigger a worker in the interrupt handler and do the unregistration in the worker to avoid a deadlock. Note: the storm detection logic equals the implementation in note_interrupt() which uses timestamps and counters stored in struct irq_desc. Since this structure is private to the generic interrupt core the TPM TIS core uses its own timestamps and counters. Furthermore the TPM interrupt handler always returns IRQ_HANDLED to prevent the generic interrupt core from processing the interrupt storm. Fixes: e644b2f498d2 ("tpm, tpm_tis: Enable interrupt test") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-lkp/202305041325.ae8b0c43-yujie.liu@intel.com/ Suggested-by: Lukas Wunner Signed-off-by: Lino Sanfilippo Reviewed-by: Jarkko Sakkinen --- drivers/char/tpm/tpm_tis_core.c | 103 +++++++++++++++++++++++++++----- drivers/char/tpm/tpm_tis_core.h | 4 ++ 2 files changed, 92 insertions(+), 15 deletions(-) Resending the patch due to several bounce messages for the first attempt. Changes to v3 (all requested by Jarko): - remove all inline comments - rename tpm_tis_reenable_polling() to tpm_tis_revert_interrupts() - rename tpm_tis_check_for_interrupt_storm() to tpm_tis_update_unhandled_irqs() - rename label "unhandled" to "err" - add Fixes: tag Changes to v2: - use define for max number of unhandles irqs(requested by Jarko) - rename intmask to int_mask (requested by Jarko) - rephrased short summary (requested by Jarko) - rename disable_interrupts to tpm_tis_disable_interrupts (requested by Jarko) - print info message concerning adding an entry to tpm_tis_dmi_table (suggested by Jerry) - amended commit message - handle failure of locality request by returning IRQ_NONE - dont take and release locality in __tpm_tis_disable_interrupts but in its caller base-commit: 6995e2de6891c724bfeb2db33d7b87775f913ad1 diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 558144fa707a..88a5384c09c0 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -24,9 +24,12 @@ #include #include #include +#include #include "tpm.h" #include "tpm_tis_core.h" +#define TPM_TIS_MAX_UNHANDLED_IRQS 1000 + static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value); static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, @@ -468,25 +471,29 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len) return rc; } -static void disable_interrupts(struct tpm_chip *chip) +static void __tpm_tis_disable_interrupts(struct tpm_chip *chip) +{ + struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); + u32 int_mask = 0; + + tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &int_mask); + int_mask &= ~TPM_GLOBAL_INT_ENABLE; + tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), int_mask); + + chip->flags &= ~TPM_CHIP_FLAG_IRQ; +} + +static void tpm_tis_disable_interrupts(struct tpm_chip *chip) { struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); - u32 intmask; - int rc; if (priv->irq == 0) return; - rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); - if (rc < 0) - intmask = 0; - - intmask &= ~TPM_GLOBAL_INT_ENABLE; - rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); + __tpm_tis_disable_interrupts(chip); devm_free_irq(chip->dev.parent, priv->irq, chip); priv->irq = 0; - chip->flags &= ~TPM_CHIP_FLAG_IRQ; } /* @@ -552,7 +559,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) if (!test_bit(TPM_TIS_IRQ_TESTED, &priv->flags)) tpm_msleep(1); if (!test_bit(TPM_TIS_IRQ_TESTED, &priv->flags)) - disable_interrupts(chip); + tpm_tis_disable_interrupts(chip); set_bit(TPM_TIS_IRQ_TESTED, &priv->flags); return rc; } @@ -752,6 +759,57 @@ static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status) return status == TPM_STS_COMMAND_READY; } +static irqreturn_t tpm_tis_revert_interrupts(struct tpm_chip *chip) +{ + struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); + const char *product; + const char *vendor; + + dev_warn(&chip->dev, FW_BUG + "TPM interrupt storm detected, polling instead\n"); + + vendor = dmi_get_system_info(DMI_SYS_VENDOR); + product = dmi_get_system_info(DMI_PRODUCT_VERSION); + + if (vendor && product) { + dev_info(&chip->dev, + "Consider adding the following entry to tpm_tis_dmi_table:\n"); + dev_info(&chip->dev, "\tDMI_SYS_VENDOR: %s\n", vendor); + dev_info(&chip->dev, "\tDMI_PRODUCT_VERSION: %s\n", product); + } + + if (tpm_tis_request_locality(chip, 0) != 0) + return IRQ_NONE; + + __tpm_tis_disable_interrupts(chip); + tpm_tis_relinquish_locality(chip, 0); + + schedule_work(&priv->free_irq_work); + + return IRQ_HANDLED; +} + +static irqreturn_t tpm_tis_update_unhandled_irqs(struct tpm_chip *chip) +{ + struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); + irqreturn_t irqret = IRQ_HANDLED; + + if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) + return IRQ_HANDLED; + + if (time_after(jiffies, priv->last_unhandled_irq + HZ/10)) + priv->unhandled_irqs = 1; + else + priv->unhandled_irqs++; + + priv->last_unhandled_irq = jiffies; + + if (priv->unhandled_irqs > TPM_TIS_MAX_UNHANDLED_IRQS) + irqret = tpm_tis_revert_interrupts(chip); + + return irqret; +} + static irqreturn_t tis_int_handler(int dummy, void *dev_id) { struct tpm_chip *chip = dev_id; @@ -761,10 +819,10 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id) rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &interrupt); if (rc < 0) - return IRQ_NONE; + goto err; if (interrupt == 0) - return IRQ_NONE; + goto err; set_bit(TPM_TIS_IRQ_TESTED, &priv->flags); if (interrupt & TPM_INTF_DATA_AVAIL_INT) @@ -780,10 +838,13 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id) rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), interrupt); tpm_tis_relinquish_locality(chip, 0); if (rc < 0) - return IRQ_NONE; + goto err; tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &interrupt); return IRQ_HANDLED; + +err: + return tpm_tis_update_unhandled_irqs(chip); } static void tpm_tis_gen_interrupt(struct tpm_chip *chip) @@ -804,6 +865,15 @@ static void tpm_tis_gen_interrupt(struct tpm_chip *chip) chip->flags &= ~TPM_CHIP_FLAG_IRQ; } +static void tpm_tis_free_irq_func(struct work_struct *work) +{ + struct tpm_tis_data *priv = container_of(work, typeof(*priv), free_irq_work); + struct tpm_chip *chip = priv->chip; + + devm_free_irq(chip->dev.parent, priv->irq, chip); + priv->irq = 0; +} + /* Register the IRQ and issue a command that will cause an interrupt. If an * irq is seen then leave the chip setup for IRQ operation, otherwise reverse * everything and leave in polling mode. Returns 0 on success. @@ -816,6 +886,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask, int rc; u32 int_status; + INIT_WORK(&priv->free_irq_work, tpm_tis_free_irq_func); rc = devm_request_threaded_irq(chip->dev.parent, irq, NULL, tis_int_handler, IRQF_ONESHOT | flags, @@ -918,6 +989,7 @@ void tpm_tis_remove(struct tpm_chip *chip) interrupt = 0; tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt); + flush_work(&priv->free_irq_work); tpm_tis_clkrun_enable(chip, false); @@ -1021,6 +1093,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, chip->timeout_b = msecs_to_jiffies(TIS_TIMEOUT_B_MAX); chip->timeout_c = msecs_to_jiffies(TIS_TIMEOUT_C_MAX); chip->timeout_d = msecs_to_jiffies(TIS_TIMEOUT_D_MAX); + priv->chip = chip; priv->timeout_min = TPM_TIMEOUT_USECS_MIN; priv->timeout_max = TPM_TIMEOUT_USECS_MAX; priv->phy_ops = phy_ops; @@ -1179,7 +1252,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, rc = tpm_tis_request_locality(chip, 0); if (rc < 0) goto out_err; - disable_interrupts(chip); + tpm_tis_disable_interrupts(chip); tpm_tis_relinquish_locality(chip, 0); } } diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h index 610bfadb6acf..b1a169d7d1ca 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h @@ -91,11 +91,15 @@ enum tpm_tis_flags { }; struct tpm_tis_data { + struct tpm_chip *chip; u16 manufacturer_id; struct mutex locality_count_mutex; unsigned int locality_count; int locality; int irq; + struct work_struct free_irq_work; + unsigned long last_unhandled_irq; + unsigned int unhandled_irqs; unsigned int int_mask; unsigned long flags; void __iomem *ilb_base_addr;