Summary
The README states that a blocked GPU is hidden via -ENOENT on device-node syscalls (/dev/dri/*, /dev/nvidia*, etc.), transparently to the app. In practice, at least one process was killed outright with SIGSYS (seccomp) on a syscall that has nothing to do with GPU device access.
Environment
- cardwire 0.12.3-1 (pacman/AUR)
- Kernel: 7.2.5-3-omarchy (Arch-based)
- Laptop, hybrid graphics: Intel (GPU 0, default) + NVIDIA RTX 5070 Laptop (GPU 1, discrete)
- Mode: Smart, GPU 1 blocked by default (per
cardwire list)
- Affected process:
wine64-preloader launching xalia.exe (Proton-CachyOS's accessibility helper)
What happened
systemd-coredump recorded wine64-preloader dying with SIGSYS, si_code=SYS_SECCOMP, 34 seconds into a session, immediately at process startup. Pulling the core with gdb and inspecting $_siginfo:
si_syscall = 158 (arch_prctl)
si_arch = AUDIT_ARCH_X86_64
rip = _start+0x26 (the second instruction the preloader executes)
rdi = 0x1002 (ARCH_SET_FS — standard TLS setup, not GPU-related)
So the process was killed for calling arch_prctl(ARCH_SET_FS, ...) — a syscall every native ELF binary makes during startup, with no connection to /dev/dri or /dev/nvidia*.
Correlated cardwired journal entries show this process was in the "blocked" state at the time:
cardwired[...]: xalia.exe[<pid>] tried to access GPU 1 (blocked by cardwire)
(repeated across several relaunch attempts, each ending the same way)
Expected (per README)
When a GPU is "blocked," the eBPF program returns -ENOENT for any syscall targeting that device, effectively hiding it from apps.
Actual
A blocked process can be killed by SIGSYS on an unrelated, universal startup syscall (arch_prctl) before it ever touches a GPU device node. This is a different (and much more disruptive) failure mode than the documented one, and it isn't obvious from the docs that seccomp/SIGSYS is involved at all.
Question for maintainers
Is this an unintended interaction (e.g., a seccomp filter/eBPF LSM hook mistakenly evaluating arch_prctl as if it were a GPU-device syscall) rather than the intended -ENOENT masking path? Happy to provide the full coredumpctl info output or the raw core if useful.
Summary
The README states that a blocked GPU is hidden via
-ENOENTon device-node syscalls (/dev/dri/*,/dev/nvidia*, etc.), transparently to the app. In practice, at least one process was killed outright withSIGSYS(seccomp) on a syscall that has nothing to do with GPU device access.Environment
cardwire list)wine64-preloaderlaunchingxalia.exe(Proton-CachyOS's accessibility helper)What happened
systemd-coredumprecordedwine64-preloaderdying withSIGSYS,si_code=SYS_SECCOMP, 34 seconds into a session, immediately at process startup. Pulling the core with gdb and inspecting$_siginfo:So the process was killed for calling
arch_prctl(ARCH_SET_FS, ...)— a syscall every native ELF binary makes during startup, with no connection to/dev/drior/dev/nvidia*.Correlated
cardwiredjournal entries show this process was in the "blocked" state at the time:(repeated across several relaunch attempts, each ending the same way)
Expected (per README)
Actual
A blocked process can be killed by
SIGSYSon an unrelated, universal startup syscall (arch_prctl) before it ever touches a GPU device node. This is a different (and much more disruptive) failure mode than the documented one, and it isn't obvious from the docs that seccomp/SIGSYSis involved at all.Question for maintainers
Is this an unintended interaction (e.g., a seccomp filter/eBPF LSM hook mistakenly evaluating
arch_prctlas if it were a GPU-device syscall) rather than the intended-ENOENTmasking path? Happy to provide the fullcoredumpctl infooutput or the raw core if useful.