Re: [BUG] tpm: prolonged stall in vtpm_proxy_fops_release() on Linux 7.3
From: Stefan Berger
Date: Fri Nov 06 2026 - 14:13:07 EST
On 11/1/26 12:36 PM, Jarkko Sakkinen wrote:
On Sun, Nov 01, 2026 at 09:22:30AM +0800, 铮 wrote:
Hi Peter, Jarkko and Jason,>>
Question
--------
vtpm_proxy_tpm_req_canceled() already exists and the driver marks the
device as being torn down before flush_work(); from the captured dumps
I cannot tell why the wait nevertheless persists for minutes. Should
the release path be bounded, or should the in-flight chip-register work
be ended more promptly once the proxy is being torn down? I am happy to
test proposed patches.
I have tried to reproduce this now but cannot. The kernel fails for me like this when booting with the suggested QEMU command line:
[ 3.224399][ T1] Timer migration: 2 hierarchy levels; 8 children per group; 1 crossnode level
[ 3.239948][ T1] smp: Bringing up secondary CPUs ...
[ 3.243980][ T1] smpboot: x86: Booting SMP configuration:
[ 3.246035][ T1] .... node #0, CPUs: #1
[ 3.252255][ T1] .... node #1, CPUs: #2 #3
[ 0.076393][ T0] ------------[ cut here ]------------
[ 0.076393][ T0] sched: CPU #2's llc-sibling CPU #0 is not on the same node! [node: 1 != 0]. Ignoring dependency.
[ 0.076393][ T0] WARNING: arch/x86/kernel/smpboot.c:329 at topology_sane.isra.0+0x97/0xb0, CPU#2: swapper/2/0
[ 0.076393][ T0] Modules linked in:
[ 0.076393][ T0] CPU: 2 UID: 0 PID: 0 Comm: swapper/2 Not tainted 7.3.0-kernsight-kasan #1 PREEMPT(full)
[ 0.076393][ T0] Hardware name: QEMU Ubuntu 26.04 PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1ubuntu1 04/01/2014
[ 0.076393][ T0] RIP: 0010:topology_sane.isra.0+0xa3/0xb0
[ 0.076393][ T0] Code: 07 00 44 89 ef e8 ed fa 07 00 44 89 e7 89 c3 e8 e3 fa 07 00 41 89 c0 48 8d 3d 79 4e 3e 10 41 89 d9 44 89 e9 4c 89 fa 44 89 e6 <67> 48 0f b9 3a eb a5 66 0f 1f 44 00 00 90 90 90 90 90 90 90 90 90
[ 0.076393][ T0] RSP: 0000:ffffc900001afde0 EFLAGS: 00010092
The first thing I was going to try is whether this has something to do with the 'STATE_OPENED_FLAG' flag. There's one location where this is set and that's after the anon_inode_getfile() was called. For a server side device to be able to access the device, udev would have to run. Maybe udev does run between anon_inode_getfile() and the server side opens the device and the immediately closes it and resets the flag BEFORE current vtpm_proxy_fops_open() sets the flag and makes the client think that there still is an server-side app responding to requests. So, let's reverse the order and set the flag before the inode gets created and the flag can be reset - patch also as attachment:
diff --git a/drivers/char/tpm/tpm_vtpm_proxy.c b/drivers/char/tpm/tpm_vtpm_proxy.c
index b81fd2a537df..245a8f959bc7 100644
--- a/drivers/char/tpm/tpm_vtpm_proxy.c
+++ b/drivers/char/tpm/tpm_vtpm_proxy.c
@@ -197,10 +197,8 @@ static __poll_t vtpm_proxy_fops_poll(struct file *filp, poll_table *wait)
*
* Called when setting up the anonymous file descriptor
*/
-static void vtpm_proxy_fops_open(struct file *filp)
+static void vtpm_proxy_fops_open(struct proxy_dev *proxy_dev)
{
- struct proxy_dev *proxy_dev = filp->private_data;
-
proxy_dev->state |= STATE_OPENED_FLAG;
}
@@ -550,6 +548,9 @@ static struct file *vtpm_proxy_create_device(
goto err_delete_proxy_dev;
}
+ /* simulate an open() on the server side */
+ vtpm_proxy_fops_open(proxy_dev);
+
file = anon_inode_getfile("[vtpms]", &vtpm_proxy_fops, proxy_dev,
O_RDWR);
if (IS_ERR(file)) {
@@ -558,8 +559,6 @@ static struct file *vtpm_proxy_create_device(
}
/* from now on we can unwind with put_unused_fd() + fput() */
- /* simulate an open() on the server side */
- vtpm_proxy_fops_open(file);
if (proxy_dev->flags & VTPM_PROXY_FLAG_TPM2)
proxy_dev->chip->flags |= TPM_CHIP_FLAG_TPM2;
From d6c27b005dfca356fa33530696e21251d91421b7 Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb@xxxxxxxxxxxxx>
Date: Fri, 6 Nov 2026 12:43:56 -0600
Subject: [PATCH] tpm: tpm_vtpm_proxy: Set STATE_OPENED_FLAG before inode is
created
The server-side inode is currently created before the STATE_OPENED_FLAG
is set. Theoretically, an application could open the server side file
after anon_inode_getfile() ran in the driver (and udev created the
device) and then immediately close the file descriptor and clear the still
unset STATE_OPENED_FLAG that currently gets set after
anon_inode_getfile(). Therefore, reverse the order so that the flag
never gets set after it was attempted to be cleared.
If the flag is set while no server-side application responds to requests,
the client-side may wait for a response until timeout.
Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxx>
---
drivers/char/tpm/tpm_vtpm_proxy.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/char/tpm/tpm_vtpm_proxy.c b/drivers/char/tpm/tpm_vtpm_proxy.c
index b81fd2a537df..245a8f959bc7 100644
--- a/drivers/char/tpm/tpm_vtpm_proxy.c
+++ b/drivers/char/tpm/tpm_vtpm_proxy.c
@@ -197,10 +197,8 @@ static __poll_t vtpm_proxy_fops_poll(struct file *filp, poll_table *wait)
*
* Called when setting up the anonymous file descriptor
*/
-static void vtpm_proxy_fops_open(struct file *filp)
+static void vtpm_proxy_fops_open(struct proxy_dev *proxy_dev)
{
- struct proxy_dev *proxy_dev = filp->private_data;
-
proxy_dev->state |= STATE_OPENED_FLAG;
}
@@ -550,6 +548,9 @@ static struct file *vtpm_proxy_create_device(
goto err_delete_proxy_dev;
}
+ /* simulate an open() on the server side */
+ vtpm_proxy_fops_open(proxy_dev);
+
file = anon_inode_getfile("[vtpms]", &vtpm_proxy_fops, proxy_dev,
O_RDWR);
if (IS_ERR(file)) {
@@ -558,8 +559,6 @@ static struct file *vtpm_proxy_create_device(
}
/* from now on we can unwind with put_unused_fd() + fput() */
- /* simulate an open() on the server side */
- vtpm_proxy_fops_open(file);
if (proxy_dev->flags & VTPM_PROXY_FLAG_TPM2)
proxy_dev->chip->flags |= TPM_CHIP_FLAG_TPM2;
--
2.56.0