fix(kernel): FileTableVerb::Resize no-op + ProcUptime soft-float
Two fixes on the clean base (all boot-investigation diagnostics removed): 1. ProcScheme::kcall now accepts FileTableVerb::Resize on filetable handles as a no-op instead of returning EBADF. After the upstream 'move fd allocation into userspace' relibc refactor, FILETABLE pre-syncs its size via a Resize call before growing; the kernel already grows posix_fdtbl on insert. Returning EBADF broke add_posix once a process's fd table grew (notably the bootstrap process manager proxying child thread ops), making the child's regs/env dup fail and its ld.so panic, crashing initfs daemons (randd) at boot. 2. ProcUptime uses integer arithmetic instead of f64 (the kernel is built with +soft-float; f64 in format!() breaks the build).
This commit is contained in:
+32
-7
@@ -975,14 +975,34 @@ impl KernelScheme for ProcScheme {
|
||||
handle.clone()
|
||||
};
|
||||
|
||||
let verb_raw: u8 = (*metadata.first().ok_or(Error::new(EINVAL))?)
|
||||
.try_into()
|
||||
.map_err(|_| Error::new(EINVAL))?;
|
||||
|
||||
// After the upstream "move fd allocation into userspace" relibc refactor,
|
||||
// FILETABLE.add_posix pre-syncs the kernel table size by issuing a
|
||||
// FileTableVerb::Resize call on the filetable handle before it grows.
|
||||
// The kernel already grows posix_fdtbl automatically on insert (see
|
||||
// Context::insert_file / bulk_add_files_posix), so accept this as a
|
||||
// no-op instead of rejecting the non-OpenViaDup filetable handle with
|
||||
// EBADF. Returning EBADF broke add_posix for any process whose fd table
|
||||
// grew — notably the bootstrap process manager while proxying a child's
|
||||
// thread ops — making the child's regs/env dup fail and its ld.so panic
|
||||
// ("failed to open handle for process registers"), crashing initfs
|
||||
// daemons (randd) at boot.
|
||||
if matches!(
|
||||
handle.kind,
|
||||
ContextHandle::Filetable { .. } | ContextHandle::NewFiletable { .. }
|
||||
) && verb_raw == FileTableVerb::Resize as u8
|
||||
{
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
let ContextHandle::OpenViaDup = handle.kind else {
|
||||
return Err(Error::new(EBADF));
|
||||
};
|
||||
|
||||
let verb: u8 = (*metadata.first().ok_or(Error::new(EINVAL))?)
|
||||
.try_into()
|
||||
.map_err(|_| Error::new(EINVAL))?;
|
||||
let verb = ProcSchemeVerb::try_from_raw(verb).ok_or(Error::new(EINVAL))?;
|
||||
let verb = ProcSchemeVerb::try_from_raw(verb_raw).ok_or(Error::new(EINVAL))?;
|
||||
|
||||
match verb {
|
||||
ProcSchemeVerb::Iopl => context::current()
|
||||
@@ -2000,9 +2020,14 @@ impl ContextHandle {
|
||||
read_from(buf, output.as_bytes(), offset)
|
||||
}
|
||||
ContextHandle::ProcUptime => {
|
||||
let uptime_s = crate::time::monotonic(token) as f64 / crate::time::NANOS_PER_SEC as f64;
|
||||
let idle_s = 0.0f64;
|
||||
let output = format!("{:.2} {:.2}\n", uptime_s, idle_s);
|
||||
// Red Bear fix: kernel is built with `+soft-float` (no SSE), so
|
||||
// f64 in format!() triggers "SSE register return with SSE
|
||||
// disabled" build error. Use integer arithmetic and emit
|
||||
// seconds.milliseconds without f64 division. Idle always 0.
|
||||
let nanos = crate::time::monotonic(token);
|
||||
let uptime_s = nanos / crate::time::NANOS_PER_SEC;
|
||||
let uptime_ms = (nanos % crate::time::NANOS_PER_SEC) / 1_000_000;
|
||||
let output = format!("{}.{:02} 0.00\n", uptime_s, uptime_ms);
|
||||
read_from(buf, output.as_bytes(), offset)
|
||||
}
|
||||
ContextHandle::ProcLoadavg => {
|
||||
|
||||
Reference in New Issue
Block a user