From f11765c02a70b4ba3401032f36ddbfe5486a5ba7 Mon Sep 17 00:00:00 2001 From: Nikolay Plastinin Date: Thu, 24 Sep 2026 14:52:54 +0800 Subject: [PATCH 1/2] fix(cardwired): stop logging every D-Bus call zbus instruments ObjectServer::dispatch_call at info level, so with the default "info" filter every incoming D-Bus call was logged with the whole message and header, several KB each. Default to "info,zbus=warn". RUST_LOG still overrides it. Co-Authored-By: Claude Opus 5.5 --- crates/cardwire-daemon/src/daemon.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/cardwire-daemon/src/daemon.rs b/crates/cardwire-daemon/src/daemon.rs index 8b6e672..c4bdf0d 100644 --- a/crates/cardwire-daemon/src/daemon.rs +++ b/crates/cardwire-daemon/src/daemon.rs @@ -22,7 +22,8 @@ pub const STATE_PATH: &str = "/var/lib/cardwire"; #[tokio::main] async fn main() -> Result<()> { // log - env_logger::Builder::from_env(Env::default().default_filter_or("info")) + // zbus logs every incoming D-Bus call at info level, with the whole message + env_logger::Builder::from_env(Env::default().default_filter_or("info,zbus=warn")) .format_target(false) .format_timestamp(None) .init(); From b308ee6e2ffa1686c3fbb550339b31a769fe0d11 Mon Sep 17 00:00:00 2001 From: Nikolay Plastinin Date: Thu, 24 Sep 2026 14:54:12 +0800 Subject: [PATCH 2/2] fix(cardwire-ebpf-userspace): explain the lockdown fallback instead of dumping the verifier log Under kernel lockdown (Secure Boot on most distributions) the kernel rejects sys_exit_getdents64 because it uses bpf_probe_write_user, and cardwired printed the whole verifier log, a few hundred lines, at warn level on every start. This is expected there, so print one line that says why and what it means, and keep the verifier log at debug level. Other load failures still print it at warn. Also document the lockdown fallback in the troubleshooting page. Co-Authored-By: Claude Opus 5.5 --- crates/cardwire-ebpf-userspace/src/lib.rs | 17 ++++++++++------- docs/diagnostics/troubleshooting.md | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/crates/cardwire-ebpf-userspace/src/lib.rs b/crates/cardwire-ebpf-userspace/src/lib.rs index 0c8591b..1f4c490 100644 --- a/crates/cardwire-ebpf-userspace/src/lib.rs +++ b/crates/cardwire-ebpf-userspace/src/lib.rs @@ -8,7 +8,7 @@ use aya::{ Btf, Ebpf, maps::{Array, HashMap, MapError, RingBuf}, programs::{Lsm, TracePoint} }; use aya_log::EbpfLogger; -use log::{Log, error, info, warn}; +use log::{Log, debug, error, info, warn}; use tokio::{ io::{Interest, unix::AsyncFd}, sync::RwLock }; @@ -150,12 +150,15 @@ impl EbpfBlocker { } Err(err) => { // If we cannot load the program, it usually mean the kernel lockdown is enabled - let lockdown = is_lockdown_enabled(); - warn!( - "Failed to load sys_exit_getdents64. Lockdown status: {}", - lockdown - ); - warn!("{}", err); + if is_lockdown_enabled() { + // Expected under lockdown, the verifier log is only noise then + warn!( + "Kernel lockdown is enabled (e.g. by Secure Boot), sys_exit_getdents64 cannot be loaded: blocked GPUs will still show up in directory listings" + ); + debug!("{}", err); + } else { + warn!("Failed to load sys_exit_getdents64: {}", err); + } warn!("falling back to a weakened cardwired..."); } }; diff --git a/docs/diagnostics/troubleshooting.md b/docs/diagnostics/troubleshooting.md index 036144f..71cc271 100644 --- a/docs/diagnostics/troubleshooting.md +++ b/docs/diagnostics/troubleshooting.md @@ -63,3 +63,20 @@ sudo systemctl restart nvidia-powerd.service > [!NOTE] > This was fixed in cardwire 0.12.1, cardwired now stop and start nvidia-powerd on mode switch instead of a naive restart + +## Secure Boot and kernel lockdown + +With Secure Boot, most distributions enable kernel lockdown. Check it with: + +```bash +cat /sys/kernel/security/lockdown +``` + +If `[integrity]` or `[confidentiality]` is selected, the kernel refuses the eBPF program that hides blocked GPUs from directory listings, and cardwired logs: + +``` +Kernel lockdown is enabled (e.g. by Secure Boot), sys_exit_getdents64 cannot be loaded: blocked GPUs will still show up in directory listings +falling back to a weakened cardwired... +``` + +Blocking still works: apps cannot open a blocked GPU, and it can still power down. The GPU's sysfs entries stay visible but cannot be read, so for example `lspci` shows a blocked GPU as `Unassigned class [ffff]: Illegal Vendor ID Device ffff`. This is expected and harmless.