Skip to content

feat: add x86_64 microvm kernel flavor for bare-metal Linux hosts - #19

Merged
AprilNEA merged 5 commits into
masterfrom
feat/microvm-x86
Aug 7, 2026
Merged

feat: add x86_64 microvm kernel flavor for bare-metal Linux hosts#19
AprilNEA merged 5 commits into
masterfrom
feat/microvm-x86

Conversation

@AprilNEA

@AprilNEA AprilNEA commented Aug 7, 2026

Copy link
Copy Markdown
Member

What

The microvm flavor goes two-arch: configs/arcbox-microvm-x86_64.config + build/CI/release wiring + a KVM boot smoke for the new kernel.

Why

Prep for Firecracker sandboxes on bare-metal Linux — ArcBox-on-Linux one-command sandboxes and the platform PaaS fleet, whose arcbox-bootkit today pins the stock Firecracker CI kernel (6.1.128) for exactly this role.

Design points

  • ACPI stays ON — on x86_64, ACPI is the Firecracker boot protocol and the virtio-mmio discovery path (FC ≥ 1.7). The old VIRTIO_MMIO_CMDLINE_DEVICES note in boot-assets was stale: FC's own CI config has it off. The arm64 flavor's no-ACPI assertion therefore splits per-arch in build-kernel.sh.
  • No RTC_CLASS at all — FC x86_64 exposes no RTC device; kvmclock (KVM_GUEST) sets the wall clock at boot, ptp_kvm keeps the post-restore resync path (and being the only PTP driver keeps /dev/ptp0 unambiguous).
  • ELF vmlinux artifact — FC x86_64 boots the uncompressed ELF at the source root, not bzImage; build-kernel.sh overrides KERNEL_IMAGE for this flavor and both build paths copy from the right place.
  • Platform boot contract — the one boot-path divergence from arm64: BLK_DEV_INITRD + RD_ZSTD (bootkit's zstd cpio, rdinit=/init), squashfs with xz (backhand 0.25's default compressor) + zlib + zstd decompressors for the run-env image. Verified against the bootkit initramfs sources: mounts are template + run-env side by side, no overlayfs consumer.
  • Untrusted-workload posture — CPU mitigations stay at kernel defaults (no mitigations=off-style trimming); the same USER_NS/seccomp/cgroup surface as arm64.

Validation

Apple Silicon dev machines cannot boot this kernel, so CI does: the amd64 runner exposes /dev/kvm, and the new Boot-smoke under Firecracker (KVM) step boots the freshly built vmlinux under the pinned FC v1.16.1 with a busybox init — proving ACPI boot, ACPI virtio-mmio discovery, virtio-blk, ext4 root, ttyS0 console, and init exec on every build. arm64 keeps its hardware validation via the arcbox sandbox e2e suite.

Follow-ups (separate repos, after release)

  • boot-assets: switch the x86_64 vmlinux pin from the FC CI kernel to this artifact (drop the stale comment).
  • platform: point arcbox-bootkit's upstream pin at this kernel when adopting.
  • arcbox: x86_64 sandbox boot-args parity when Linux-host sandboxes land.

The microvm flavor goes two-arch. x86_64 serves Firecracker sandboxes on
bare-metal Linux KVM — ArcBox-on-Linux and the platform PaaS fleet
(arcbox-bootkit currently pins the stock Firecracker CI kernel there).

The config mirrors the arm64 flavor's cuts but encodes the x86_64 device
model where it genuinely differs: ACPI stays ON (it is the Firecracker
boot protocol and the virtio-mmio discovery path since 1.7 — the old
VIRTIO_MMIO_CMDLINE_DEVICES note was stale), kvmclock replaces the
missing RTC (no RTC_CLASS at all; ptp_kvm keeps the restore-resync
path), the console is the legacy COM1 8250, and the artifact is the ELF
vmlinux at the source root, not bzImage. The platform boot contract adds
the one boot-path divergence from arm64: BLK_DEV_INITRD + RD_ZSTD for
the bootkit initramfs, and squashfs with xz (backhand's default) + zlib
+ zstd decompressors for the run-env image.

build-kernel.sh drops the arm64-only gate, splits the microvm assertion
set per arch (PL031 + no-ACPI on arm64; ACPI + KVM_GUEST + initramfs +
squashfs on x86_64), and learns that vmlinux lives at the source root.

CI grows the fourth matrix leg and boot-smokes the freshly built x86_64
kernel under the pinned Firecracker on the KVM-capable amd64 runner —
ACPI boot, virtio-mmio discovery, virtio-blk, ext4 root, ttyS0, and init
exec proven on every build, since Apple Silicon dev machines cannot run
it. The release ships microvm-kernel-x86_64 alongside the existing
three artifacts.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@greptile-apps

greptile-apps Bot commented Aug 7, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds an x86_64 Firecracker microVM kernel flavor for bare-metal Linux hosts.

  • Adds a purpose-built x86_64 kernel configuration with ACPI-based virtio-mmio discovery, KVM clocks, initramfs, and squashfs support.
  • Updates the build and release paths to produce an ELF vmlinux artifact.
  • Adds a digest-pinned Firecracker KVM boot smoke test and updates repository documentation.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
configs/arcbox-microvm-x86_64.config Defines the new x86_64 Firecracker guest configuration, including hardware-reduced ACPI discovery, KVM timing, sandbox isolation primitives, and platform filesystem support.
scripts/build-kernel.sh Adds architecture-specific microVM assertions and selects the source-root ELF vmlinux for x86_64 builds.
.github/workflows/build.yml Builds, KVM boot-smokes, verifies, packages, and releases the new x86_64 microVM kernel artifact.
CLAUDE.md Documents the per-architecture microVM contracts and the requirement to keep configuration assertions synchronized.
README.md Documents the x86_64 microVM flavor, host model, boot protocol, and artifact format.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  C[arcbox-microvm-x86_64.config] --> B[build-kernel.sh]
  B --> V[ELF vmlinux artifact]
  V --> S[Firecracker KVM boot smoke]
  S --> R[Release microvm-kernel-x86_64]
Loading

Reviews (5): Last reviewed commit: "fix(x86-microvm): boot via hardware-redu..." | Re-trigger Greptile

Comment thread configs/arcbox-microvm-x86_64.config
Comment thread .github/workflows/build.yml Outdated
… smoke's Firecracker digest

The CI boot smoke caught the design error on its first run: the FC v1.16
x86_64 DSDT is 0x22E bytes with no virtio nodes — ACPI carries the boot
protocol, MADT and VMGenID, but virtio-mmio devices arrive only via the
virtio_mmio.device= entries Firecracker auto-appends to the cmdline. The
smoke booted to 'VFS: unable to mount root' with the device announced on
the cmdline and no driver listening. VIRTIO_MMIO_CMDLINE_DEVICES is now
on and asserted; the config/README narrative tells the measured story.

Review fixes: the smoke's Firecracker tarball is digest-pinned before
execution, and the RANDOMIZE_BASE line now documents why it is inert
here (x86 KASLR lives in the bzImage decompression stub, which direct
ELF loading bypasses) rather than reading as a security trade.
…Qs exist

The boot smoke's second finding, root-caused end to end: FC's MADT
carries no PCAT_COMPAT (madt.rs header flags = 0) and its device model
does not answer the i8259 data-port probe, so kernels >= 6.7 select the
NULL PIC before early_irq_init() and preallocate zero legacy IRQ
descriptors ('preallocated irqs: 0'). FC still hands ISA-range GSIs to
its cmdline virtio-mmio devices, and request_irq() without a descriptor
is -EINVAL — 'virtio_blk: probe failed with error -22', every device
dead. FC's own CI kernels (6.1) predate the behavior change, which is
why the incompatibility is invisible in their testing.

One-hunk patch via the repo's patch mechanism: when the probe finds no
PIC, still preallocate the 16-descriptor legacy range — the exact
arrangement (NULL PIC + preallocated descriptors + IOAPIC delivery) the
FC CI kernels demonstrably work in. Real-PIC and PCAT_COMPAT systems
are unaffected; the system flavors pay 16 spare descriptors.
The smoke's round-3 verdict showed the descriptor-only patch fixed half
the failure: request_irq moved from -EINVAL (no descriptor) to -ENOSYS
(descriptor with no_irq_chip). The legacy bring-up is a chain — probe
verdict -> descriptor prealloc -> mp_irqs identity mappings
(mp_config_acpi_legacy_irqs loops over nr_legacy_irqs()) -> IOAPIC
wiring — and patching stages individually is whack-a-mole. Supersede it
at the root, the way probe_8259A's own PCAT_COMPAT comment prescribes:
skip the port probe and pretend the PIC is there, so the whole chain
comes up exactly as on a PCAT system. Every VMM this tree's kernels
boot under either emulates the PIC (QEMU/KVM) or needs the full legacy
setup despite lacking one (Firecracker).
…nel policy prescribes

Three smoke rounds converged on the real model, confirmed by FC's own
docs/kernel-policy.md. Firecracker x86_64 is a hardware-reduced ACPI
platform: the FADT sets HW_REDUCED_ACPI (nulling the legacy PIC is
by-design, so the i8259 patch is deleted, not needed), the DSDT
enumerates virtio-mmio as LNRO0005 nodes, and — the piece this config
was missing — ACPI initialization inside the guest requires CONFIG_PCI
even though no PCI device ever appears. Cutting PCI produced
'AE_BAD_PARAMETER, During Region initialization' + 'Unable to load the
System Description Tables', which silently killed all ACPI enumeration
and left no virtio devices at all.

The cmdline discovery enabled in the previous fix is reverted to off:
FC deprecates it explicitly (kernel-policy.md suggests
VIRTIO_MMIO_CMDLINE_DEVICES=n and X86_MPPARSE=n), and it is actively
harmful here — FC still auto-appends the entries, and with the option
on they spawn duplicate devices with raw ISA IRQs that cannot work on
a hardware-reduced platform (the -22/-38 request_irq failures of
rounds 2-4).

Asserts follow: PCI moves to ASSERT_Y on x86_64 (stays ASSERT_N on
arm64), VIRTIO_MMIO_CMDLINE_DEVICES and X86_MPPARSE join x86_64's
ASSERT_N.
@AprilNEA
AprilNEA merged commit 6570646 into master Aug 7, 2026
9 checks passed
@AprilNEA
AprilNEA deleted the feat/microvm-x86 branch August 7, 2026 11:06
@linear-code

linear-code Bot commented Aug 7, 2026

Copy link
Copy Markdown

CORE-87

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant