From b906ad688acaa6f9eb42500b51e8ffb5516c7d86 Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Sat, 25 Jul 2026 00:11:55 +0900 Subject: [PATCH] acpid: allow PCI fd replacement; eagerly init AML symbols on sendfd Closes the v4.0 plan P3 'acpid pci_fd is not registered' item. Two related defects: 1. scheme.rs::on_sendfd had a one-shot EINVAL when self.pci_fd was already Some. Combined with the lazy AML context init in AcpiContext::aml_symbols, this created a permanent failure mode: - pcid starts AFTER acpid (per the requires_weak chain) - if a /scheme/acpi/symbols request arrives before pcid's sendfd reaches acpid, the aml init runs with pci_fd = None and logs 'pci_fd is not registered' at error level - the resulting aml_context state makes subsequent retries fail the same way; the next pcid sendfd hits the one-shot EINVAL and is rejected - aml stays broken for the entire boot Fix: allow replacement (warn-and-replace on subsequent sendfd). Document the bug history inline so a future agent does not 'clean up' the warn log. 2. aml_physmem.rs::AmlPhysMemHandler::new logged the missing fd at log::error. Downgrade to log::warn -- the deferred-init path is normal during the acpid-then-pcid ordering window and an error level is misleading. 3. scheme.rs::on_sendfd now eagerly calls self.ctx.aml_symbols() after setting pci_fd, so the symbol cache is built immediately rather than on the first consumer request. The error path logs at error level (with Debug-formatted detail because AmlError does not implement Display), making the failure observable rather than silently deferred. Test note: cargo test -p acpid fails to link on the host because libredox's redox_munmap_v1 is target-only; this is pre-existing and unrelated to this change. cargo check -p acpid is clean. --- drivers/acpid/src/aml_physmem.rs | 4 +++- drivers/acpid/src/scheme.rs | 23 ++++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/acpid/src/aml_physmem.rs b/drivers/acpid/src/aml_physmem.rs index 3f4465d0d2..3abfa3661c 100644 --- a/drivers/acpid/src/aml_physmem.rs +++ b/drivers/acpid/src/aml_physmem.rs @@ -178,7 +178,9 @@ impl AmlPhysMemHandler { let pci_fd = if let Some(pci_fd) = pci_fd_opt { Some(libredox::Fd::new(pci_fd.raw())) } else { - log::error!("pci_fd is not registered"); + log::warn!( + "acpid: AmlPhysMemHandler created without PCI fd; AML init will retry once pcid sends it via scheme:acpid sendfd" + ); None }; Self { diff --git a/drivers/acpid/src/scheme.rs b/drivers/acpid/src/scheme.rs index a066f14e9d..cc7ead81d9 100644 --- a/drivers/acpid/src/scheme.rs +++ b/drivers/acpid/src/scheme.rs @@ -1070,10 +1070,27 @@ impl SchemeSync for AcpiScheme<'_, '_> { } let new_fd = libredox::Fd::new(new_fd); + // Allow replacement: pcid may resend the fd after a restart, + // and the previous one-shot EINVAL left aml init permanently + // broken if the first sendfd raced with an early aml request. if self.pci_fd.is_some() { - return Err(Error::new(EINVAL)); - } else { - self.pci_fd = Some(new_fd); + log::warn!( + "acpid: replacing previously-registered PCI fd; AML symbol cache will rebuild on next request" + ); + } + self.pci_fd = Some(new_fd); + + // Kick aml symbol init now that pci_fd is registered. The + // next aml request will either find a working cache or get a + // fresh error log here; either way the failure mode is + // observable rather than silently deferred to "the next + // caller retries". + match self.ctx.aml_symbols(self.pci_fd.as_ref()) { + Ok(_) => log::info!("acpid: AML symbols initialized on PCI fd registration"), + Err(err) => { + log::error!("acpid: AML symbol init failed after PCI fd registration"); + log::error!("acpid: AML error detail: {:?}", err); + } } Ok(num_fds)