vfio-native

Veel software gedraagt zich anders, of weigert volledig te draaien, zodra het kan detecteren dat het zich in een hypervisor bevindt. Malware-monsters schakelen zichzelf uit of kiezen een onschadelijk pad. Commerciële software kiest een licentie-pad. Drivers en firmware volgen een ander codepad. Al deze zaken maken een virtuele machine onbruikbaar voor het observeren van wat de software daadwerkelijk zou doen op een fysieke machine; je meet dan de sandbox in plaats van het onderwerp.

Er zijn twee onafhankelijke problemen die dit gat veroorzaken, en dit project pakt beide aan.

Ten eerste wijkt KVM op manieren af van de AMD64-architectuur die een gast direct kan uitlezen. Denk aan de verkeerde exception vector voor een SVM-instructie bij CPL>0 (#GP waar de architectuur #UD specificeert) of een hypercall bij CPL>0 die helemaal geen exception veroorzaakt. Dit zijn defecten in de conformiteit aan de specificaties. De drie KVM-patches zorgen ervoor dat KVM exact overeenkomt met de architectuur, wat ze acceptabel maakt voor upstream-integratie.

Ten tweede is het geëmuleerde platform van QEMU intern niet consistent met welke plaat gebouwd is. Denk aan ACPI-link-device namen die geen enkele echte firmware gebruikt, PCI-vendor en subsystem-ID's die bij de emulator horen in plaats van bij een apparaat, firmware-tabelvelden die geen enkele commerciële plaat instelt, en device-identiteitsstrings die de emulator bij naam noemen. Door deze te corrigeren, ziet het geëmuleerde platform eruit als een echt platform.

Daarnaast is er een VFIO-tuninglaag: vCPU-pinning op echte SMT-paren, het afstemmen van de gast op één cache-domein, het houden van de emulator-thread buiten de vCPU-cores en host-CPU-isolatie terwijl de gast draait. Dit is onafhankelijk van het getrouwheidswerk (fidelity work) en wordt apart gemeten.

Resultaten en Prestaties

Gemeten tegen VMAware, die 85 detectietechnieken gebruikt. Een standaard KVM-gast scoort 10/85. Met deze aanpassingen wordt dit 1/85 (zowel in de v2.8.1 release als de huidige HEAD), waarbij de laatste overlevende detectie een echte GPU-passthrough vereist. Het oordeel van VMAware is dan als volgt:

  • VM brand: Unknown
  • VM likeliness: 20%
  • VM confirmation: false
  • CONCLUSIE: Running on bare metal

Deze correcties kosten geen meetbare prestaties. Vergeleken met dezelfde gast waarbij het getrouwheidswerk volledig is weggelaten en elke Hyper-V enlightenment is ingeschakeld, is het verschil kleiner dan de spreiding tussen verschillende runs. Zie docs/RESULTS.md voor details.

Waarschuwing: Gebruik dit alleen op hardware die u beheert en met software waarvoor u een licentie heeft.

---

Installatie en Gebruik

1. Installeren

Er zijn drie pakketten, allemaal gebouwd volgens AUR-regels en getest in een schone extra-x86_64-build chroot. Ze halen deze repo op tag v1.1.0. Vanuit een checkout werken de volgende drie makepkg -si commando's:

git clone https://git.archworks.co/sandwich/vfio-native
cd vfio-native/packaging
(cd vfio-native && makepkg -si)
(cd vfio-native-qemu && makepkg -si)
(cd vfio-native-kvm-dkms && makepkg -si)

Overzicht van de pakketten:

PakketOmschrijving
vfio-nativeDe drie commando's, de patches, de ACPI-tabellen, de benchmark en de libvirt-hook.
vfio-native-qemuQEMU 11.1.2 met platform-identiteitspatches, in /opt/qemu-native.
vfio-native-kvm-dkmsDe gepatchte KVM-modules, herbouwd door DKMS voor elke geïnstalleerde kernel van de vastgepinde release.

De modules komen in updates/dkms/, wat door modprobe wordt verkozen, maar ze worden niet automatisch herladen. Zorg dat elke VM is uitgeschakeld en voer uit:

sudo modprobe -r kvm_amd kvm && sudo modprobe kvm_amd

Dit levert drie commando's op:

  • vm-native-setup: Configureer een libvirt-domein.
  • vm-native-verify: Meet of het daadwerkelijk heeft gewerkt.
  • vm-native-gpu: Stel GPU-passthrough in.

Let op: Alleen de 'full' modus vereist de QEMU- en KVM-pakketten. De 'native' modus vereist enkel aanpassingen aan de domein-XML.

Voor niet-Arch gebruikers: De scripts in scripts/ zijn eenvoudige shell-scripts en werken onafhankelijk. De module-patches kunnen worden gebouwd als arch/x86/kvm vanuit een kernel-tree van de release die u gebruikt; scripts/install-modules.sh is hiervoor het handmatige pad.

2. De gast eenmalig configureren

Een volledige handleiding staat in docs/GUEST-SETUP.md. De korte versie voor een Windows-gast:

Een Windows-gast die zijn eigen hypervisor draait, rapporteert dit eerlijk. Dit kan niet aan de host-zijde worden gewijzigd; de gast draait dan ook echt Hyper-V. Het uitschakelen hiervan maakt de VM sneller, omdat VBS 5-15% CPU-prestaties kost bij CPU-intensieve workloads.

Voer het volgende uit in de gast:

bcdedit /set hypervisorlaunchtype off
Disable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All -NoRestart
reg add "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v EnableVirtualizationBasedSecurity /t REG_DWORD /d 0 /f

Herstart twee keer. Verwijder de QEMU- en SPICE-guest agents. Verplaats de disk naar emulated NVMe (bus='nvme' met een <serial>), aangezien de gepatchte QEMU geen virtio-disk zal booten.

3. De host eenmalig configureren

sudo cpupower frequency-set -g performance

4. Het domein configureren

virsh -c qemu:///system shutdown win11
vm-native-setup

Dit start een interactief proces (met standaarden voor elk antwoord) voor niveau, cores, RAM, identiteit, USB, disk en Secure Boot. Het script leest zelf de CPU-layout uit (AMD CCD's of Intel P/E cores), stemt de gast af op één cache-domein, pint elke vCPU op een echt SMT-paar, houdt de emulator buiten de vCPU-cores, verplaatst disks naar emulated NVMe, vervangt de virtio-device set, configureert Secure Boot met een gegenereerde key store, schrijft de SMBIOS- en ACPI-identiteit, en geeft de gast een CPU-identiteit van de generatie van de host.

  • -r: Geeft de deployment eigen serials en MAC.
  • -u auto: Zet toetsenbord en muis automatisch door (passthrough).
  • -y: Accepteert alle standaarden zonder prompts.

Voorbeeld commando: vm-native-setup -d win11 -p full -c 8 -m 16 -r -u auto -y

Uitleg flags:

  • -d: domein
  • -p: tuned, native of full (standaard full)
  • -c: guest cores (SMT verdubbelt dit naar vCPUs)
  • -m: guest RAM in GiB
  • -s: Secure Boot met enrolled keys, on (standaard) of off
  • -u: USB passthrough (none, auto, of vid:pid,...)
  • -r: randomiseer hardware-identiteit (serials, MAC, geheugenmodule)
  • -S: fit naar een gedumpte SMBIOS van een echte machine (Methode B)
  • -y: geen prompts

Het script maakt eerst een backup van het domein. Het opnieuw uitvoeren is veilig.

5. Controleren of het werkt

vm-native-verify

Dit controleert onder andere QPC-kosten, rdtsc-kosten, L3-latentie en jitter. vm-native-verify meldt ook of CPUID-passthrough is ingeschakeld.

6. CPUID passthrough

CPUID-passthrough moet uitstaan tijdens de cold-boot (omdat Windows anders kan vastlopen) en aanstaan zodra de gast is opgestart.

Automatisch via libvirt hook:

  • sudo vm-native-cpuid enable win11: Uit tijdens cold-boot, aan zodra de gast op het netwerk is, uit bij stop.
  • sudo vm-native-cpuid status: Bekijk actuele status.
  • sudo vm-native-cpuid disable win11: Stop de automatisering voor deze gast.
  • sudo vm-native-cpuid revert: Verwijder de hook en reset de switch.

Handmatig: Voer de twee regels uit die vm-native-setup print voor uw SKU, maar doe dit pas als de gast is opgestart. Zet het uit (echo N) vóór de volgende boot.

---

De Drie Niveaus

Alle niveaus krijgen dezelfde prestatie-tuning. Het verschil zit in de hoeveelheid platform-correcties.

NiveauScoreVereistenOnderhoud
tuned13/85NietsGeen
native7/85NietsGeen
full1/85vfio-native-qemu + vfio-native-kvm-dkms, passthrough na bootDKMS-pakket updaten bij elke kernel-release
  • tuned: Alleen pinning en cache-domein sizing.
  • native: Alleen domein-XML aanpassingen; overleeft host-updates ongeschonden.
  • full: Maximale getrouwheid.

---

Belangrijke Overwegingen

Behoud van host-cores

Laat de host altijd minimaal 4 fysieke cores over. Windows calibreert de TSC bij het opstarten; dit is een race. Als de host de vCPU-threads van de gast niet schoon kan inplannen, geeft Windows de TSC op en stijgen de QueryPerformanceCounter (QPC) kosten van circa 15 ns naar 1300 ns.

Cache-domeinen

Het beperken van de gast tot één cache-domein verlaagt de L3-latentie van circa 17 ns naar 10 ns. Dit is waardevol voor latency-gevoelig werk, maar minder voor throughput.

Realtime Scheduler

Zet niet elke vCPU op een realtime scheduler (<vcpusched scheduler='fifo'>). Dit kan de emulator-thread uithongeren, waardoor het systeem onresponsief wordt tot QEMU handmatig wordt beëindigd.

---

Technische Details van de Patches

KVM

Er zijn vijf patches voor upstream en één experimentele patch. Ze corrigeren KVM tegen de architectuur.

PatchDoel (Clears)
0001-KVM-SVM-intercept-GP...SVM_EXCEPTIONS
0002-KVM-x86-emulator-UD...KVM_INTERCEPTION
0003-KVM-x86-UD-for-KVM...KVM_INTERCEPTION
0004-KVM-SVM-intercept-ICEBP...DBVM
0005-KVM-selftests-verify...Test voor 0004
EXPERIMENTAL-0006...TIMER

QEMU

Tien patchsets tegen v11.1.2, waaronder firmware, disk-identiteit, PCI-ID's, USB-HID, audio, SMBIOS, EDID en CPU-misc.

---

GPU Passthrough

Gebruik vm-native-gpu om GPU's en IOMMU-groepen te beheren.

  • Eén GPU: De host geeft de kaart af tijdens het draaien van de gast en neemt deze terug daarna.

sudo vm-native-gpu --single win11 0000:03:00.0

  • Twee GPU's (één reserve): Bindt de kaart bij boot aan vfio-pci zodat de host deze nooit claimt.

sudo vm-native-gpu --dual 0000:0f:00.0

  • Ongedaan maken: sudo vm-native-gpu --revert

---

Host-bronnen en Onderhoud

Resourcebeheer

Er worden geen host-bronnen gereserveerd wanneer de gast niet draait. Statische hugepages worden bewust vermeden om permanent geheugenverlies te voorkomen. De CPU-isolatie hook beperkt de host tot de cores die de gast niet gebruikt en herstelt dit bij elke exit-path (shutdown, crash, etc.).

Onderhoudstabel

Eventtuned / nativefull
Kernel rebuild (zelfde release)NietsDKMS bouwt modules; reload of reboot
Kernel update (nieuwe release)NietsModules stoppen met bouwen; update _kver in DKMS-pakket
QEMU pakket updateNietsNiets (/opt/qemu-native is een eigen pakket)
Nieuwere QEMU baseNietsPatches uit patches/qemu/ opnieuw toepassen

---

Projectstructuur

  • patches/kvm/: Vijf upstream-stijl kernel patches + één experimentele.
  • patches/qemu/: Tien patchsets tegen QEMU 11.1.2.
  • packaging/: Drie AUR-pakketten (tools, patched QEMU, DKMS modules).
  • scripts/: Setup, verify, GPU, libvirt hook, module install.
  • bench/: Benchmark en TIMER probe.
  • acpi/: SSDT-bronnen voor batterij, platform devices en sensor probes.
  • docs/: Analyse, resultaten en testinstructies.

Credits: Geschreven tegen VMAware door NotRequiem. Licentie: GPL-2.0.