SchOS/cmd
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Nexoniarz e72205cdc0 panic: the crash screen reaches every display, not just the console's
"it also doesn't show crash screen on virtio gpu or just other gpu than default
vga" -- true, and on the virtio-gpu it was worse than nothing. The head kept
showing the console from a second before the panic: one screen saying the
kernel is dead, the other showing a shell prompt.

panic() painted into the console framebuffer and stopped there. Two cases were
missing, and they are not the same problem.

**The kernel still drives it.** display_acquire() hands back a buffer; the
report is copied in and presented. Ordinary, and a no-op when the display
class's buffer *is* the console's, so a one-screen machine does not do the work
twice.

**A process drives it.** The hard one, and the one hybrid.md owed an answer
for. The kernel let go of the device deliberately, and the process holding it
will never run again -- there is no scheduling after a panic -- so there is
nobody left to ask. It is not a race that can be won by being careful.

So the userspace driver says where it is scanning out *in advance*:
PCIIOC_PANICFB, registered by vgpud after bring-up and after every modeset. On
a panic the kernel paints the report into that memory and asks the kernel
driver the device was taken from to put it on screen one last time --
`panic_present` in struct pci_driver, which virtio-gpu implements by resetting
the device out from under a driver that is still nominally running. That is
safe here and nowhere else, because nothing is going to run again.

The panic path allocates nothing. It cannot: a corrupted heap is one of the
ways a machine gets here, and an allocator that deadlocks takes the crash
screen *and* the serial log's last chance to be read. So the driver keeps its
BAR mappings across the handover, rebuilds one queue from 20 KB of static
memory, and bounds every spin -- including the reset acknowledge, which is an
unbounded `while` in probe() and correct there.

**The registration is checked like the promise it is.** The range must lie
inside a block that process got from PCIIOC_DMA on that device. Without that,
a claimed device would be a way to nominate any physical address in the machine
-- page tables, kernel text -- to be overwritten with four megabytes of crash
report at the one moment nothing is left to notice. That is a worse bug than
the one this fixes. It goes away with the claim and with the process.

What it buys is worth stating plainly: a device can be evicted to userspace
without the kernel losing its ability to tell you the machine died. The
alternative was a driver boundary that is also a blind spot.

Verified both ways under QEMU with two heads, `echo c > /proc/sysrq`, and a
screendump of each over QMP:

  vgpud holding the device   both heads byte-identical, serial says
                             "The report is on the virtio-gpu display too."
  kernel holding it          same, via display_acquire/display_present
                             (/proc/pci shows 1af4:1050 [virtio-gpu])

Both supported configurations: one boot each, no traps, no panics, socktest and
memfdtest green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 16:53:16 +02:00
..
chvt tty: AltGr+F1..F6 by default, and AltGr+-/+ to step 2026-09-13 13:22:01 +02:00
fbinfo hybrid: /dev/pci -- a driver can live outside the kernel now 2026-09-13 15:34:28 +02:00
httpd userland: 268 applets, an editor, names that resolve, and a web server 2026-09-14 19:24:55 +02:00
inputtest Initial commit: Schunix as it stands before the SchOS rename 2026-08-09 13:47:01 +02:00
ldlsd ldls: a second driver, and everything it found 2026-09-14 15:20:07 +02:00
loadkeys kbd: three layouts, and the arrow keys were sitting on top of UTF-8 2026-09-20 01:09:32 +02:00
memfdtest memfd: a shared memory object you reach by descriptor 2026-09-22 09:47:31 +02:00
netecho ldls: L4 was free after all, and the plan closes 2026-09-14 13:37:04 +02:00
nettest net: recvfrom says who sent it, and a datagram is delivered whole 2026-08-15 16:23:06 +02:00
pcitest hybrid: the driver is killed, and the driver comes back 2026-09-14 00:05:43 +02:00
ping net: the socket layer stops saying yes to things it did not do, and ping works 2026-09-12 17:14:35 +02:00
reflink schfs: the commit barrier, reflink, and attributes with an index over them 2026-08-15 16:02:02 +02:00
resolvconf font: the console draws outlines now, and a byte could not have held Ą 2026-09-20 00:35:34 +02:00
schattr schfs: the commit barrier, reflink, and attributes with an index over them 2026-08-15 16:02:02 +02:00
schdbg debugger: D5, the network transport -- and the plan closes 2026-09-14 15:33:53 +02:00
schdbgd debugger: D5, the network transport -- and the plan closes 2026-09-14 15:33:53 +02:00
schinit boot: one line when it works, all of it when it does not 2026-09-14 21:19:50 +02:00
schinitd tty: arrow keys, backspace, and four terminals nobody was home on 2026-09-14 22:43:54 +02:00
schmode hybrid: a modeset, from a process 2026-09-14 01:36:05 +02:00
shmtest Rename Schunix to SchOS; the kernel becomes SchIFT 2026-08-09 14:09:59 +02:00
sigtest signal: the return trampoline was Linux-only, and a test that proves the rest 2026-09-21 23:56:34 +02:00
socktest unix: a bound socket is a file 2026-09-22 10:06:10 +02:00
vgpud panic: the crash screen reaches every display, not just the console's 2026-09-22 16:53:16 +02:00