XNIC

Linux · C · PCI · networking

A small Linux Ethernet driver, built to understand what happens between the kernel and a network card.

XNIC controls an emulated Intel 82540EM-compatible network device in QEMU. It sends and receives real packets, handles interrupts, and recovers from resets while traffic is running.

This is an educational driver validated with an emulated device. No physical-silicon or production-readiness conclusion is drawn.

What is happening here?

QEMU pretends to be a PCI Ethernet card. Linux discovers that card and loads XNIC. The driver then programs device registers and shares packet buffers with the device through DMA descriptor rings.

On transmit, Linux gives the driver a packet. XNIC maps its memory for the device, writes a descriptor, and rings a register “doorbell.” On receive, an interrupt schedules NAPI so Linux can process packets in batches without being overwhelmed by interrupts.

What I implemented

What I actually tested

TestObserved result
Traffic and ring wraparound646,400 requests and replies, zero packet loss; 10,100 RX and TX ring wraps.
Interface lifecycle1,000 down/up cycles and 100 driver rebind cycles.
Reset during traffic100 resets with automatic recovery and no module reload.
Bad receive descriptorsMissing end-of-packet, hardware-error, and invalid-length cases were rejected.
DPDK forwarding20 of 20 packets forwarded through the virtual PCAP path, including partial-TX cleanup.
W5500 software preflightARM64 Linux 6.8 build and sparse pass; 10 contract tests and 100 unbound module lifecycles pass with no kernel messages.

The repository contains commands, raw logs, PCAP files, versions, and expected-versus-observed results. KASAN, lockdep, physical PMD performance, and MSI execution are not claimed.

A bug the evidence exposed

A stalled 64-entry transmit ring stopped the Linux queue, but the diagnostic counter did not always show that the ring had become full. The initial hypothesis was completion timing. The real problem was that “full” was detected only on a future transmit call—after Linux had already honored the queue stop and might never call again.

The fix was to detect the transition immediately after consuming the last usable descriptor, under the same lock used by completion cleanup. The reproducer, rejected hypothesis, root cause, synchronization reasoning, and regression test are recorded in the bug diary.

Validation boundary

Validated in this repository

  • Linux PCI and netdev driver behavior in QEMU
  • DMA descriptor ownership and memory ordering
  • Interrupt/NAPI and teardown synchronization
  • Repeatable debugging and fault-path testing
  • Functional DPDK and packet-capture paths

Not validated yet

  • Physical board or new-silicon bring-up—the W5500 lab is designed but not yet executed
  • Oscilloscope, logic-analyzer, or JTAG work
  • Production or upstream driver ownership
  • Real-NIC DPDK performance validation
  • RDMA development or validation

Reproduce it

Run the same driver path yourself

The recorded baseline uses an Apple Silicon Mac, QEMU/HVF, an Ubuntu 24.04 ARM64 guest, 4 GiB of guest RAM, an Ed25519 SSH key, and roughly 8 GiB of free host storage. TCG is the slower fallback.

1 · Launch the guest

git clone https://github.com/blackdragoon26/xnic-v1.git
cd xnic-v1
./scripts/host/bootstrap-macos.sh
./scripts/host/fetch-guest.sh
./scripts/host/run-qemu.sh

2 · Copy, build, and bind

./scripts/host/sync-to-guest.sh
ssh -p 2222 xnic@127.0.0.1
cd ~/xnic-v1
sudo ./scripts/guest/setup.sh
make
sudo ./scripts/guest/bind-driver.sh

Then inspect ip -br link, ethtool -i xnic0, and ethtool -S xnic0, or run sudo ./scripts/guest/qualification-suite.sh. The complete reproduction guide includes expected observations, qualification, cleanup, and Linux-host notes.

Confidence roadmap

The next evidence that would materially strengthen XNIC

  1. Independent reproduction: a clean run performed by someone other than the author.
  2. Diagnostic kernel: complete qualification under KASAN and lockdep, with MSI actually selected.
  3. Physical bring-up: W5500 electrical, logic-analyzer, traffic, reset, and lifecycle artifacts from a Raspberry Pi.
  4. Physical DPDK path: a real PMD, controlled traffic peer, topology, repetitions, and raw counters.
  5. Release provenance: a signed tag and short demonstration tied to an exact evidence manifest.

Technical documents

These documents are rendered on this site. GitHub is available when you want the implementation or raw artifacts.

Author

Built by Sankalp Jha

XNIC is designed, implemented, tested, documented, and maintained by Sankalp Jha. Technical corrections and evidence-backed contributions are welcome.