From patchwork Mon May 9 08:05:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lino Sanfilippo X-Patchwork-Id: 12843173 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 D987CC433F5 for ; Mon, 9 May 2022 08:45:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237328AbiEIIq3 (ORCPT ); Mon, 9 May 2022 04:46:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235727AbiEIIOx (ORCPT ); Mon, 9 May 2022 04:14:53 -0400 Received: from mout.gmx.net (mout.gmx.net [212.227.17.21]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AA61515D31D; Mon, 9 May 2022 01:10:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1652083627; bh=xOpvZ8BgGCUz6IDaFNm7AWkuquQ2TTNkNVxmdRJZRIo=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=E2vrTJ8P0DxVREsgDXGdGC/uKskZK8QkaM951p2q8ytXOAa41Vx+vtL0AfSCZNxij a/+x9fmIn7/t4Vbdm1+8sy0vG5a+Iik2P1pts7SfpSf35Skolpu3MJlzhdKmc/rrlw drIwxuoi46gCXDqo8bJZlrT87J4ec3/6JtZOpYww= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from Venus.fritz.box ([46.223.3.89]) by mail.gmx.net (mrgmx105 [212.227.17.168]) with ESMTPSA (Nemesis) id 1MbAgq-1oKpCF03EO-00bdkT; Mon, 09 May 2022 10:07:07 +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, LinoSanfilippo@gmx.de, lukas@wunner.de, p.rosenberger@kunbus.com, Lino Sanfilippo Subject: [PATCH v4 4/6] tpm, tpm_tis: avoid CPU cache incoherency in irq test Date: Mon, 9 May 2022 10:05:57 +0200 Message-Id: <20220509080559.4381-5-LinoSanfilippo@gmx.de> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220509080559.4381-1-LinoSanfilippo@gmx.de> References: <20220509080559.4381-1-LinoSanfilippo@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:4t6mWcZUnR8Zow/cWZDz9hnDGH0BwWHhkduqhaFeeoJCNlegYyq WMw8AKELkLhuUBk2KStJnG2/LTrmkD5o41pRVjgn1BE+Ib/UQfnUw9rR76RF1mkrtYJvt63 J46ePcf+TzVHpITclAXsg3LvC4FGnJOLPeQbr6gMk0E9VDgPW+n3p3vPifPHjvvu3gktjQU CPlDj2S0GSPL/Y+hMKgXw== X-UI-Out-Filterresults: notjunk:1;V03:K0:jQrDmr+Dqx4=:XOm0JdT4QTHWTtXnZnVPIZ PvNmeB3ZqMrZ4bMl/ARrVO5VFxPCERk+N6xVIJluiBgC9g4sSd6qvHtPhsFCyYH4ns27A6Jm0 93rcrP24l++IBY7pncbYAN8Z7DI4iRzOcwt3ZFDQ2lpOcx7Y5C+OxQeIHgHTm0+2QC2Q5Ic/P uTeIMmA5p6E4qwSasGjN3dYe9+eNBl7U/Fir8MGvh4XvasuNBqSdhD65aiRRcAKw70J+85aWM CdiPGBbovn0MMwO3ixfYX/bTdBO9lfHZdiig/dawKFoXG66CDoTlNCMeK/mL6Q+PEVfdSwtoK FhrZeLIbMdioCJbZZIZfS8lwEvzgufMa6ftys0i8WDYdBYGq4MAa+vtn5IqsCrN1Ct293edcU fJwmM1p/FYs4PwkgPb+C43EcAgcCXcZdh/rmcMQepLA/cwgYQjEZ8HMKCWm6BnZ13k9fGPOCd cu7bhXD0VAvro0kqeioiaQ+EJlDhETcf5FEevEb+V0cKVemGh5G8Yq6VlFExCpzD/JJVh0KSQ oYSX0QOIkRWjZm8W2ux4WD/MZfT18lNVhwNdsB76DKO2UV5PLRVuUKJ7+X5P1VYIsNL0xypWh zWmhIUyM69UrmAZckLqqtQnf/2oztSnI3FuGDZHkDBunOlrRz/BcR63Xgw4NmTCwT6w2P/Dq0 a0t92kMkckjzjMwF0dxYVk2C2cDNBf7pnISmX+Qppmy3DKJ07ReJha5oYOU1iBrkHmmi70dBF NKUtmvJ4+enKrXHQO+GwoUGRGOCaX9ZUKYnErIBptkwumtEqxUfvDBKiTRznHgN+eGmB7amKr NsnJCNfSy6EZEeeK3qhPy/M9JVH8CRDoncueMLU+ibPM76VN2mJnNCJiXUBcUb6dEbQRr03es FlLnTyDPFtbSiOQg3I0f2m5AymsqzDN2P/2lCHsdhQQyV+67+N6lRmT+kt1lkydKPrfjQCqgs oQuZ3lDi7iVYbEX7RVHTwbDDAY2HqdwmTMf1pH/ngxMHOw3Kh2KfwowtTHebTl2iK+61LgLIi MRyLB67p4ZszC6lls1FFxt6MRCu2e/rBbYjh441/ER7CeHSyR65zViVwf1HhwLYU6HOjbizbT z/FU8od+I6f6vQ= Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org From: Lino Sanfilippo The interrupt handler that sets irq_tested to indicate that interrupts are working may run on another CPU than the thread that checks this variable in tmp_tis_send(). Since no synchronization is used to access irq_tested, there is no guarantee for cache coherency between the CPUs, so that the value set by the interrupt handler might not be visible to the testing thread. Avoid this issue by using a bitfield instead of a boolean variable and by accessing this field with bit manipulating functions that guarantee cache coherency. Signed-off-by: Lino Sanfilippo --- drivers/char/tpm/tpm_tis_core.c | 13 +++++++------ drivers/char/tpm/tpm_tis_core.h | 6 +++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 4f3b82c3f205..bdfde1cd71fe 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -470,7 +470,8 @@ 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) + if (!(chip->flags & TPM_CHIP_FLAG_IRQ) || + test_bit(TPM_TIS_IRQTEST_OK, &priv->irqtest_flags)) return tpm_tis_send_main(chip, buf, len); /* Verify receipt of the expected IRQ */ @@ -480,11 +481,11 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) rc = tpm_tis_send_main(chip, buf, len); priv->irq = irq; chip->flags |= TPM_CHIP_FLAG_IRQ; - if (!priv->irq_tested) + if (!test_bit(TPM_TIS_IRQTEST_OK, &priv->irqtest_flags)) tpm_msleep(1); - if (!priv->irq_tested) + if (!test_bit(TPM_TIS_IRQTEST_OK, &priv->irqtest_flags)) disable_interrupts(chip); - priv->irq_tested = true; + set_bit(TPM_TIS_IRQTEST_OK, &priv->irqtest_flags); return rc; } @@ -689,7 +690,7 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id) if (interrupt == 0) return IRQ_NONE; - priv->irq_tested = true; + set_bit(TPM_TIS_IRQTEST_OK, &priv->irqtest_flags); if (interrupt & TPM_INTF_DATA_AVAIL_INT) wake_up_interruptible(&priv->read_queue); if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT) @@ -780,7 +781,7 @@ static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask, if (rc < 0) return rc; - priv->irq_tested = false; + clear_bit(TPM_TIS_IRQTEST_OK, &priv->irqtest_flags); chip->flags |= TPM_CHIP_FLAG_IRQ; /* Generate an interrupt by having the core call through to diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h index 43b724e55192..c8972ea8e13e 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h @@ -89,11 +89,15 @@ enum tpm_tis_flags { TPM_TIS_USE_THREADED_IRQ = BIT(2), }; +enum tpm_tis_irqtest_flags { + TPM_TIS_IRQTEST_OK = BIT(0), +}; + struct tpm_tis_data { u16 manufacturer_id; int locality; int irq; - bool irq_tested; + unsigned long irqtest_flags; unsigned long flags; void __iomem *ilb_base_addr; u16 clkrun_enabled;