Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
status: open
kind: defect
opened: 2026-10-08
---

# A claim's BAR asked for again after its handle closed panics the kernel

`pcidev::bar_object` (`kernel/src/pcidev/mod.rs`) makes one object per memory
BAR and keeps it in the claim's binding, to answer every later
`SYS_DEVICE_BAR_MAP` of that BAR with "the same object every time". The object
it keeps is counted by its handles like any other: when the one handle the
first answer installed closes, `HandleEntry`'s drop
(`kernel/src/object/handle.rs`) retires it. The binding still holds it, so the
next request for that BAR hands the retired object to `ops::install`, and
`HandleEntry::new` asserts against exactly that. The holder of a live claim
takes the machine down with three ordinary calls: ask, close, ask.

The same object is retired without a close when the first install is refused
for a full handle table: the entry built for it is dropped. Read from the
code, not run.

**Measured** at `06bbc236d`, on `tests/testcases` under QEMU with the virtio
NIC as the claimed function: `cargo test --test toyos-build -- bar_map_again`
exits 1 on

PANIC: panicked at src/object/handle.rs:108:9:
a handle to a retired SharedMem (koid 197)

after the job's line `bar_map_again: BAR 4 asked for and its handle closed;
asking again`.

No metal row was run: the T14's one function a job can claim is its I219, and
a red here is the bench's machine in a panic.

**Exit condition**: a BAR asked for again on a live claim, after every handle
to the first answer has gone, is answered with a handle that maps or with a
refusal, and `bar_map_again` is green; the arm where the first install is
refused for room is read by a test as well.

**Owner**: whoever holds `issues/every-driver-is-still-in-the-kernel.md`.

**Its test is deleted**: `a86cafa06` took `bar_map_again` out, and
`git revert a86cafa06` brings it back.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
status: open
kind: defect
opened: 2026-10-08
---

# A PCI call in flight names its function by a slot the next claim reuses

Every syscall on a PCI claim — the BAR, the DMA grants and mappings, the
config read — resolves its handle to a `pcidev` slot number
(`pci_slot` and the register target, `kernel/src/syscall/device.rs`) and lets
go of the claim before it acts. What
it then acts on is whatever `BOUND[slot]` holds when `with_bound`
(`kernel/src/pcidev/mod.rs`) takes that slot's lock, which checks that the
slot is bound and not faulted, and not whose binding it is. The two steps are
under different locks with nothing held across them.

A slot is not a name for one claim: the last handle's close releases it, a
function that was reset leaves it `Free`, and `slot::reserve`
(`kernel/pci/src/slot.rs`) gives the first free slot to the next claim,
whichever function and process that is. A call that resolved its slot before
its own claim was released therefore runs against the next holder's function,
and answers its caller with that function's object. A claim is authority over
one function for one holder; here it reaches another's.

**Read from the code, not run.** A call made after the close is refused at
the handle, so only a call already past `pci_slot` is exposed, and a thread
in a syscall holding no lock can be preempted there. A guest cannot order a
release and a second claim inside that interval; the test owes the kernel a
hold at that point, which is an actuator this tree does not have.

**Exit condition**: a call on a claim acts on that claim's binding or is
refused — its identity is held from the handle to the act, or the binding is
checked against it — and a test that holds a call between the two steps,
across the claim's release and the slot's next claim, sees it refused with
the second holder's function untouched.

**Owner**: whoever holds `issues/every-driver-is-still-in-the-kernel.md`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
status: open
kind: defect
opened: 2026-10-08
---

# netstack keeps the socket of a connection whose client sent no close

A piped TCP stream has three things in netstack
(`userland/netstack/src/main.rs`): the bridge in `piped_connections`, the
smoltcp socket in the socket set with its two 64 KiB buffers, and the id's
entry in `sockets`. A client's close request removes all three. When a
connection ends any other way — the peer finishes or resets and the client
drops its pipe ends, or the client dies — `bridge_piped` removes the bridge
and nothing else. The socket and its entry stay for the life of the process.

`max_piped_connections` counts bridges and pending connects, so each ended
connection gives its slot back while its socket stays: the bound netstack
states for what clients can make it hold does not cover this, and every
client holding the `netstack` connector can grow it one connection at a time.
`inspect` reports the entries in `net.sockets.tcp` and has no count that tells
a kept one from a live one.

**Measured** at `06bbc236d`, on `tests/netcase` under QEMU against a host
server that ends each connection at once:
`cargo test --test toyos-build -- netstack_socket_churn` exits 1 on

netstack_socket_churn: 4 connections ended and let go; netstack held 0 stream(s) before them and holds 4 after

each of the four read after `net.piped.live` had returned to its reading
before the first. The same run with the close request sent before the drop
exits 0.

**Exit condition**: a connection netstack lets go leaves no socket and no
table entry, whoever ended it, and `netstack_socket_churn` is green.

**Owner**: whoever holds `issues/toyos-has-its-own-network-stack.md`.

**Its test is deleted**: `8dd55d06a` took `netstack_socket_churn` out, with
the `netstack` connector `tests/netcase`'s runner held for it, and
`git revert 8dd55d06a` brings both back.
Loading