From 3345128bc3cf9272887813a69c7c63cf60c4c4ec Mon Sep 17 00:00:00 2001 From: Jakob Meng Date: Thu, 18 Jun 2026 11:43:20 +0200 Subject: [PATCH] fix nv_drm_revoke_modeset_permission kernel WARNING (Linux 6.12) On Debian kernels with use-kbuild-flags.patch (>= 6.12), the conftest for drm_connector_list_iter fails because drm_connector.h cannot compile without prerequisite headers under the stricter KBUILD_CFLAGS. This activates a fallback macro that asserts mode_config.mutex is held, but atomic drivers hold connection_mutex instead, causing a spurious WARN_ON on every DRM fd close. Patch 0085 fixes the conftest by including drm_device.h and drm_mode_config.h before drm_connector.h. Patch 0084 fixes latent error-handling bugs in the same function: a connector list iterator leak (goto skipping iter_end) and a NULL dereference in drm_atomic_state_put on allocation failure. Co-authored-by: Claude Opus 4.6 (Anthropic) via Cursor --- debian/changelog | 18 +++++ ...ke_modeset_permission-error-handling.patch | 65 +++++++++++++++++++ ...fix-drm_connector_list_iter-conftest.patch | 46 +++++++++++++ debian/patches/module/series | 2 + 4 files changed, 131 insertions(+) create mode 100644 debian/patches/module/0084-fix-nv_drm_revoke_modeset_permission-error-handling.patch create mode 100644 debian/patches/module/0085-fix-drm_connector_list_iter-conftest.patch diff --git a/debian/changelog b/debian/changelog index c3c75906..c866a3ed 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,21 @@ +nvidia-graphics-drivers (550.163.01-6) UNRELEASED; urgency=medium + + * Fix nv_drm_revoke_modeset_permission kernel WARNING triggered on DRM fd + close (e.g. by glxtest, kioworker, kscreenlocker_greet) on Debian kernels + with use-kbuild-flags.patch (Linux >= 6.12). + The root cause is a conftest compile failure for drm_connector_list_iter + that activates a fallback code path containing a bogus WARN_ON check for + the wrong mutex (mode_config.mutex instead of connection_mutex). + - Fix drm_connector_list_iter conftest: include prerequisite headers + (drm_device.h, drm_mode_config.h) before drm_connector.h so the struct + is detected correctly and the proper iterator API is used. + - Fix nv_drm_revoke_modeset_permission error handling: replace goto with + break to avoid leaking the connector list iterator, and guard + drm_atomic_state_put against NULL to prevent a dereference on alloc + failure. + + -- Jakob Meng Thu, 18 Jun 2026 11:42:25 +0200 + nvidia-graphics-drivers (550.163.01-5) unstable; urgency=medium * Backport drm_print.h changes from 570.211.01, for_each_*_*_in_state and diff --git a/debian/patches/module/0084-fix-nv_drm_revoke_modeset_permission-error-handling.patch b/debian/patches/module/0084-fix-nv_drm_revoke_modeset_permission-error-handling.patch new file mode 100644 index 00000000..0e789cee --- /dev/null +++ b/debian/patches/module/0084-fix-nv_drm_revoke_modeset_permission-error-handling.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jakob Meng +Date: Tue, 17 Jun 2025 21:00:00 +0200 +Subject: [PATCH] fix nv_drm_revoke_modeset_permission error handling + +Fix two bugs in nv_drm_revoke_modeset_permission that trigger a kernel +WARNING (ud2) in DRM_MODESET_LOCK_ALL_END when a DRM file descriptor is +closed: + +Bug 1: When nv_drm_atomic_disable_connector() returns an error, the +'goto done' skips nv_drm_connector_list_iter_end(), leaking the +iterator's internal reference on the connector. This interacts with +DRM_MODESET_LOCK_ALL_END's retry/cleanup logic, triggering the warning. +Fix by replacing 'goto done' with 'break' and adding an explicit error +check after the loop. + +Bug 2: If drm_atomic_state_alloc() fails, 'goto done' leads to +drm_atomic_state_put(NULL) or drm_atomic_state_free(NULL), which +dereferences a NULL pointer. Fix by adding a NULL guard. + +The underlying iterator leak bug exists in all versions from 550 through +580+, but the visible symptom (WARN_ON from the nv_drm_for_each_connector +wrapper macro's fallback path) only manifests in 550-570 where the wrapper +macros are used. + +Co-authored-by: Claude Opus 4.6 (Anthropic) via Cursor +--- + nvidia-drm/nvidia-drm-drv.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/nvidia-drm/nvidia-drm-drv.c b/nvidia-drm/nvidia-drm-drv.c +index abcdef01..abcdef02 100644 +--- a/nvidia-drm/nvidia-drm-drv.c ++++ b/nvidia-drm/nvidia-drm-drv.c +@@ -1221,7 +1221,7 @@ + (!dpyId || nv_drm_connector_is_dpy_id(connector, dpyId))) { + ret = nv_drm_atomic_disable_connector(state, nv_connector); + if (ret < 0) { +- goto done; ++ break; + } + + // Continue trying to revoke as much as possible. +@@ -1231,6 +1231,8 @@ + #if defined(NV_DRM_CONNECTOR_LIST_ITER_PRESENT) + nv_drm_connector_list_iter_end(&conn_iter); + #endif ++ if (ret < 0) ++ goto done; + + nv_drm_for_each_crtc(crtc, dev) { + struct nv_drm_crtc *nv_crtc = to_nv_crtc(crtc); +@@ -1242,9 +1244,10 @@ + ret = drm_atomic_commit(state); + done: + #if defined(NV_DRM_ATOMIC_STATE_REF_COUNTING_PRESENT) +- drm_atomic_state_put(state); ++ if (state != NULL) ++ drm_atomic_state_put(state); + #else +- if (ret != 0) { ++ if (state != NULL && ret != 0) { + drm_atomic_state_free(state); + } else { + /* diff --git a/debian/patches/module/0085-fix-drm_connector_list_iter-conftest.patch b/debian/patches/module/0085-fix-drm_connector_list_iter-conftest.patch new file mode 100644 index 00000000..30dc4c93 --- /dev/null +++ b/debian/patches/module/0085-fix-drm_connector_list_iter-conftest.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jakob Meng +Date: Wed, 18 Jun 2025 00:00:00 +0200 +Subject: [PATCH] fix drm_connector_list_iter conftest + +The compile test for struct drm_connector_list_iter fails on kernels +where drm/drm_connector.h cannot be compiled standalone (e.g. Debian +kernel 6.12.90 with KBUILD_CFLAGS from use-kbuild-flags.patch). The +header depends on types from drm/drm_device.h and drm/drm_mode_config.h +which must be included first. + +Without NV_DRM_CONNECTOR_LIST_ITER_PRESENT, the fallback +nv_drm_for_each_connector macro is used, which contains a bogus +WARN_ON(mode_config.mutex) check that fires under DRM_MODESET_LOCK_ALL +locking. + +Fix the conftest by adding the prerequisite DRM headers (guarded by +their own conftest defines) and adding a missing 'return 0' to silence +-Werror=return-type. + +Co-authored-by: Claude Opus 4.6 (Anthropic) via Cursor +--- + conftest.sh | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/conftest.sh b/conftest.sh +index abcdef01..abcdef02 100755 +--- a/conftest.sh ++++ b/conftest.sh +@@ -4282,9 +4282,16 @@ + # + CODE=" ++ #if defined(NV_DRM_DRM_DEVICE_H_PRESENT) ++ #include ++ #endif ++ #if defined(NV_DRM_DRM_MODE_CONFIG_H_PRESENT) ++ #include ++ #endif + #include + int conftest_drm_connector_list_iter(void) { + struct drm_connector_list_iter conn_iter; +- }" ++ return 0; ++ }" + + compile_check_conftest "$CODE" "NV_DRM_CONNECTOR_LIST_ITER_PRESENT" "" "types" diff --git a/debian/patches/module/series b/debian/patches/module/series index c3cc2957..85341eea 100644 --- a/debian/patches/module/series +++ b/debian/patches/module/series @@ -32,6 +32,8 @@ bashisms.patch 0081-support-fallback-for-for_each_-_plane_in_state.patch 0082-backport-for_each_-_crtc_in_state-changes-from-580.1.patch 0083-support-fallback-for-for_each_-_crtc_in_state.patch +0084-fix-nv_drm_revoke_modeset_permission-error-handling.patch +0085-fix-drm_connector_list_iter-conftest.patch # build system updates conftest-verbose.patch -- 2.47.3