[PATCH BACKPORT v3] drm/nouveau: fix hibernate on disabled GPU
From: Christoph Rudorff
Date: Wed Mar 26 2025 - 10:04:51 EST
Hibernate bricks the machine if a discrete GPU was disabled via
echo IGD > /sys/kernel/debug/vgaswitcheroo/switch
The freeze and thaw handler lacks checking the GPU power state,
as suspend and resume do.
This patch add the checks and fix this issue.
This is a backport and applies to v6.6 and below.
Signed-off-by: Christoph Rudorff <chris@xxxxxxxxxxx>
---
I got an old MacBook having a defective nvidia GPU
So I put this in the initrd scripts to turn it off asap:
mount -t debugfs none /sys/kernel/debug
echo IGD > /sys/kernel/debug/vgaswitcheroo/switch
which powers down the nouveau.
Suspend and resume works,
but hibernate locks up the machine.
The handlers are not checking the GPU state.
This is a good candidate for backport.
This patch applies to v6.6 and below
---
Changes in v3:
- Backport for v6.6 and below
- Link to v2: https://lore.kernel.org/r/20250325-nouveau-fix-hibernate-v2-1-2bd5c13fb953@xxxxxxxxxxx
Changes in v2:
- EDITME: use my real name, my nick raised bugs
- Link to v1: https://lore.kernel.org/r/20250304-nouveau-fix-hibernate-v1-1-ee4433546030@xxxxxxxxxxx
---
drivers/gpu/drm/nouveau/nouveau_drm.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index ac15a662e06042e2c133da9c17fcd53000a98650..a05151b557dac6860e07fe7147aa81b7b15e6f4b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -1026,6 +1026,11 @@ nouveau_pmops_freeze(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
+
+ if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF ||
+ drm_dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF)
+ return 0;
+
return nouveau_do_suspend(drm_dev, false);
}
@@ -1034,6 +1039,11 @@ nouveau_pmops_thaw(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
+
+ if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF ||
+ drm_dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF)
+ return 0;
+
return nouveau_do_resume(drm_dev, false);
}
---
base-commit: 4b6a8fa777d29785c7ddb51dcbb2b5411deefaca
change-id: 20250304-nouveau-fix-hibernate-249826d427bb
Best regards,
--
Christoph Rudorff <chris@xxxxxxxxxxx>