NVIDIA Open GPU Kernel Modules Version
610.57.04 (distribution package, not a self-built commit; the code quoted below is unchanged on main at the time of writing)
Please confirm this issue does not happen with the proprietary driver (of the same version). This issue tracker is only for bugs specific to the open kernel driver.
Operating System and Version
CachyOS
Kernel Release
Linux 7.1.8-1-cachyos #1 SMP PREEMPT_DYNAMIC Tue, 11 Aug 2026 09:10:42 +0000 x86_64 GNU/Linux (distribution kernel, not self-built)
Please confirm you are running a stable release kernel (e.g. not a -rc). We do not accept bug reports for unreleased kernels.
Hardware: GPU
GPU 0: NVIDIA GeForce RTX 5070 Laptop GPU
Describe the bug
In src/nvidia-modeset/src/nvkms-rm.c, nvRmMuxPre() sets the skip field and
then immediately overwrites the whole flags word:
params.flags = DRF_DEF(0073_CTRL_DFP, _DISP_MUX_FLAGS, _SR_ENTER_SKIP, _NO);
if (state == MUX_STATE_DISCRETE) {
params.flags = NV0073_CTRL_DFP_DISP_MUX_FLAGS_SWITCH_TYPE_IGPU_TO_DGPU;
} else if (state == MUX_STATE_INTEGRATED) {
params.flags = NV0073_CTRL_DFP_DISP_MUX_FLAGS_SWITCH_TYPE_DGPU_TO_IGPU;
}
The second assignment should be |=. Because _SR_ENTER_SKIP_NO and
_SWITCH_TYPE_IGPU_TO_DGPU are both 0, the resulting value is identical
today, so there is no visible regression - but it means SR_ENTER_SKIP can
never be set by the driver, and that field is therefore dead code.
That matters on this machine. NV0073_CTRL_CMD_DFP_RUN_PRE_DISP_MUX_OPERATIONS
returns NV_ERR_NOT_SUPPORTED (0x56) with the flags the driver sends, which
reads like the platform not implementing the entry point at all. Sweeping the
documented flag space shows otherwise (displayId 0x200, run twice, identical
both times):
PRE i->d sr=no bl=no flags=0x0 -> 0x56 NOT_SUPPORTED
PRE i->d sr=YES bl=no flags=0x2 -> 0x0 OK
PRE i->d sr=no bl=YES flags=0x8 -> 0x56 NOT_SUPPORTED
PRE i->d sr=YES bl=YES flags=0xa -> 0x0 OK
PRE d->i sr=no bl=no flags=0x1 -> 0x56 NOT_SUPPORTED
PRE d->i sr=YES bl=no flags=0x3 -> 0x0 OK
PRE d->i sr=no bl=YES flags=0x9 -> 0x56 NOT_SUPPORTED
PRE d->i sr=YES bl=YES flags=0xb -> 0x0 OK
POST (all eight combinations) -> 0x0 OK
So the entry point is implemented, and only the PSR-entry sub-step is refused
on this platform. The remainder of pre-ops documented in ctrl0073dfp.h (SOR
sequencer, BL GPIO control, LCD VDD / BL EN / PWM MUX handover) works. The one
flag combination the firmware accepts is exactly the one the driver cannot
send.
nvRmMuxPost() contains the same overwrite, and additionally passes the
_SR_ENTER_SKIP name where the field is _SR_EXIT_SKIP. Same bit position, so
that part is a naming slip rather than a behaviour change.
Suggested fix:
params.flags = DRF_DEF(0073_CTRL_DFP, _DISP_MUX_FLAGS, _SR_ENTER_SKIP, _NO);
if (state == MUX_STATE_DISCRETE) {
params.flags |= NV0073_CTRL_DFP_DISP_MUX_FLAGS_SWITCH_TYPE_IGPU_TO_DGPU;
} else if (state == MUX_STATE_INTEGRATED) {
params.flags |= NV0073_CTRL_DFP_DISP_MUX_FLAGS_SWITCH_TYPE_DGPU_TO_IGPU;
} else {
return FALSE;
}
plus a way for the caller to request SR_ENTER_SKIP_YES, so pre-ops can still
run on platforms where PSR entry is unavailable.
To Reproduce
Preconditions:
- A laptop with a dynamic display mux whose internal panel is wired to both
GPUs, with firmware reporting mux mode DYNAMIC. Verified here on an Acer
Predator PHN16S-71 (Intel Arrow Lake-S + RTX 5070 Laptop, BIOS V1.26,
PI3DPX8121 mux).
- The mux RM controls are
RMCTRL_FLAGS_KERNEL_PRIVILEGED, so they cannot be
called from userspace at any uid. Reaching them needs a kernel-side RM client
(here: a small out-of-tree module using the exported nvidia_get_rm_ops,
whose .op dispatches NV04_CONTROL at RS_PRIV_LEVEL_KERNEL).
Steps:
- Resolve the muxed display id with
NV0073_CTRL_CMD_SYSTEM_QUERY_DISPLAY_IDS_WITH_MUX (returns 0x200 here).
- Call
NV0073_CTRL_CMD_SPECIFIC_SET_ACPI_ID_MAPPING, then
NV0073_CTRL_CMD_DFP_INIT_MUX_DATA with the panel's real EDID
manfId/productId. Both return NV_OK.
- Call
NV0073_CTRL_CMD_DFP_RUN_PRE_DISP_MUX_OPERATIONS with
flags = _SWITCH_TYPE_IGPU_TO_DGPU (that is, 0x0, the value the driver
sends). It returns NV_ERR_NOT_SUPPORTED.
- Repeat with bit 1 set (
_SR_ENTER_SKIP_YES, flags = 0x2). It returns
NV_OK.
- Repeat both for the
d->i direction (flags = 0x1 and 0x3) for the same
result.
Bug Incidence
Always
nvidia-bug-report.log.gz
nvidia-bug-report.log.gz
More Info
Expected: RUN_PRE_DISP_MUX_OPERATIONS either performs the non-PSR portion of
pre-ops, or reports something more specific than NV_ERR_NOT_SUPPORTED when
only the PSR sub-step is unavailable.
Actual: it refuses the whole call, and the flag that makes it succeed cannot be
set through the driver.
Related, and possibly worth its own issue: MuxInit() populates
pDispEvo->muxDisplays only from a hardcoded ACPI-id table that currently holds
one entry ({.acpiId = 0x8001a420, .displayId = 0x1000, .dodIndex = 0}). On any
other machine the nvDpyIdIsInDpyIdList() check in
nvRmMuxPre/Switch/Post fails, so NVKMS_IOCTL_SWITCH_MUX is unreachable.
The in-tree comment already describes it as "a poor-man's alternative to the
WDDM driver's CDisplayMgr::NVInitializeACPIToDeviceMaskMap()". Deriving the
mapping from _DOD at runtime would make the existing API usable much more
widely.
NVIDIA Open GPU Kernel Modules Version
610.57.04(distribution package, not a self-built commit; the code quoted below is unchanged onmainat the time of writing)Please confirm this issue does not happen with the proprietary driver (of the same version). This issue tracker is only for bugs specific to the open kernel driver.
Operating System and Version
CachyOS
Kernel Release
Linux 7.1.8-1-cachyos #1 SMP PREEMPT_DYNAMIC Tue, 11 Aug 2026 09:10:42 +0000 x86_64 GNU/Linux (distribution kernel, not self-built)
Please confirm you are running a stable release kernel (e.g. not a -rc). We do not accept bug reports for unreleased kernels.
Hardware: GPU
GPU 0: NVIDIA GeForce RTX 5070 Laptop GPU
Describe the bug
In
src/nvidia-modeset/src/nvkms-rm.c,nvRmMuxPre()sets the skip field andthen immediately overwrites the whole flags word:
The second assignment should be
|=. Because_SR_ENTER_SKIP_NOand_SWITCH_TYPE_IGPU_TO_DGPUare both0, the resulting value is identicaltoday, so there is no visible regression - but it means
SR_ENTER_SKIPcannever be set by the driver, and that field is therefore dead code.
That matters on this machine.
NV0073_CTRL_CMD_DFP_RUN_PRE_DISP_MUX_OPERATIONSreturns
NV_ERR_NOT_SUPPORTED(0x56) with the flags the driver sends, whichreads like the platform not implementing the entry point at all. Sweeping the
documented flag space shows otherwise (displayId
0x200, run twice, identicalboth times):
So the entry point is implemented, and only the PSR-entry sub-step is refused
on this platform. The remainder of pre-ops documented in
ctrl0073dfp.h(SORsequencer, BL GPIO control, LCD VDD / BL EN / PWM MUX handover) works. The one
flag combination the firmware accepts is exactly the one the driver cannot
send.
nvRmMuxPost()contains the same overwrite, and additionally passes the_SR_ENTER_SKIPname where the field is_SR_EXIT_SKIP. Same bit position, sothat part is a naming slip rather than a behaviour change.
Suggested fix:
plus a way for the caller to request
SR_ENTER_SKIP_YES, so pre-ops can stillrun on platforms where PSR entry is unavailable.
To Reproduce
Preconditions:
GPUs, with firmware reporting mux mode
DYNAMIC. Verified here on an AcerPredator PHN16S-71 (Intel Arrow Lake-S + RTX 5070 Laptop, BIOS V1.26,
PI3DPX8121 mux).
RMCTRL_FLAGS_KERNEL_PRIVILEGED, so they cannot becalled from userspace at any uid. Reaching them needs a kernel-side RM client
(here: a small out-of-tree module using the exported
nvidia_get_rm_ops,whose
.opdispatchesNV04_CONTROLatRS_PRIV_LEVEL_KERNEL).Steps:
NV0073_CTRL_CMD_SYSTEM_QUERY_DISPLAY_IDS_WITH_MUX(returns0x200here).NV0073_CTRL_CMD_SPECIFIC_SET_ACPI_ID_MAPPING, thenNV0073_CTRL_CMD_DFP_INIT_MUX_DATAwith the panel's real EDIDmanfId/productId. Both returnNV_OK.NV0073_CTRL_CMD_DFP_RUN_PRE_DISP_MUX_OPERATIONSwithflags = _SWITCH_TYPE_IGPU_TO_DGPU(that is,0x0, the value the driversends). It returns
NV_ERR_NOT_SUPPORTED._SR_ENTER_SKIP_YES,flags = 0x2). It returnsNV_OK.d->idirection (flags = 0x1and0x3) for the sameresult.
Bug Incidence
Always
nvidia-bug-report.log.gz
nvidia-bug-report.log.gz
More Info
Expected:
RUN_PRE_DISP_MUX_OPERATIONSeither performs the non-PSR portion ofpre-ops, or reports something more specific than
NV_ERR_NOT_SUPPORTEDwhenonly the PSR sub-step is unavailable.
Actual: it refuses the whole call, and the flag that makes it succeed cannot be
set through the driver.
Related, and possibly worth its own issue:
MuxInit()populatespDispEvo->muxDisplaysonly from a hardcoded ACPI-id table that currently holdsone entry (
{.acpiId = 0x8001a420, .displayId = 0x1000, .dodIndex = 0}). On anyother machine the
nvDpyIdIsInDpyIdList()check innvRmMuxPre/Switch/Postfails, soNVKMS_IOCTL_SWITCH_MUXis unreachable.The in-tree comment already describes it as "a poor-man's alternative to the
WDDM driver's
CDisplayMgr::NVInitializeACPIToDeviceMaskMap()". Deriving themapping from
_DODat runtime would make the existing API usable much morewidely.