diff --git a/drivers/cube/cubelinux_store.rs b/drivers/cube/cubelinux_store.rs index dfe224192..18de5b2d9 100644 --- a/drivers/cube/cubelinux_store.rs +++ b/drivers/cube/cubelinux_store.rs @@ -4168,6 +4168,23 @@ impl kernel::InPlaceModule for CubeStoreModule { pr_info!("cubelinux: store reader registered at /dev/cubelinux\n"); // SAFETY: called exactly once, in the module initializer, before anything can take it. unsafe { SPACE_STARTS.init() }; + // STORE_FILE needs the same treatment, and it was the one that went without. + // + // The failure mode is why it hid for so long. A zeroed mutex satisfies the uncontended + // fast path — the count reads 0, which means "unlocked" — so one writer at a time works + // perfectly and nothing looks wrong. The first *contended* lock takes + // __mutex_lock_slowpath, which splices the task into the mutex's wait list; that list is + // uninitialised, so its head is NULL and the splice stores through it. A write to address + // 0 in kernel mode, after which the task returns with interrupts disabled and + // preemption held, which is a machine that cannot panic, log, or recover. + // + // Found by verify-file-store.sh MODE=race: twelve concurrent puts to a store that is a + // file on the root filesystem oopsed in cubelinux_store::store_file, while twelve + // sequential ones passed with exact log accounting. The same signature is on the box, + // where the store had several writers: a hard freeze with no panic despite panic=30, and + // a journal that simply stops. + // SAFETY: called exactly once, in the module initializer, before anything can take it. + unsafe { STORE_FILE.init() }; try_pin_init!(Self { _miscdev <- MiscDeviceRegistration::register(MiscDeviceOptions { name: c_str!("cubelinux"),