From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 57EB6298CAB; Thu, 16 Jul 2026 14:03:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784210622; cv=none; b=Xyw8rhYgTW+PGEA4bBptY25kdRbes4fJvavWOk04CuCj5e7iFj6/6Lz9vtm7FaNKfZuN3RDEim8OB/kbJ3TiPgrLmxLruSRiCkRjUxg1k43BUcNnLWeTchAPkNH50hz1MJDQrcN2umSSc8rHS38u1N/uu3MF9SR/Kjlv8qvVbh4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784210622; c=relaxed/simple; bh=Ozmp881ShaDl2hwQg74JP1QDr8j5sfXyDDg/edyhCog=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gPXuKzJNs6fTex+d4UouZXodpynOy4opuXAq0Cr3aAnjlnMaOdl/ZY3mBAavxgESSC09QDcQ32GYCgaNUSvRywlcuoH45ToDUC0WIa4EfBLvJEXUQisIRisE5FRLvdzzNghvkKLxPvx7fRdGVKnTw1Q7J/KbxG0PFeOGPpkBUuE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=F9+X0kNu; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="F9+X0kNu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BCF9D1F000E9; Thu, 16 Jul 2026 14:03:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1784210621; bh=ZsbOYGLeKMLtfj7ie3DmrNjKrKxscx1JKSVaHbKhA7Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=F9+X0kNuJCSFavQ+bB6au3iII+wKAVviOgrBZh/+Vw0hyFV0cJsms/RJhTBf+r2ao 9oNP968dD7JwBqP4NyAgF8yfVesGUHze5CJ/P4CT1jRuS2i6N9VMmqakh1e6NVzow6 gTJHHE5aI9iP7prJJ+6Iy7UfeH1OAlwDmiGUzAV0= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Alex Williamson , Kevin Tian , Alex Williamson Subject: [PATCH 6.18 117/480] vfio/pci: Latch disable_idle_d3 per device Date: Thu, 16 Jul 2026 15:27:44 +0200 Message-ID: <20260716133047.236150327@linuxfoundation.org> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260716133044.672218725@linuxfoundation.org> References: <20260716133044.672218725@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Alex Williamson commit 4575e9aac5336d1365138c0284773bf8da4b1fa3 upstream. When disable_idle_d3 was introduced in vfio-pci, it directly manipulated the device power state with pci_set_power_state(). There were no refcounts to maintain or balanced operations, we could unconditionally bring the device to D0 and conditionally move it to D3hot. Therefore the module parameter was made writable. Later, in commit c61302aa48f7 ("vfio/pci: Move module parameters to vfio_pci.c"), as part of the vfio-pci-core split, the writable aspect of the module parameter was nullified. The parameter value could still be changed through sysfs, but the vfio-pci driver latched the values into vfio-pci-core globals at module init. Loading the vfio-pci module, or unloading and reloading, with non-default or different values could change the globals relative to existing devices bound to vfio-pci variant drivers. Runtime PM was introduced in commit 7ab5e10eda02 ("vfio/pci: Move the unused device into low power state with runtime PM"), which marks the point where power states became refcounted. PM get and put operations need to be balanced, but the same module operations noted above can change the global variables relative to those devices already bound to vfio-pci variant drivers. This introduces a window where PM operations can now become unbalanced. To resolve this with a narrow footprint for stable backports, the disable_idle_d3 flag is latched into the vfio_pci_core_device at the time of initialization, such that the device always operates with a consistent value. NB. vfio_pci_dev_set_try_reset() now unconditionally raises the runtime PM usage count around bus reset to account for disable_idle_d3 becoming a per-device rather than global flag. When this flag is set, the additional get/put pair is harmless and allows continued use of the shared vfio_pci_dev_set_pm_runtime_get() helper. Fixes: 7ab5e10eda02 ("vfio/pci: Move the unused device into low power state with runtime PM") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Alex Williamson Reviewed-by: Kevin Tian Link: https://lore.kernel.org/r/20260615191241.688297-2-alex.williamson@nvidia.com Signed-off-by: Alex Williamson Signed-off-by: Greg Kroah-Hartman --- drivers/vfio/pci/vfio_pci_core.c | 19 ++++++++++--------- include/linux/vfio_pci_core.h | 1 + 2 files changed, 11 insertions(+), 9 deletions(-) --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -506,7 +506,7 @@ int vfio_pci_core_enable(struct vfio_pci u16 cmd; u8 msix_pos; - if (!disable_idle_d3) { + if (!vdev->disable_idle_d3) { ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) return ret; @@ -584,7 +584,7 @@ out_free_state: out_disable_device: pci_disable_device(pdev); out_power: - if (!disable_idle_d3) + if (!vdev->disable_idle_d3) pm_runtime_put(&pdev->dev); return ret; } @@ -720,7 +720,7 @@ out: vfio_pci_dev_set_try_reset(vdev->vdev.dev_set); /* Put the pm-runtime usage counter acquired during enable */ - if (!disable_idle_d3) + if (!vdev->disable_idle_d3) pm_runtime_put(&pdev->dev); } EXPORT_SYMBOL_GPL(vfio_pci_core_disable); @@ -2131,6 +2131,8 @@ int vfio_pci_core_init_dev(struct vfio_d init_rwsem(&vdev->memory_lock); xa_init(&vdev->ctx); + vdev->disable_idle_d3 = disable_idle_d3; + return 0; } EXPORT_SYMBOL_GPL(vfio_pci_core_init_dev); @@ -2222,7 +2224,7 @@ int vfio_pci_core_register_device(struct dev->driver->pm = &vfio_pci_core_pm_ops; pm_runtime_allow(dev); - if (!disable_idle_d3) + if (!vdev->disable_idle_d3) pm_runtime_put(dev); ret = vfio_register_group_dev(&vdev->vdev); @@ -2231,7 +2233,7 @@ int vfio_pci_core_register_device(struct return 0; out_power: - if (!disable_idle_d3) + if (!vdev->disable_idle_d3) pm_runtime_get_noresume(dev); pm_runtime_forbid(dev); @@ -2250,7 +2252,7 @@ void vfio_pci_core_unregister_device(str vfio_pci_vf_uninit(vdev); vfio_pci_vga_uninit(vdev); - if (!disable_idle_d3) + if (!vdev->disable_idle_d3) pm_runtime_get_noresume(&vdev->pdev->dev); pm_runtime_forbid(&vdev->pdev->dev); @@ -2578,7 +2580,7 @@ static void vfio_pci_dev_set_try_reset(s * state. Increment the usage count for all the devices in the dev_set * before reset and decrement the same after reset. */ - if (!disable_idle_d3 && vfio_pci_dev_set_pm_runtime_get(dev_set)) + if (vfio_pci_dev_set_pm_runtime_get(dev_set)) return; if (!pci_reset_bus(pdev)) @@ -2588,8 +2590,7 @@ static void vfio_pci_dev_set_try_reset(s if (reset_done) cur->needs_reset = false; - if (!disable_idle_d3) - pm_runtime_put(&cur->pdev->dev); + pm_runtime_put(&cur->pdev->dev); } } --- a/include/linux/vfio_pci_core.h +++ b/include/linux/vfio_pci_core.h @@ -86,6 +86,7 @@ struct vfio_pci_core_device { bool needs_pm_restore:1; bool pm_intx_masked:1; bool pm_runtime_engaged:1; + bool disable_idle_d3:1; bool sriov_active; struct pci_saved_state *pci_saved_state; struct pci_saved_state *pm_save;