Skip to content

Implement Windows host support (WHPX) - #90

Open
mrexodia wants to merge 14 commits into
earendil-works:mainfrom
mrexodia:windows-support
Open

Implement Windows host support (WHPX)#90
mrexodia wants to merge 14 commits into
earendil-works:mainfrom
mrexodia:windows-support

Conversation

@mrexodia

@mrexodia mrexodia commented Apr 15, 2026

Copy link
Copy Markdown

Closes #21

Session: https://pi.dev/session/#009bb13df5408d6e7dff80631eb6df69
Review: https://pi.dev/session/#79f60c5f2455ebc93d66e3a31b0febbd

Manual testing report (this is what I ran myself to confirm things work): https://gist.github.com/mrexodia/b3261b1a5d05b37a7834d36f997ded74

Currently working on getting the GitHub Actions to actually pass (also tests Windows), might take a little bit...

Happy to do some more work to clean this up into separate commits if you are willing to merge this in principle. I glanced over the code and most things looked reasonable, but I only focused on getting it to actually work for now.

Contribution Agreement

Please ensure this PR follows the guidelines in CONTRIBUTING.md. (NOTE: this file does not exist in the repo)

By submitting this pull request, I confirm the following:

I understand that the entity Earendil Inc. (incorporated in the state of Delaware in 2025) needs some rights from me in order to utilize my contributions in this PR. As a contributor I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Earendil Inc. can use, modify, copy, and redistribute my contributions, under Earendil Inc.'s choice of terms.

@mrexodia
mrexodia force-pushed the windows-support branch 2 times, most recently from ffd5e6e to eecacb6 Compare April 16, 2026 00:02
@mrexodia

Copy link
Copy Markdown
Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e4ec901c72

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread host/src/sandbox/server-transport.ts Outdated
Comment thread host/src/cli/mount-spec.ts Outdated
@mrexodia
mrexodia force-pushed the windows-support branch 2 times, most recently from da9924d to a5d828a Compare April 16, 2026 21:25
@mrexodia
mrexodia marked this pull request as ready for review April 16, 2026 22:12

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a5d828aa3a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread host/src/sandbox/server-ops.ts
@mrexodia
mrexodia force-pushed the windows-support branch 2 times, most recently from 9dd34a8 to 16a68d3 Compare April 22, 2026 20:49
@cravenceiling

Copy link
Copy Markdown

+1

@mrexodia

Copy link
Copy Markdown
Author

I rebased, workflows are currently running on my repo: https://github.com/mrexodia/gondolin/actions/runs/26248033650

@mrexodia

Copy link
Copy Markdown
Author

https://github.com/mrexodia/gondolin/actions/runs/26251373997 CI is green again!

mrexodia added 12 commits July 10, 2026 17:17
secret-host-suggestions.ts hardcoded a POSIX /tmp fallback that was
never updated when the rest of the codebase moved to os.tmpdir() for
Windows support, so `--host-secret NAME` (without an explicit @host)
threw ENOENT on Windows before the VM even started.
quoteCmdArg caret-escaped characters (including embedded double
quotes) inside a quoted argument, which corrupts cmd.exe's own
command-line parsing rather than producing a literal character -
verified empirically against a real cmd.exe that this silently broke
the whole invocation. Also drops the unnecessary `call` prefix when
re-exec'ing through cmd.exe: `call`'s own argument re-parsing doesn't
respect caret-escaped metacharacters the way a plain `/s`-wrapped
command line does, which is what actually made metacharacter escaping
(&, |, <, >) work correctly. Arguments containing a literal double
quote are now rejected outright rather than silently mis-invoked,
since there's no reliable way to deliver one to a .bat/.cmd file's
argv through cmd.exe.

Adds unit tests plus a real cmd.exe end-to-end test (skipped off
Windows) since this logic previously had no coverage at all.
host/src/qemu/img.ts and host/src/sandbox/server-options.ts each
independently reimplemented near-identical Windows QEMU-family binary
discovery (probe via --version, search ProgramW6432/ProgramFiles
install roots, dedupe, pick first responder), differing only in the
target binary basename - a fix to the install-path heuristics had to
be applied in both places or they'd silently drift apart. Extracts
the shared logic into qemu/locate-binary.ts and rewires both call
sites, plus the third near-duplicate in the test WHPX probe helper.
…ints

Standalone addition so later commits (and a later dedup pass) have a
single place to construct a throwaway win32-vs-unix test endpoint,
instead of every test file hand-rolling the same platform branch.
selectRngObject() returned null on win32, so every Windows-hosted
guest booted with no virtio-rng device at all - a real capability
regression vs Linux/macOS hosts, previously undocumented and
untested. Uses QEMU's cross-platform rng-builtin backend instead
(host getrandom()/BCryptGenRandom, no /dev/urandom-equivalent device
file needed, available since QEMU 5.0).
qemuCanInitializeAccel probes WHPX support via synchronous
spawnSync with up to a 1.5s timeout, invoked from selectAccel on
every sandbox/VM creation. spawnSync blocks the entire Node event
loop (not just the calling async context), so the first WHPX probe
for a given qemuPath stalls any other in-flight sandbox's I/O in the
same host process.

Adds an async primeAccelProbeCache that performs the same probe via
non-blocking spawn and populates the same cache selectAccel reads
from. resolveSandboxServerOptionsAsync (the path SandboxServer.create
uses, i.e. the recommended API) awaits it before the synchronous accel
selection runs, so the common case never blocks. The synchronous
SandboxServer constructor has no async alternative available and
keeps today's existing (unworsened) blocking behavior.
The QMP idle-pause monitor was hardcoded to a Unix domain socket
(defaultQmpSocketPath, executeQmpCommand, and the buildQemuArgs
-qmp arg), unlike every other virtio/network socket in this
codebase which already went through the cross-platform LocalEndpoint
abstraction. Nothing rejected setting sandbox.qemuIdlePauseMs on
Windows, so a user who opted in would hit a broken QMP connection
attempt at runtime with no test ever having exercised that path.

Reserves a loopback TCP port for the QMP endpoint on Windows (QEMU's
-qmp chardev supports tcp:host:port just as well as unix:path) and
resolves it lazily since the port reservation needs an async
bind/close round trip that can't happen in the constructor - start()
awaits it before spawning qemu, guarded by a new `starting` flag so a
concurrent start() call can't slip past the child-process check while
that's in flight. The one await point is skipped entirely when
idle-pause isn't configured, so the common case stays fully
synchronous like before.

Un-skips and rewrites the "idle pause uses a short QMP socket" test to
exercise a real QMP round trip over whichever transport the platform
actually uses, instead of being unconditionally skipped on Windows.
skipIfBackendUnavailable skipped the entire suite on win32 regardless
of backend - including "qemu", the backend this codebase's Windows
support actually uses - citing a "Windows QEMU suite" that doesn't
exist anywhere in the repo. VM boot+exec, rootfs-resize, VFS mount
parity, and network-egress-mediation-via-httpHooks assertions never
ran on Windows for the one backend that's supported there. Now only
krun (genuinely unsupported on Windows) is skipped; qemu falls
through to the existing shouldSkipVmTests() hardware-accel gate like
every other platform.
All ~16 path-traversal/symlink-escape security tests (the guard that
stops a sandboxed guest from escaping a --mount-hostfs mount root via
symlinks) were unconditionally skipped on win32, on the assumption
symlinks always need elevation there - not true under Developer Mode
or an elevated process, and this left the guard completely untested
wherever it's actually capable of running. Replaces the platform
check with a one-time real symlink-creation probe, so the tests run
for real wherever they can.

Running them for real surfaced one genuine, safe platform behavior
difference: Windows' RemoveDirectory (unlike POSIX rmdir) doesn't
refuse to operate on a directory symlink/junction, it removes the
reparse point itself without following it - equally safe (the real
target is never touched) but doesn't throw ENOTDIR. The affected test
now asserts the platform-appropriate outcome instead of assuming
POSIX semantics everywhere.
The sole test for recoverGitBashPathListSpec mocked runCygpath to
return a hardcoded string instead of exercising real `cygpath -u -p`
output, so a real-world cygpath format difference (spaces, drive
letters, the trailing non-path "ro" token) could silently break the
recovery path while the test kept passing.

Replaces the mock's fixture with a value verified against a real
cygpath.exe invocation (the previous fixture used a path nested under
a typical Git-for-Windows install root, which coincidentally collapses
under cygpath's own POSIX root mount - a misleading, environment-
dependent "realistic-looking" value that wasn't actually representative).
Adds a real end-to-end test exercising defaultRunCygpath's actual
execFileSync("cygpath", ...) call, gated on cygpath being available.
…elper

Six test files each hand-rolled their own win32-vs-unix endpoint
constructor with slightly different literal values (fixed vs
ephemeral ports, different path construction), instead of using the
shared makeTestEndpoint helper - a future change to Windows loopback-
endpoint defaults would need to be found and updated in six places,
and missing one would leave that file silently asserting stale
transport semantics.
…less of host OS

Used the native `path` module (path.join/path.delimiter/path.extname),
which follows the actual host OS's conventions rather than Windows'.
deps.platform lets callers simulate win32 path resolution from a
non-Windows host (exactly what the new unit tests do), but on a real
Linux/macOS CI runner path.delimiter is ":" and path.join uses "/" -
so a simulated "PATH=C:\a;C:\tools" never split correctly and the
.cmd-shim-on-PATH test failed for real on Linux CI. Switches to
path.win32 explicitly, since this function's entire purpose is
resolving a Windows PATH/PATHEXT lookup irrespective of what platform
happens to be running the code.
@CeruleanSky

CeruleanSky commented Aug 24, 2026

Copy link
Copy Markdown

Thank you for your efforts, I hope this gets reviewed and merged next round or two, maybe pi is tying their hands up, or they need a ping.

I was testing things out, I am using QEMU emulator version 11.1.0 (v11.1.0-12130-ge470268ff4) with intel i7-7700hq on a laptop.

I ran into problems with the test that determines if whpx will work or not, but my experiments show that qemu will still run with accel whpx if you bypass it.

D:\qemu>qemu-system-x86_64 -accel whpx -machine none -nodefaults -display none -S

Just prints out:
/home/stefan/src/qemu/repo.or.cz/qemu/ar7/include/hw/i386/x86.h:107:X86_MACHINE: Object 0000016850a99480 is not an instance of type x86-machine

Details

I attached a full -trace enable=* log of the command.

trace log excerpt:
object_class_dynamic_cast_assert type=whpx-accel->accel (../../../accel/accel-common.c:22:accel_find)
object_new obj=0000023b460d2360 type=whpx-accel
object_dynamic_cast_assert obj=0000023b460d2360 type=whpx-accel->accel (../../../system/vl.c:2419:do_configure_accelerator)
object_class_dynamic_cast_assert type=whpx-accel->accel (../../../accel/accel-system.c:41:accel_init_machine)
object_dynamic_cast_assert obj=0000023b45f34a90 type=none-machine->x86-machine (/home/stefan/src/qemu/repo.or.cz/qemu/ar7/include/hw/i386/x86.h:107:X86_MACHINE)
/home/stefan/src/qemu/repo.or.cz/qemu/ar7/include/hw/i386/x86.h:107:X86_MACHINE: Object 0000023b45f34a90 is not an instance of type x86-machine

Then exits with errorlevel 3:
D:\qemu>echo %ERRORLEVEL%
3

But I changed:

    if (process.platform === "win32") {
        if (targetArch !== "x64")
            return "tcg";
        if (!qemuPath)
            return "whpx";
        if (!qemuSupportsAccel(qemuPath, "whpx")) {
            return "tcg";
        }
        return qemuCanInitializeAccel(qemuPath, "whpx") ? "whpx" : "tcg";
    }

To: if (process.platform === "win32") return"whpx"; and qemu does launch just fine.

dmesg output:
 $ dmesg

[    0.000000] Linux version 6.18.22-0-virt (buildozer@build-3-23-x86_64) (cc (Alpine 15.2.0) 15.2.0, GNU ld (GNU Binutils) 2.45.1) #1-Alpine SMP PREEMPT_DYNAMIC 2026-04-11 15:53:25
[    0.000000] Command line: console=ttyS0 initramfs_async=1 sandboxfs.mount=/data sandboxfs.bind=/etc/gondolin,/etc/gondolin/mitm,/workspace
[    0.000000] x86/CPU: Model not found in latest microcode list
[    0.000000] BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
[    0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved
[    0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000003ffdcfff] usable
[    0.000000] BIOS-e820: [mem 0x000000003ffdd000-0x000000003fffffff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000b0000000-0x00000000bfffffff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000fed1c000-0x00000000fed1ffff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000fffc0000-0x00000000ffffffff] reserved
[    0.000000] NX (Execute Disable) protection: active
[    0.000000] APIC: Static calls initialized
[    0.000000] SMBIOS 2.8 present.
[    0.000000] DMI: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
[    0.000000] DMI: Memory slots populated: 1/1
[    0.000000] vmware: hypercall mode: 0x00
[    0.000000] Hypervisor detected: VMware
[    0.000000] vmware: TSC freq read from hypervisor : 2807.999 MHz
[    0.000000] vmware: Host bus clock speed read from hypervisor : 1000000000 Hz
[    0.000000] vmware: using clock offset of 785507694 ns
[    0.000126] tsc: Detected 2807.999 MHz processor
[    0.001082] e820: update [mem 0x00000000-0x00000fff] usable ==> reserved
[    0.001088] e820: remove [mem 0x000a0000-0x000fffff] usable
[    0.001096] last_pfn = 0x3ffdd max_arch_pfn = 0x400000000
[    0.001126] MTRR map: 4 entries (3 fixed + 1 variable; max 19), built from 8 variable MTRRs
[    0.001130] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT
[    0.011480] found SMP MP-table at [mem 0x000f54a0-0x000f54af]
[    0.011660] RAMDISK: [mem 0x3f9ec000-0x3ffcffff]
[    0.011663] ACPI: Early table checksum verification disabled
[    0.011667] ACPI: RSDP 0x00000000000F52C0 000014 (v00 BOCHS )
[    0.011674] ACPI: RSDT 0x000000003FFE2373 000038 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.011682] ACPI: FACP 0x000000003FFE2163 0000F4 (v03 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.011733] ACPI: DSDT 0x000000003FFE0040 002123 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.011738] ACPI: FACS 0x000000003FFE0000 000040
[    0.011742] ACPI: APIC 0x000000003FFE2257 000080 (v03 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.011745] ACPI: HPET 0x000000003FFE22D7 000038 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.011750] ACPI: MCFG 0x000000003FFE230F 00003C (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.011755] ACPI: WAET 0x000000003FFE234B 000028 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.011759] ACPI: Reserving FACP table memory at [mem 0x3ffe2163-0x3ffe2256]
[    0.011761] ACPI: Reserving DSDT table memory at [mem 0x3ffe0040-0x3ffe2162]
[    0.011762] ACPI: Reserving FACS table memory at [mem 0x3ffe0000-0x3ffe003f]
[    0.011763] ACPI: Reserving APIC table memory at [mem 0x3ffe2257-0x3ffe22d6]
[    0.011764] ACPI: Reserving HPET table memory at [mem 0x3ffe22d7-0x3ffe230e]
[    0.011765] ACPI: Reserving MCFG table memory at [mem 0x3ffe230f-0x3ffe234a]
[    0.011767] ACPI: Reserving WAET table memory at [mem 0x3ffe234b-0x3ffe2372]
[    0.012959] No NUMA configuration found
[    0.012961] Faking a node at [mem 0x0000000000000000-0x000000003ffdcfff]
[    0.012967] NODE_DATA(0) allocated [mem 0x3ffd8d40-0x3ffdcfff]
[    0.013249] Zone ranges:
[    0.013251]   DMA      [mem 0x0000000000001000-0x0000000000ffffff]
[    0.013254]   DMA32    [mem 0x0000000001000000-0x000000003ffdcfff]
[    0.013256]   Normal   empty
[    0.013257] Movable zone start for each node
[    0.013259] Early memory node ranges
[    0.013259]   node   0: [mem 0x0000000000001000-0x000000000009efff]
[    0.013261]   node   0: [mem 0x0000000000100000-0x000000003ffdcfff]
[    0.013263] Initmem setup node 0 [mem 0x0000000000001000-0x000000003ffdcfff]
[    0.013336] On node 0, zone DMA: 1 pages in unavailable ranges
[    0.014686] On node 0, zone DMA: 97 pages in unavailable ranges
[    0.101872] On node 0, zone DMA32: 35 pages in unavailable ranges
[    0.103493] ACPI: PM-Timer IO Port: 0x608
[    0.103514] ACPI: LAPIC_NMI (acpi_id[0xff] dfl dfl lint[0x1])
[    0.103745] IOAPIC[0]: apic_id 0, version 32, address 0xfec00000, GSI 0-23
[    0.103752] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
[    0.103755] ACPI: INT_SRC_OVR (bus 0 bus_irq 5 global_irq 5 high level)
[    0.103757] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
[    0.103758] ACPI: INT_SRC_OVR (bus 0 bus_irq 10 global_irq 10 high level)
[    0.103760] ACPI: INT_SRC_OVR (bus 0 bus_irq 11 global_irq 11 high level)
[    0.103766] ACPI: Using ACPI (MADT) for SMP configuration information
[    0.103768] ACPI: HPET id: 0x8086a201 base: 0xfed00000
[    0.103783] CPU topo: Max. logical packages:   1
[    0.103784] CPU topo: Max. logical dies:       1
[    0.103785] CPU topo: Max. dies per package:   1
[    0.103793] CPU topo: Max. threads per core:   1
[    0.103794] CPU topo: Num. cores per package:     2
[    0.103795] CPU topo: Num. threads per package:   2
[    0.103795] CPU topo: Allowing 2 present CPUs plus 0 hotplug CPUs
[    0.103809] [mem 0x40000000-0xafffffff] available for PCI devices
[    0.103811] Booting paravirtualized kernel on VMware hypervisor
[    0.103813] clocksource: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1910969940391419 ns
[    0.110469] setup_percpu: NR_CPUS:256 nr_cpumask_bits:2 nr_cpu_ids:2 nr_node_ids:1
[    0.121462] percpu: Embedded 55 pages/cpu s185752 r8192 d31336 u1048576
[    0.121474] pcpu-alloc: s185752 r8192 d31336 u1048576 alloc=1*2097152
[    0.121478] pcpu-alloc: [0] 0 1
[    0.121535] Kernel command line: console=ttyS0 initramfs_async=1 sandboxfs.mount=/data sandboxfs.bind=/etc/gondolin,/etc/gondolin/mitm,/workspace
[    0.121607] printk: log buffer data + meta data: 131072 + 458752 = 589824 bytes
[    0.127275] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
[    0.130073] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
[    0.130229] Fallback order for Node 0: 0
[    0.130234] Built 1 zonelists, mobility grouping on.  Total pages: 262011
[    0.130236] Policy zone: DMA32
[    0.142600] mem auto-init: stack:all(zero), heap alloc:on, heap free:off
[    0.157107] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
[    0.157483] Kernel/User page tables isolation: enabled
[    0.160860] Dynamic Preempt: none
[    0.161215] rcu: Preemptible hierarchical RCU implementation.
[    0.161217] rcu:    RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=2.
[    0.161220]    Trampoline variant of Tasks RCU enabled.
[    0.161221]    Tracing variant of Tasks RCU enabled.
[    0.161222] rcu: RCU calculated value of scheduler-enlistment delay is 100 jiffies.
[    0.161223] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2
[    0.161233] RCU Tasks: Setting shift to 1 and lim to 1 rcu_task_cb_adjust=1 rcu_task_cpu_ids=2.
[    0.161235] RCU Tasks Trace: Setting shift to 1 and lim to 1 rcu_task_cb_adjust=1 rcu_task_cpu_ids=2.
[    0.171740] NR_IRQS: 16640, nr_irqs: 440, preallocated irqs: 16
[    0.172393] rcu: srcu_init: Setting srcu_struct sizes based on contention.
[    0.173521] kfence: initialized - using 2097152 bytes for 255 objects at 0x(____ptrval____)-0x(____ptrval____)
[    0.174000] Console: colour *CGA 80x25
[    0.174128] printk: legacy console [ttyS0] enabled
[    0.583676] ACPI: Core revision 20250807
[    0.587047] clocksource: hpet: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604467 ns
[    0.592966] APIC: Switch to symmetric I/O mode setup
[    0.599872] x2apic enabled
[    0.603889] APIC: Switched APIC routing to: physical x2apic
[    0.618972] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
[    0.622551] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x2879c523a63, max_idle_ns: 440795252908 ns
[    0.629470] Calibrating delay loop (skipped) preset value.. 5615.99 BogoMIPS (lpj=2807999)
[    0.632395] Last level iTLB entries: 4KB 64, 2MB 8, 4MB 8
[    0.632473] Last level dTLB entries: 4KB 64, 2MB 32, 4MB 32, 1GB 4
[    0.633482] mitigations: Enabled attack vectors: user_kernel, user_user, guest_host, guest_guest, SMT mitigations: auto
[    0.634474] Speculative Store Bypass: Vulnerable
[    0.635475] Spectre V2 : Mitigation: Retpolines
[    0.636473] ITS: Mitigation: Aligned branch/return thunks
[    0.637473] MDS: Vulnerable: Clear CPU buffers attempted, no microcode
[    0.638473] Spectre V1 : Mitigation: usercopy/swapgs barriers and __user pointer sanitization
[    0.639474] Spectre V2 : Spectre v2 / SpectreRSB: Filling RSB on context switch and VMEXIT
[    0.640476] active return thunk: its_return_thunk
[    0.641476] x86/fpu: x87 FPU will use FXSAVE
[    0.663464] Freeing SMP alternatives memory: 40K
[    0.663483] pid_max: default: 32768 minimum: 301
[    0.665082] LSM: initializing lsm=lockdown,capability,landlock
[    0.666725] landlock: Up and running.
[    0.667464] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.667578] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.672464] smpboot: CPU0: Intel QEMU Virtual CPU version 2.5+ (family: 0xf, model: 0x6b, stepping: 0x1)
[    0.674464] Performance Events: unsupported Netburst CPU model 107 no PMU driver, software events only.
[    0.674646] signal: max sigframe size: 1440
[    0.675717] rcu: Hierarchical SRCU implementation.
[    0.676471] rcu:    Max phase no-delay instances is 400.
[    0.678719] Timer migration: 1 hierarchy levels; 8 children per group; 1 crossnode level
[    0.682464] NMI watchdog: Perf NMI watchdog permanently disabled
[    0.682925] smp: Bringing up secondary CPUs ...
[    0.685464] smpboot: x86: Booting SMP configuration:
[    0.685482] .... node  #0, CPUs:      #1
[    0.689676] smp: Brought up 1 node, 2 CPUs
[    0.691472] smpboot: Total of 2 processors activated (11231.99 BogoMIPS)
[    0.693840] Memory: 979964K/1048044K available (14616K kernel code, 2027K rwdata, 9740K rodata, 2996K init, 1184K bss, 64328K reserved, 0K cma-reserved)
[    0.697574] devtmpfs: initialized
[    0.698621] x86/mm: Memory block size: 128MB
[    0.703663] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911260446275000 ns
[    0.704592] posixtimers hash table entries: 1024 (order: 2, 16384 bytes, linear)
[    0.705670] futex hash table entries: 512 (32768 bytes on 1 NUMA nodes, total 32 KiB, linear).
[    0.717316] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[    0.720020] audit: initializing netlink subsys (disabled)
[    0.722999] thermal_sys: Registered thermal governor 'step_wise'
[    0.723046] audit: type=2000 audit(1787598535.108:1): state=initialized audit_enabled=0 res=1
[    0.728514] cpuidle: using governor ladder
[    0.730507] cpuidle: using governor menu
[    0.732672] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5
[    0.735865] PCI: ECAM [mem 0xb0000000-0xbfffffff] (base 0xb0000000) for domain 0000 [bus 00-ff]
[    0.739477] PCI: ECAM [mem 0xb0000000-0xbfffffff] reserved as E820 entry
[    0.742487] PCI: Using configuration type 1 for base access
[    0.745674] kprobes: kprobe jump-optimization is enabled. All kprobes are optimized if possible.
[    0.752864] HugeTLB: registered 2.00 MiB page size, pre-allocated 0 pages
[    0.755470] HugeTLB: 28 KiB vmemmap can be freed for a 2.00 MiB page
[    0.760418] ACPI: Added _OSI(Module Device)
[    0.761475] ACPI: Added _OSI(Processor Device)
[    0.762474] ACPI: Added _OSI(Processor Aggregator Device)
[    0.766464] ACPI: 1 ACPI AML tables successfully acquired and loaded
[    0.769704] ACPI: Interpreter enabled
[    0.771496] ACPI: PM: (supports S0 S3 S5)
[    0.772470] ACPI: Using IOAPIC for interrupt routing
[    0.774533] PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and report a bug
[    0.775474] PCI: Using E820 reservations for host bridge windows
[    0.777652] ACPI: Enabled 2 GPEs in block 00 to 3F
[    0.783855] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
[    0.784483] acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI HPX-Type3]
[    0.787588] acpi PNP0A08:00: _OSC: platform does not support [PCIeHotplug LTR]
[    0.789566] acpi PNP0A08:00: _OSC: OS now controls [PME PCIeCapability]
[    0.793037] PCI host bridge to bus 0000:00
[    0.794481] pci_bus 0000:00: root bus resource [io  0x0000-0x0cf7 window]
[    0.797474] pci_bus 0000:00: root bus resource [io  0x0d00-0xffff window]
[    0.800475] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff window]
[    0.802490] pci_bus 0000:00: root bus resource [mem 0x40000000-0xafffffff window]
[    0.805518] pci_bus 0000:00: root bus resource [mem 0xc0000000-0xfebfffff window]
[    0.808476] pci_bus 0000:00: root bus resource [mem 0x100000000-0x8ffffffff window]
[    0.812476] pci_bus 0000:00: root bus resource [bus 00-ff]
[    0.814725] pci 0000:00:00.0: [8086:29c0] type 00 class 0x060000 conventional PCI endpoint
[    0.820464] pci 0000:00:01.0: [1af4:1001] type 00 class 0x010000 conventional PCI endpoint
[    0.826464] pci 0000:00:01.0: BAR 0 [io  0xc000-0xc07f]
[    0.827517] pci 0000:00:01.0: BAR 1 [mem 0xfebc0000-0xfebc0fff]
[    0.829602] pci 0000:00:01.0: BAR 4 [mem 0xfebf0000-0xfebf3fff 64bit pref]
[    0.835464] pci 0000:00:02.0: [1af4:1005] type 00 class 0x00ff00 conventional PCI endpoint
[    0.839464] pci 0000:00:02.0: BAR 0 [io  0xc100-0xc11f]
[    0.841511] pci 0000:00:02.0: BAR 1 [mem 0xfebc1000-0xfebc1fff]
[    0.843602] pci 0000:00:02.0: BAR 4 [mem 0xfebf4000-0xfebf7fff 64bit pref]
[    0.849464] pci 0000:00:03.0: [1af4:1003] type 00 class 0x078000 conventional PCI endpoint
[    0.856472] pci 0000:00:03.0: BAR 0 [io  0xc080-0xc0bf]
[    0.858516] pci 0000:00:03.0: BAR 1 [mem 0xfebc2000-0xfebc2fff]
[    0.860646] pci 0000:00:03.0: BAR 4 [mem 0xfebf8000-0xfebfbfff 64bit pref]
[    0.866507] pci 0000:00:04.0: [1af4:1000] type 00 class 0x020000 conventional PCI endpoint
[    0.869464] pci 0000:00:04.0: BAR 0 [io  0xc120-0xc13f]
[    0.871516] pci 0000:00:04.0: BAR 1 [mem 0xfebc3000-0xfebc3fff]
[    0.873615] pci 0000:00:04.0: BAR 4 [mem 0xfebfc000-0xfebfffff 64bit pref]
[    0.875509] pci 0000:00:04.0: ROM [mem 0xfeb80000-0xfebbffff pref]
[    0.881464] pci 0000:00:1f.0: [8086:2918] type 00 class 0x060100 conventional PCI endpoint
[    0.884859] pci 0000:00:1f.0: quirk: [io  0x0600-0x067f] claimed by ICH6 ACPI/GPIO/TCO
[    0.889680] pci 0000:00:1f.2: [8086:2922] type 00 class 0x010601 conventional PCI endpoint
[    0.893540] pci 0000:00:1f.2: BAR 4 [io  0xc140-0xc15f]
[    0.895515] pci 0000:00:1f.2: BAR 5 [mem 0xfebc4000-0xfebc4fff]
[    0.899023] pci 0000:00:1f.3: [8086:2930] type 00 class 0x0c0500 conventional PCI endpoint
[    0.904439] pci 0000:00:1f.3: BAR 4 [io  0x0700-0x073f]
[    0.911262] ACPI: PCI: Interrupt link LNKA configured for IRQ 10
[    0.913493] ACPI: PCI: Interrupt link LNKB configured for IRQ 10
[    0.914780] ACPI: PCI: Interrupt link LNKC configured for IRQ 11
[    0.916715] ACPI: PCI: Interrupt link LNKD configured for IRQ 11
[    0.920725] ACPI: PCI: Interrupt link LNKE configured for IRQ 10
[    0.923555] ACPI: PCI: Interrupt link LNKF configured for IRQ 10
[    0.926717] ACPI: PCI: Interrupt link LNKG configured for IRQ 11
[    0.929724] ACPI: PCI: Interrupt link LNKH configured for IRQ 11
[    0.932597] ACPI: PCI: Interrupt link GSIA configured for IRQ 16
[    0.934501] ACPI: PCI: Interrupt link GSIB configured for IRQ 17
[    0.935504] ACPI: PCI: Interrupt link GSIC configured for IRQ 18
[    0.937503] ACPI: PCI: Interrupt link GSID configured for IRQ 19
[    0.940503] ACPI: PCI: Interrupt link GSIE configured for IRQ 20
[    0.942492] ACPI: PCI: Interrupt link GSIF configured for IRQ 21
[    0.945500] ACPI: PCI: Interrupt link GSIG configured for IRQ 22
[    0.948502] ACPI: PCI: Interrupt link GSIH configured for IRQ 23
[    0.952186] iommu: Default domain type: Translated
[    0.953471] iommu: DMA domain TLB invalidation policy: lazy mode
[    0.957057] SCSI subsystem initialized
[    0.958897] libata version 3.00 loaded.
[    0.958897] pps_core: LinuxPPS API ver. 1 registered
[    0.960472] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    0.964489] PTP clock support registered
[    0.967468] PCI: Using ACPI for IRQ routing
[    1.142464] PCI: pci_cache_line_size set to 64 bytes
[    1.142464] e820: reserve RAM buffer [mem 0x0009fc00-0x0009ffff]
[    1.142464] e820: reserve RAM buffer [mem 0x3ffdd000-0x3fffffff]
[    1.142534] hpet: 3 channels of 0 reserved for per-cpu timers
[    1.144574] clocksource: Switched to clocksource tsc-early
[    1.149058] VFS: Disk quotas dquot_6.6.0
[    1.153531] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    1.158678] pnp: PnP ACPI init
[    1.161133] ACPI: IRQ 4 override to edge(!), high(!)
[    1.164374] system 00:04: [mem 0xb0000000-0xbfffffff window] has been reserved
[    1.169544] pnp: PnP ACPI: found 5 devices
[    1.181927] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns
[    1.187979] NET: Registered PF_INET protocol family
[    1.192092] IP idents hash table entries: 16384 (order: 5, 131072 bytes, linear)
[    1.222812] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes, linear)
[    1.229329] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[    1.234075] TCP established hash table entries: 8192 (order: 4, 65536 bytes, linear)
[    1.239091] TCP bind hash table entries: 8192 (order: 6, 262144 bytes, linear)
[    1.243601] TCP: Hash tables configured (established 8192 bind 8192)
[    1.247616] MPTCP token hash table entries: 1024 (order: 3, 24576 bytes, linear)
[    1.252243] UDP hash table entries: 512 (order: 3, 32768 bytes, linear)
[    1.256206] UDP-Lite hash table entries: 512 (order: 3, 32768 bytes, linear)
[    1.260196] NET: Registered PF_UNIX/PF_LOCAL protocol family
[    1.263806] NET: Registered PF_XDP protocol family
[    1.264727] pci_bus 0000:00: resource 4 [io  0x0000-0x0cf7 window]
[    1.269967] pci_bus 0000:00: resource 5 [io  0x0d00-0xffff window]
[    1.273673] pci_bus 0000:00: resource 6 [mem 0x000a0000-0x000bffff window]
[    1.277854] pci_bus 0000:00: resource 7 [mem 0x40000000-0xafffffff window]
[    1.281872] pci_bus 0000:00: resource 8 [mem 0xc0000000-0xfebfffff window]
[    1.286100] pci_bus 0000:00: resource 9 [mem 0x100000000-0x8ffffffff window]
[    1.290918] PCI: CLS 0 bytes, default 64
[    1.293781] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x2879c523a63, max_idle_ns: 440795252908 ns
[    1.299859] clocksource: Switched to clocksource tsc
[    1.300213] Unpacking initramfs...
[    1.303918] Initialise system trusted keyrings
[    1.311983] workingset: timestamp_bits=40 max_order=18 bucket_order=0
[    1.316247] Key type asymmetric registered
[    1.318898] Asymmetric key parser 'x509' registered
[    1.322163] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 247)
[    1.329885] io scheduler mq-deadline registered
[    1.332673] io scheduler kyber registered
[    1.335137] io scheduler bfq registered
[    1.373439] ERST DBG: ERST support is disabled.
[    1.377410] ACPI: \_SB_.GSIF: Enabled at IRQ 21
[    1.384699] ACPI: \_SB_.GSIG: Enabled at IRQ 22
[    1.393429] ACPI: \_SB_.GSIH: Enabled at IRQ 23
[    1.399838] ACPI: \_SB_.GSIE: Enabled at IRQ 20
[    1.410108] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[    1.414812] 00:02: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[    1.442407] Freeing initrd memory: 6032K
[    1.478737] VMware PVSCSI driver - version 1.0.7.0-k
[    1.482495] ACPI: \_SB_.GSIA: Enabled at IRQ 16
[    1.489349] ahci 0000:00:1f.2: AHCI vers 0001.0000, 32 command slots, 1.5 Gbps, SATA mode
[    1.494777] ahci 0000:00:1f.2: 6/6 ports implemented (port mask 0x3f)
[    1.499089] ahci 0000:00:1f.2: flags: 64bit ncq only
[    1.511065] scsi host0: ahci
[    1.513457] scsi host1: ahci
[    1.516559] scsi host2: ahci
[    1.519541] scsi host3: ahci
[    1.522621] scsi host4: ahci
[    1.525361] scsi host5: ahci
[    1.527831] ata1: SATA max UDMA/133 abar m4096@0xfebc4000 port 0xfebc4100 irq 26 lpm-pol 1
[    1.532887] ata2: SATA max UDMA/133 abar m4096@0xfebc4000 port 0xfebc4180 irq 26 lpm-pol 1
[    1.538016] ata3: SATA max UDMA/133 abar m4096@0xfebc4000 port 0xfebc4200 irq 26 lpm-pol 1
[    1.543301] ata4: SATA max UDMA/133 abar m4096@0xfebc4000 port 0xfebc4280 irq 26 lpm-pol 1
[    1.548747] ata5: SATA max UDMA/133 abar m4096@0xfebc4000 port 0xfebc4300 irq 26 lpm-pol 1
[    1.554105] ata6: SATA max UDMA/133 abar m4096@0xfebc4000 port 0xfebc4380 irq 26 lpm-pol 1
[    1.559497] hv_vmbus: registering driver hv_netvsc
[    1.563031] i8042: PNP: PS/2 Controller [PNP0303:KBD,PNP0f13:MOU] at 0x60,0x64 irq 1,12
[    1.571166] serio: i8042 KBD port at 0x60,0x64 irq 1
[    1.574602] serio: i8042 AUX port at 0x60,0x64 irq 12
[    1.578190] hv_vmbus: registering driver hyperv_keyboard
[    1.581595] rtc_cmos 00:03: RTC can wake from S4
[    1.587700] rtc_cmos 00:03: registered as rtc0
[    1.590288] input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input0
[    1.591643] rtc_cmos 00:03: setting system clock to 2026-08-24T19:08:56 UTC (1787598536)
[    1.602734] rtc_cmos 00:03: alarms up to one day, y3k, 242 bytes nvram, hpet irqs
[    1.607581] intel_pstate: CPU model not supported
[    1.611223] gre: GRE over IPv4 demultiplexer driver
[    1.614919] NET: Registered PF_INET6 protocol family
[    1.632097] Segment Routing with IPv6
[    1.634544] In-situ OAM (IOAM) with IPv6
[    1.637050] Key type dns_resolver registered
[    1.640221] IPI shorthand broadcast: enabled
[    1.650904] sched_clock: Marking stable (1208204689, 441692795)->(2043960287, -394062803)
[    1.674658] registered taskstats version 1
[    1.677143] Loading compiled-in X.509 certificates
[    1.692822] Loaded X.509 cert 'alpinelinux.org: Alpine Linux kernel key: d76a695f66ad9cd28f5c22a8508f36e91f521f7a'
[    1.702379] Demotion targets for Node 0: null
[    1.706931] Key type .fscrypt registered
[    1.709717] Key type fscrypt-provisioning registered
[    1.869983] ata1: SATA link down (SStatus 0 SControl 300)
[    1.879955] ata3: SATA link down (SStatus 0 SControl 300)
[    1.883128] ata2: SATA link down (SStatus 0 SControl 300)
[    1.886704] ata4: SATA link down (SStatus 0 SControl 300)
[    1.896937] ata6: SATA link down (SStatus 0 SControl 300)
[    1.899932] ata5: SATA link down (SStatus 0 SControl 300)
[    1.903491] Freeing unused kernel image (initmem) memory: 2996K
[    1.906062] Write protecting the kernel read-only data: 26624k
[    1.910020] Freeing unused kernel image (text/rodata gap) memory: 1764K
[    1.913299] Freeing unused kernel image (rodata/data gap) memory: 500K
[    1.916330] rodata_test: all tests were successful
[    1.918279] Run /init as init process
[    1.919800]   with arguments:
[    1.919803]     /init
[    1.919805]   with environment:
[    1.919806]     HOME=/
[    1.919807]     TERM=linux
[    1.928947] Invalid ELF header magic: != ELF
[    1.951331] virtio_blk virtio0: 2/0/0 default/read/poll queues
[    1.959959] virtio_blk virtio0: [vda] 587776 512-byte logical blocks (301 MB/287 MiB)
[    1.967403] Invalid ELF header magic: != ELF
[    2.007166] Invalid ELF header magic: != ELF
[    2.015192] Invalid ELF header magic: != ELF
[    2.019680] Invalid ELF header magic: != ELF
[    2.283926] EXT4-fs (vda): mounted filesystem 29d2014a-decd-4d64-85bf-6eab9f00803c r/w without journal. Quota mode: none.
[    2.826465] random: crng init done
[    2.893589] NET: Registered PF_PACKET protocol family
[    3.018632] fuse: init (API version 7.45)
 $ uname -a
 Linux (none) 6.18.22-0-virt #1-Alpine SMP PREEMPT_DYNAMIC 2026-04-11 15:53:25 x86_64 Linu

Don't know if there is a good way to tell if it is actually very accelerated but I am getting on cpuid leaf 0x40000000
Hypervisor vendor: VMwareVMware

Where if there is no accel paramter specified or when using TCG I get TCGTCGTCGTCG

They both seem to take the same cpu usage.

Additional things I experimented with:

-machine q35,hpet=off reduces the cpu usage by about 2% on my machine (13.5-14.5% down to 11.5-12.5%).

I did modify controller.js to use cpu=max / cpu=host and they timed out and had double cpu usage. Gave up on that. Other things I tried were kernel-irqchip=on, and stuff like config.append + " idle=halt nohz=on clocksource=tsc" and other things did not seem to reduce usage or at least significantly.

qemu_failure.log.txt

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.

Add Windows host support

3 participants