From nobody Thu Dec 18 00:34:21 2025 Received: from smtp-fw-6002.amazon.com (smtp-fw-6002.amazon.com [52.95.49.90]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AD4E430E830; Fri, 20 Jun 2025 18:08:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=52.95.49.90 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750442920; cv=none; b=UGAfh+8+VDhsomC7qdvVZ30SNNaZULUOcqb8ZI9ntRYnlUSXvi1JFf56cUlZAvfjUqJdc+edgqK9u+feU1YgfCEGPjBS6SUXPnoLqdEWM7yJ8VriOJqgr/4me+KUXuTZSIhPXevifLGnFGPUqhBJC/DbOVgRrlVuK1zAQlHFOQ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750442920; c=relaxed/simple; bh=t1h/NKkK8cEwtLBeyp2T/WCU+1jO2QeiqWnC4nACPJ8=; h=From:To:CC:Subject:Date:Message-ID:Content-Type:MIME-Version; b=jEKQGebbBhMciy3o9YbIhbP3DtV8wvQT46g29nsWpDl42zSNggXAN7qvBVuAkhJOmuUh791N8L5GeGI1lIqhloR0m8TlDh0+cG2U/TNkYA5O35UOZjAt22KTqpAR8PnqPpQKYq16CuoDNXfHoJmThXskl5QhBeLagNoOvvDrd1I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.co.uk; spf=pass smtp.mailfrom=amazon.co.uk; dkim=pass (2048-bit key) header.d=amazon.co.uk header.i=@amazon.co.uk header.b=FYzt9bfB; arc=none smtp.client-ip=52.95.49.90 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amazon.co.uk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amazon.co.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=amazon.co.uk header.i=@amazon.co.uk header.b="FYzt9bfB" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.co.uk; i=@amazon.co.uk; q=dns/txt; s=amazoncorp2; t=1750442919; x=1781978919; h=from:to:cc:subject:date:message-id: content-transfer-encoding:mime-version; bh=GhG7Mn5TeXYPwLyALqxnBg3OgPet0/LmcqQZUQN16cI=; b=FYzt9bfBDOELraQ7hPe2jRSz5l5IW4oUwn62KyDgkTAvalC0kXSgjUk2 qJ9GB6Ms343gjd71GqTCcsO+YJbjySXZqlZu/C8nGufHBEpU/31Y9yhSQ ygP9VI1lW4bSh5hTu60ptom90RxGmAxZCvxgb+eemn/aEuD76pMBmkTiD V2FPVNL+WOQZf2t2HozjTv6AxfVq3npkG4I640mu4OKxvp6iBEplGvYac frR577T0j3EPetm92/YJblSKlCQhi1qIDYS7Mt7wk+pRn8ElDqaB7Kgvw fRSM6TAdrtdtlK7FyhHaZFk1s8NjFEUCb+Dxi1/qAUhe9eM1SjGgm7KB7 Q==; X-IronPort-AV: E=Sophos;i="6.16,252,1744070400"; d="scan'208";a="512323869" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO smtpout.prod.us-west-2.prod.farcaster.email.amazon.dev) ([10.43.8.6]) by smtp-border-fw-6002.iad6.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Jun 2025 18:08:33 +0000 Received: from EX19MTAEUB002.ant.amazon.com [10.0.43.254:17959] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.35.171:2525] with esmtp (Farcaster) id 620fb4a1-0951-4c54-ae47-01c96faff03a; Fri, 20 Jun 2025 18:08:31 +0000 (UTC) X-Farcaster-Flow-ID: 620fb4a1-0951-4c54-ae47-01c96faff03a Received: from EX19D031EUB002.ant.amazon.com (10.252.61.105) by EX19MTAEUB002.ant.amazon.com (10.252.51.59) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1544.14; Fri, 20 Jun 2025 18:08:31 +0000 Received: from EX19D031EUB002.ant.amazon.com (10.252.61.105) by EX19D031EUB002.ant.amazon.com (10.252.61.105) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1544.14; Fri, 20 Jun 2025 18:08:31 +0000 Received: from EX19D031EUB002.ant.amazon.com ([fe80::33ef:803f:4724:b020]) by EX19D031EUB002.ant.amazon.com ([fe80::33ef:803f:4724:b020%3]) with mapi id 15.02.1544.014; Fri, 20 Jun 2025 18:08:31 +0000 From: "Orlov, Ivan" To: "peterhuewe@gmx.de" , "jarkko@kernel.org" CC: "Orlov, Ivan" , "jgg@ziepe.ca" , "linux-integrity@vger.kernel.org" , "linux-kernel@vger.kernel.org" , "Woodhouse, David" , "noodles@earth.li" Subject: [PATCH v2] tpm: Fix the timeout & use ktime Thread-Topic: [PATCH v2] tpm: Fix the timeout & use ktime Thread-Index: AQHb4g5UspHmJE4YYk+ZmPc+YkBqTA== Date: Fri, 20 Jun 2025 18:08:31 +0000 Message-ID: <20250620180828.98413-1-iorlov@amazon.com> Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: Content-Transfer-Encoding: quoted-printable Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The current implementation of timeout detection works in the following way: 1. Read completion status. If completed, return the data 2. Sleep for some time (usleep_range) 3. Check for timeout using current jiffies value. Return an error if timed out 4. Goto 1 usleep_range doesn't guarantee it's always going to wake up strictly in (min, max) range, so such a situation is possible: 1. Driver reads completion status. No completion yet 2. Process sleeps indefinitely. In the meantime, TPM responds 3. We check for timeout without checking for the completion again. Result is lost. Such a situation also happens for the guest VMs: if vCPU goes to sleep and doesn't get scheduled for some time, the guest TPM driver will timeout instantly after waking up without checking for the completion (which may already be in place). Perform the completion check once again after exiting the busy loop in order to give the device the last chance to send us some data. Since now we check for completion in two places, extract this check into a separate function. Signed-off-by: Ivan Orlov --- V1 -> V2: - Exclude the jiffies -> ktime change from the patch - Instead of recording the time before checking for completion, check for completion once again after leaving the loop drivers/char/tpm/tpm-interface.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interf= ace.c index 8d7e4da6ed53..6960ee2798e1 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -82,6 +82,13 @@ static bool tpm_chip_req_canceled(struct tpm_chip *chip,= u8 status) return chip->ops->req_canceled(chip, status); } =20 +static bool tpm_transmit_completed(struct tpm_chip *chip) +{ + u8 status_masked =3D tpm_chip_status(chip) & chip->ops->req_complete_mask; + + return status_masked =3D=3D chip->ops->req_complete_val; +} + static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t b= ufsiz) { struct tpm_header *header =3D buf; @@ -129,8 +136,7 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, = void *buf, size_t bufsiz) stop =3D jiffies + tpm_calc_ordinal_duration(chip, ordinal); do { u8 status =3D tpm_chip_status(chip); - if ((status & chip->ops->req_complete_mask) =3D=3D - chip->ops->req_complete_val) + if (tpm_transmit_completed(chip)) goto out_recv; =20 if (tpm_chip_req_canceled(chip, status)) { @@ -142,6 +148,13 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip,= void *buf, size_t bufsiz) rmb(); } while (time_before(jiffies, stop)); =20 + /* + * Check for completion one more time, just in case the device reported + * it while the driver was sleeping in the busy loop above. + */ + if (tpm_transmit_completed(chip)) + goto out_recv; + tpm_chip_cancel(chip); dev_err(&chip->dev, "Operation Timed out\n"); return -ETIME; --=20 2.43.0