Skip to content

[kernel][whp] E: Skip PIC initialization with xAPIC-only mode#13

Draft
esaurez wants to merge 3 commits into
enhancement-vmm-cpuid-frequency-overridefrom
enhancement-kernel-skip-pic-whp
Draft

[kernel][whp] E: Skip PIC initialization with xAPIC-only mode#13
esaurez wants to merge 3 commits into
enhancement-vmm-cpuid-frequency-overridefrom
enhancement-kernel-skip-pic-whp

Conversation

@esaurez

@esaurez esaurez commented Apr 22, 2026

Copy link
Copy Markdown
Owner

Replica of nanvix#1971.

Summary

Skip legacy 8259 PIC initialization on WHP+microvm when xAPIC is available, reducing VM exits from ~62 to ~15 per cold-start.

Problem

On WHP, every guest I/O port access causes a full VM exit to userspace. PIC initialization writes ICW1-ICW4 commands to ports 0x20/0x21/0xA0/0xA1, totaling ~47 PMIO exits that are handled as no-ops by the VMM.

Implementation

Added XapicOnly(Xapic) variant to InterruptControllerType. Also includes a prerequisite fix: use WHvGetCapability(ProcessorClockFrequency) instead of get_base_frequency_mhz() for the TSC control register.

Measured Improvements (p50)

Metric Baseline PIC Skip Change
Total exits 61-62 14-15 -76%
p50 total 83,959us 78,858us -6%

Depends on #11 (CPUID frequency override).

ppenna and others added 3 commits April 2, 2026 09:48
- Reduce PIT-based calibration window from 10 ms to 1 ms.
- Replace PIT-based calibration with RDTSC spin loop when CPUID
  leaf 0x16 is available, eliminating ~100 VM exits during boot.
- Fall back to PIT-based calibration (1 ms window) when leaf 0x16
  is unavailable instead of guessing TSC frequency.
- Add max-iteration guard to RDTSC spin loop to prevent hangs.
- Fix CPUID helper to check max supported leaf and set ECX=0
  explicitly for well-defined subleaf selection.
Hyper-V zeros out CPUID leaf 0x16 on the host, so get_base_frequency_mhz()
returns 0. Use WHvGetCapability(ProcessorClockFrequency) instead, which
returns the actual TSC frequency in Hz.

Without this fix, the guest falls back to PIT-based calibration (184 extra
VM exits) instead of the fast RDTSC path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When the xAPIC timer has been successfully initialized via
try_init_xapic_timer() on WHP+microvm, skip legacy 8259 PIC
initialization entirely. The WHP LAPIC emulator handles timer
delivery and EOI via MMIO without VM exits.

This eliminates ~47 PIC I/O port exits per cold-start (ports
0x20/0x21/0xA0/0xA1), reducing total exits from ~62 to ~15.
Each exit costs ~470us on WHP (two hypercalls: DispatchVp +
SetVpRegisters), so this saves ~5-22ms depending on system load.

The new XapicOnly interrupt controller variant:
- Uses xAPIC for EOI (MMIO, handled in-kernel by Hyper-V)
- No-ops for unmask (LAPIC timer already unmasked during calibration)
- IKC interrupts are injected via WHvRequestInterrupt through the
  LAPIC, not through PIC routing

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

2 participants