Twee instellingen die je ooit koos en vergat

Proxmox VE 9 doet twee nuttige dingen voor je zonder dat je erom vraagt. Het geeft een gast met het Fisher-Price OS (Windows) de paravirtuele functies die hij nodig heeft om fatsoenlijk op KVM te draaien, en het laadt bij het opstarten actuele CPU-microcode.

Beide gaan automatisch. Beide hangen ook af van een beslissing die je één keer nam, misschien jaren geleden, en waar je sindsdien niet meer naar hebt gekeken.

De eerste hangt af van het OS Type dat je koos toen de VM werd aangemaakt. Kies een van de Microsoft Windows-items en Proxmox voegt bij elke start de Hyper-V-enlightenments toe. Laat het op Other staan, wat makkelijk gebeurt als je een schijf importeert of iets ouds kloont, en de gast krijgt er niet één. Hij start, hij draait, hij is trager, en niets vertelt het je.

De tweede hangt af van hoe de host bij versie 9 is gekomen. De installer van 9.0 zet de firmware-component van Debian aan en installeert het microcodepakket voor jouw CPU. Een host die vanaf 8.x is geüpgraded, houdt de repository’s die hij had, en bij de meeste daarvan betekent dat helemaal geen microcodepakket. Op een AMD Zen 5-host met kernel 6.17.9 of nieuwer is dat geen theoretisch gat: gasten met de EPYC-CPU-typen starten niet meer.

Twee standaarden, twee vergeten keuzesEen VM: bepaald door het OS-typeOS-type, één keer gekozenMicrosoft WindowsOther of Linuxhv_-flags toegevoegdbij elke starthelemaal geenen geen waarschuwingEen host: bepaald door de weg naar 9Proxmox VE 9-host9.x-installergeüpgraded vanaf 8.xmicrocodepakketgeïnstalleerdgeen pakketpve8to9 waarschuwt alleen
Beide standaarden hangen aan een keuze die gemaakt is lang voordat er iets misgaat. Het rechterpad is in beide gevallen het pad waar niets je voor waarschuwt.

De rest van dit stuk neemt ze een voor een door: wat het is, de precieze regel die Proxmox toepast, hoe je het aanzet waar het ontbreekt, en hoe je bewijst dat het is aangeslagen. De regels komen uit de code van qemu-server en pve-manager op een live 9.2-host, niet uit het geheugen, want twee ervan zijn niet wat de meeste mensen zouden raden.

Wat een enlightenment eigenlijk is

Een gastbesturingssysteem dat voor echte hardware is geschreven, steekt veel moeite in dingen die binnen een VM verspilling zijn. Het programmeert timers via geëmuleerde chips, draait rondjes op locks die vastgehouden worden door een vCPU die niet eens is ingepland, en laat watchdogs afgaan als de host een paar milliseconden steelt.

Paravirtualisatie lost dat op door de gast te laten weten dat hij een gast is en hem rechtstreeks met de hypervisor te laten praten. Linux doet dat met de eigen interfaces van KVM. Het Fisher-Price OS (Windows) spreekt maar één paravirtueel dialect, dat van Hyper-V, dus KVM implementeert dat dialect en vertelt de gast dat hij op een Hyper-V-compatibele hypervisor draait. Elk onderdeel daarvan heet een enlightenment.

Niets daarvan staat aan tenzij iets erom vraagt. De documentatie van QEMU is er duidelijk over: “No Hyper-V enlightenments are enabled by default by either KVM or QEMU”1. Op Proxmox is qemu-server degene die erom vraagt, en die vraagt alleen als het OS-type een van de Microsoft Windows-items is.

Je kunt het verschil op elke host zien. Dit is een Linux-VM op mijn 9.2-node, ostype: l26, CPU-type host:

# qm showcmd 101 --pretty | grep -- -cpu
  -cpu host,+kvm_pv_eoi,+kvm_pv_unhalt \

Twee KVM-flags voor de eigen paravirtuele interrupt- en spinlockafhandeling van Linux, en helemaal geen hv_-flags. Goed voor Linux. Fout voor een gast die alleen Hyper-V verstaat.

Wat elke enlightenment doet, volgens de beschrijvingen van QEMU1:

FlagWat de gast krijgtWat het bespaart
hv_timeHyper-V-referentieklok en TSC-paginatijdstempels lezen zonder exit
hv_relaxedde opdracht watchdog-time-outs uit te zettenvalse time-outs als een vCPU uit de planning is gehaald
hv_vapicVP-assistpagina voor de APICend-of-interrupt zonder exit
hv_spinlocksparavirtuele spinlocks, aantal pogingen voordat de host het hoortrondjes draaien op een lock waarvan de houder niet draait
hv_vpindexeen eigen index per virtuele processorvoorwaarde voor de volgende vier
hv_runtimehoe lang elke vCPU echt gedraaid heefteen eerlijk beeld van gestolen tijd
hv_synic, hv_stimersynthetische interruptcontroller en timersgeëmuleerde timerhardware
hv_ipiIPI’s naar veel vCPU’s in één hypercalléén APIC-exit per doel-CPU
hv_resetreset via de hypervisor
hv_evmcsenlightened VMCS, alleen Intelsnellere geneste virtualisatie
hv_tlbflushparavirtuele TLB-shootdownwachten op vCPU’s die niet draaien

Het OS-type is de schakelaar

De regel zit in één functie, get_hyperv_enlightenments in CPUConfig.pm van qemu-server2. Eerst wordt het OS-type omgezet in een versienummer: win11 wordt 11, win10 wordt 10, w2k8 en wvista worden allebei 6, en de typen voor XP en 2003 worden 5. Linux, Other en al het andere worden 0.

Daarna lopen de poorten op volgorde.

Welke hv_-flags qemu-server toevoegt, poort voor poortVan OS-type naar hv_-flags, in de volgorde van de codeVersie van het OS-type onder 6?jastop: niets toegevoegdOVMF-firmware en versie onder 8?jastop: niets toegevoegdmachine 2.3, dan 2.6 of latervoegt toespinlocks vapic time reset vpindex runtimeversie 7 of hogervoegt toerelaxed synic stimer ipiIntel-host, versie 11, machine 11.0+pve2voegt toeevmcs
De volgorde waarin qemu-server ze toepast. Een versie onder 6 stopt bij de eerste poort, en een UEFI-gast ouder dan het 8.x-type stopt bij de tweede, zonder dat er iets wordt toegevoegd.

Een regel lezen is één ding. Hem draaien is beter. Dus laadde ik de geïnstalleerde CPUConfig.pm op twee 9.2-hosts, mijn AMD Ryzen-node voor de AMD-rijen en een Intel Celeron N5100-node voor de Intel-rijen, en riep die functie aan met elke combinatie:

OS-typeFirmwareMachineversieHostToegevoegde enlightenments
l26 of otherelkeelkeelkegeen
wxp (5)SeaBIOS11.0elkegeen
w2k8 (Vista/2008)SeaBIOS11.0elkespinlocks, vapic, time, reset, vpindex, runtime
win7SeaBIOS11.0elkede zes hierboven plus relaxed, synic, stimer, ipi
win7OVMF11.0elkegeen
win10OVMF11.0+pve2Intelalle tien, geen evmcs
win11OVMF11.0+pve1Intelalle tien, geen evmcs
win11OVMF11.0+pve2Intelalle tien plus evmcs
win11SeaBIOS11.0+pve2AMDalle tien, geen evmcs

Drie dingen daarin zijn het weten waard voordat je de GUI in duikt.

Een UEFI-gast met een OS-type ouder dan 8.x krijgt niets. De code keert vroeg terug als de firmware OVMF is en de versie onder 8 ligt. Een 7/2008r2-gast die je naar UEFI hebt verhuisd, is stilletjes elke enlightenment kwijt die hij had.

hv_evmcs wil drie dingen tegelijk. Een Intel-host, het OS-type 11/2022/2025 en machineversie 11.0+pve2 of later. Een 10/2016/2019-gast krijgt hem standaard nooit, hoe nieuw zijn machineversie ook is.

De leverancier van de host wordt gelezen als de VM start. De controle roept read_cpuinfo aan op de node die de VM start, niet op de plek waar de VM is aangemaakt. In een gemengd Intel- en AMD-cluster krijgt dezelfde VM hv_evmcs op de ene node en niet op de andere, bij elke koude start opnieuw bepaald.

De oudere poorten op machineversie (2.3, 2.6, 2.12, 3.1) doen er alleen toe voor VM’s die vastgepind zijn op machines uit het verre verleden van QEMU. Alles wat je vandaag aanmaakt, komt er zonder meer doorheen.

Kies dus het OS-type dat het dichtst bij de gast ligt, niet het nieuwste in de lijst. Een 10/2016/2019-gast hoort op 10/2016/2019. De documentatie van Proxmox geeft nog een reden waarom het type ertoe doet, los van deze flags: het bepaalt ook dingen als of de virtuele RTC op lokale tijd loopt3.

Waarom je oudere VM’s de fix van juli missen

hv_evmcs als standaard is nieuw. Het kwam in qemu-server 9.2.0 op 15 juli 2026, om “mitigate guest freezes and 100% CPU usage seen on certain Intel CPUs with Windows guests that use Virtualization-Based Security (VBS)”4, en het is gekoppeld aan machineversie 11.0+pve2.

Die koppeling is het addertje, want Proxmox pint de machineversie van elke VM met een Microsoft Windows-OS-type vast op het moment dat hij wordt aangemaakt. De documentatie geeft de reden: “Windows is sensitive to changes in the virtual hardware - even between cold boots”3. Het is een verstandige beslissing. Het betekent ook dat een VM die in juni 2026 is aangemaakt op 11.0+pve1 of ouder zit, en daar blijft tot iemand hem verplaatst.

Gaat iemand hem voor je verplaatsen? Nee. De nieuwe standaard geldt voor nieuwe VM’s en voor VM’s die je bewust ophoogt, en verder voor niks.

Heb je Intel-hosts met 11/2022/2025-gasten waarop VBS aanstaat, en is er een daarvan op 100% CPU vastgelopen, dan is dit het eerste wat je controleert:

qm config <vmid> | grep -E '^(ostype|machine):'

Een ostype: win11 met een machine:-regel onder pc-q35-11.0+pve2 moet omhoog om de fix te krijgen. Ophogen verandert de virtuele hardware die de gast ziet, en dat is precies waar het vastpinnen tegen beschermt. Doe het dus in een onderhoudsvenster, met eerst een back-up of snapshot, via Hardware → Machine → Edit, vink Advanced aan en kies de versie.

Begint de regel met pc-i440fx-, dan is de versie het kleinere probleem: die gast hoort helemaal niet op i440fx, om de redenen in Gebruik altijd Q35, niet i440fx, en Instellen, en bewijzen dat het is aangeslagen hieronder behandelt dat.

Twee verwante standaarden kwamen in dezelfde paar maanden binnen en zijn het weten waard nu je er toch mee bezig bent. qemu-server 9.1.12 zette de flags cet-ibt en cet-ss uit voor het type 11/2022/2025, omdat gasten met VBS niet meer opstartten met QEMU 11.0 en de 7.x-kernels die ze doorgaven4. En 9.1.14 maakte de CPU-eigenschap level beschikbaar, die de documentatie omschrijft als “a known workaround for Hyper-V boot failures of Windows guests on recent Intel hosts when the CPU type is host or max”3.

De kant van QEMU, release voor release

qemu-server bouwt de commandoregel. pve-qemu-kvm is de QEMU die hem uitvoert, en de fix van juli heeft ze allebei nodig.

Machineversie 11.0+pve2 is alleen te kiezen als er een QEMU 11.0-binary is geïnstalleerd, want qemu-server weigert elke machineversie die nieuwer is dan de QEMU die hij op de host vindt5. De +pve2 is de eigen revisieteller van qemu-server, niet die van QEMU, dus elke 11.0-build voldoet. Op de dag dat 9.2.0 uitkwam, zag het paar er zo uit:

PakketVersieUitgebrachtWat het brengt
qemu-server9.2.015 juli 2026de standaard hv-evmcs en machine 11.0+pve2
pve-qemu-kvm11.0.2-11 juli 2026QEMU 11.0.2, die dag de actuele
pve-qemu-kvm, minimum11.0.0-15 mei 2026de eerste QEMU 11.0-build

Zorgt apt ervoor dat je ze allebei hebt? Nee. qemu-server 9.2.0 declareert niets strengers dan pve-qemu-kvm (>= 7.1~)6, dus een node waarop QEMU op 10.x is vastgehouden neemt de nieuwe qemu-server zonder morren aan, en kan daarna de machineversie waar de fix aan hangt niet aanbieden. Controleer ze allebei, op elke node. Dit is mijn 9.2-host vandaag, al ruim voorbij allebei:

# pveversion -v | grep -E '^(qemu-server|pve-qemu-kvm):'
pve-qemu-kvm: 11.0.3-4
qemu-server: 9.2.11

Elke QEMU-release sinds Proxmox VE 9.0 op 10.0.2 uitkwam7 heeft eigen fixes meegebracht voor gasten met het Fisher-Price OS (Windows). Dit zijn de fixes die de gast raken, uit de pakketchangelog van Proxmox8 en de upstream changelogs van QEMU9:

QEMUProxmox-buildWat het voor de gast repareerde
10.010.0.2-1, 17 juni 2025de bug “PCI Label Id”, onschuldig in het Engels maar in staat gelokaliseerde installaties te laten vastlopen
10.110.1.2-3, 17 november 2025een regressie in het VNC-klembord die de muisaanwijzer brak
10.110.1.2-5, 22 december 2025back-ups van een VM met een TPM-schijf die bleven hangen, een io_uring-fix
11.011.0.0-1, 5 mei 2026een regressie in de FUSE-export die swtpm gebruikt voor de TPM-status
11.011.0.2-1, 1 juli 2026Hyper-V-enlightenments herkend als CPUID-flags, zodat een eigen CPU-model ze kan dragen

QEMU 11.0 maakte ook iets stuk: het begon cet-ibt en cet-ss door te geven, en dat is wat VBS-gasten niet meer liet opstarten en qemu-server 9.1.12 ertoe bracht ze uit te zetten, zoals hierboven behandeld.

Met de fixes voor de guest agent in dezelfde releases zit het anders. QEMU 10.1, 10.2 en 11.0 repareerden elk delen van de VSS- en filesystem-freeze-afhandeling van de guest agent, waaronder de “Access denied Event ID 8194” die 11.0 verhielp9. Niets daarvan komt mee met pve-qemu-kvm. De agent voor die gast wordt geleverd op de ISO met virtio-win-drivers10, dus hij verandert alleen als je de agent in de VM bijwerkt.

De twee flags die je zelf kunt zetten

Proxmox laat je geen willekeurige CPU-flags aan een VM toevoegen. Hardware → Processors → Edit, vink Advanced aan, en Extra CPU Flags biedt een vaste lijst, gedefinieerd in CPUFlags.pm11. Twee items op die lijst zijn enlightenments, en het zijn de twee die Proxmox standaard niet zet, of tot juli niet zette.

FlagEigen omschrijving van ProxmoxWanneer zetten
hv-tlbflush“Improve performance in overcommitted Windows guests. May lead to guest bluescreens on old CPUs.”Optioneel. Probeer eerst één VM en houd hem in de gaten.
hv-evmcs“Improve performance for nested virtualization. Only supported on Intel CPUs.”Geneste Hyper-V, WSL2 of VBS in de gast, op Intel. Staat al aan voor 11/2022/2025 op 11.0+pve2.

Allebei werden ze opt-in in qemu-server 6.0-6 op 23 juli 2019, in de changelog omschreven als “sometimes problematic”4. hv-tlbflush is dat zeven jaar lang gebleven. Dat zegt wel iets over hoeveel testwerk hij vraagt voordat je hem over een cluster uitrolt.

De eigen notitie van QEMU bij hv-evmcs is dat hij alleen voor Intel is, en dat “some virtualization features (e.g. Posted Interrupts) are disabled when hv-evmcs is enabled”1. Hem met de hand aanzetten op een gast die niets met geneste virtualisatie doet, levert je niets op en kost je dat.

Instellen, en bewijzen dat het is aangeslagen

Voor een nieuwe VM: Create VM → OS, zet Type op Microsoft Windows en Version op wat er het dichtst bij komt.

Voor een bestaande: Options → OS Type → Edit, kies de versie, OK. Proxmox pint de machineversie vast wanneer je een bestaande VM naar een Microsoft Windows-type omzet, net als bij het aanmaken4, dus reken erop dat de machine:-regel in de configuratie ook verandert.

En zet hem op q35. Een gast met enlightenments heeft op pc-i440fx niets te zoeken. Het is de chipset zonder PCIe-bus, en de redenen gaan veel verder dan passthrough; ze staan allemaal in Gebruik altijd Q35, niet i440fx.

De wizard houdt je niet tegen, en voor de meeste Microsoft Windows-types zet hij je er zelfs neer. De eigen documentatie van Proxmox noemt Intel 440FX “the default”3, en de OS-standaarden van de GUI wijken daar voor precies één item van af: 11/2022/2025 krijgt machine: 'q35' en bios: 'ovmf'12. Elk ander Microsoft Windows-type erft de generieke standaarden, en die zetten helemaal geen machine. Een 10/2016/2019-gast die je aanmaakt door steeds op Next te klikken, belandt dus op i440fx: met enlightenments en tegelijk op de verkeerde chipset.

OS-type gekozen in de wizardMachine die hij krijgtFirmware die hij krijgt
11/2022/2025q35OVMF
10/2016/2019 en elk ouder Microsoft Windows-typei440fxSeaBIOS
Other, Linuxi440fxSeaBIOS

Wijzig het op het tabblad System voordat je de wizard afrondt. Voor een VM die al bestaat is van chipset wisselen een grotere verandering aan de virtuele hardware dan een hogere machineversie, dus gelden dezelfde regels voor onderhoudsvenster en back-up, en de q35-post behandelt wat de gast daarmee doet.

Zet hem daarna echt uit. De enlightenments zijn argumenten op de commandoregel van QEMU, en die regel wordt alleen opgebouwd als het QEMU-proces start. Een herstart vanuit de gast houdt hetzelfde proces, dus ook de oude flags. Sluit af, wacht op stopped, en dan Start.

Bewijs het vanaf de host, want daar zit het antwoord:

qm showcmd <vmid> --pretty | grep -o "hv_[a-z_]*[=0-9a-fx]*" | sort -u

Dat print wat qemu-server bij de volgende start aan QEMU geeft. Een 11/2022/2025-gast op 11.0+pve2 op Intel hoort er elf te tonen: hv_evmcs, hv_ipi, hv_relaxed, hv_reset, hv_runtime, hv_spinlocks=0x1fff, hv_stimer, hv_synic, hv_time, hv_vapic en hv_vpindex. Dezelfde gast op AMD toont er tien. Een lege uitvoer betekent dat het OS-type geen Microsoft Windows-type is, of dat het een type van vóór 8.x op UEFI is.

Start een gast na de wijziging niet meer op, zet het OS-type dan voor één start terug op Other om de enlightenments als oorzaak aan te wijzen of uit te sluiten. Hij draait zonder. Alleen slechter.

Microcode: wat het oplost en waar het vandaan komt

De tweede standaard zit onder de hypervisor, niet erboven.

CPU-microcode is de firmware van de leverancier voor de processor zelf. Updates verhelpen beveiligingslekken en ernstige CPU-bugs, en de beheerdershandleiding van Proxmox maakt het punt dat telt voor wie zich zorgen maakt over snelheidsverlies: “a patched microcode is usually still more performant than an unpatched microcode where the kernel itself has to do mitigations”13.

Er zijn drie plekken waar het vandaan kan komen, en ze staan los van elkaar.

BronToegepastGeleverd doorOp mijn 9.2-host nu
BIOS/UEFI-update van het bordbij elke keer aanzetten, blijvendde leverancier van bord of serverwat de laatste BIOS meebracht
Debian non-free-firmwarevroeg in de boot, uit de initramfsDebianintel-microcode 3.20251111.1~deb13u1, amd64-microcode 3.20250311.1
Proxmox VE-repositoryvroeg in de boot, uit de initramfsProxmoxamd64-microcode 3.20251202.1~bpo13+1, geen Intel-pakket

De BIOS-route is degene die Proxmox aanbeveelt13. De route via vroeg laden is het vangnet voor als de bordleverancier is gestopt met BIOS-updates, wat bij alles van een paar jaar oud meestal zo is.

Die derde rij verraste me. Proxmox heeft in zijn eigen repository een nieuwere amd64-microcode dan Debian in trixie heeft14, met dezelfde pinprioriteit, dus apt kiest die van Proxmox. Op een AMD-host met de Proxmox-repository ingesteld is dat de versie die je uiteindelijk draait, en zoals de volgende sectie laat zien, is het de versie die ertoe doet.

Waar microcode tijdens een boot wordt toegepastEén boot, van links naar rechtsAanzettenBIOS-microcodeBootloaderlaadt initramfsKernel startvroege updateHost draaitgasten startenLaat ladengeblokkeerdblijvend,bordleverancieruit de initramfs,Debian of Proxmoxblacklist in/etc/modprobe.d
Vroeg laden gebeurt voordat de kernel iets anders heeft gestart. Laat laden op een draaiend systeem is de route die Debian blokkeert, en die blijft geblokkeerd.

Vroeg laden is wat dit stuk inricht. De microcode gaat de initramfs in en de kernel past hem toe aan het allereerste begin van de boot, voordat er iets anders draait.

Laat laden past hem toe op een draaiend systeem. De eigen documentatie van de kernel heeft een sectie met de titel “Why is late loading dangerous?” en sinds 5.19 staat het niet meer standaard aan15. Debian blokkeert het ook. Dit is het bestand op mijn host, letterlijk:

# cat /etc/modprobe.d/amd64-microcode-blacklist.conf
# The microcode module attempts to apply a microcode update when
# it autoloads.  This is not always safe, so we block it by default.
blacklist microcode

Laat het met rust. De host hierboven heeft het en toont toch een geslaagde vroege update, dus het zit nergens in de weg.

Beide routes vragen een herstart. Daar kom je niet onderuit.

En het is alleen x86. De handleiding van Proxmox zegt ronduit: “There is no equivalent operating-system-level microcode package for arm64”13.

Waarom een geüpgradede host er geen heeft

“Non-free” in non-free-firmware gaat over de licentie, niet over geld of een Proxmox-abonnement. De wiki van Debian legt het uit: de kernelkant is vrije software, maar de updatedata van de leverancier is “opaque”, “and its contents are unknown to Debian”16. Daarom zit het in een eigen component, en daarom krijgt een Debian-systeem het niet tenzij die component aanstaat.

De installer van Proxmox VE 9.0 zet hem aan. Volgens de release notes zal de ISO “Install the microcode package matching the current platform”, en “installations now have the non-free-firmware repository enabled”7. Een upgrade doet geen van beide, omdat die de repositoryregels behoudt die je op 8.x had.

Verse 9.x-installatieGeüpgraded vanaf 8.x
non-free-firmwareaangezet door de installerwat 8.x had, vaak afwezig
Microcodepakketgeïnstalleerd voor de gevonden CPUgeen, tot je de component toevoegt
Wat het je verteltniets nodigpve8to9, als FAIL en als WARN, en alleen als je hem draait
Latere updatesapt full-upgrade en een herstarthetzelfde, zodra het pakket erop staat

De checker meldt het wel, en harder dan ik had verwacht. Dit is hij op mijn Intel-node, die vanaf 8.x is geüpgraded:

# pve8to9 | grep -i -B1 -A2 microcode
PASS: Legacy file '/etc/sysctl.conf' is not present.
INFO: Checking if matching CPU microcode package is installed.
FAIL: unable to determine installed intel-microcode version.
WARN: The matching CPU microcode package 'intel-microcode' could not be found! Consider installing it to receive the latest security and bug fixes for your CPU.
	apt install intel-microcode
SKIP: NOTE: Expensive checks, like CT cgroupv2 compat, not performed without '--full' parameter

De FAIL is een bijwerking: het opzoeken van de versie logt een fout voor elk pakket dat niet geïnstalleerd is, nog voordat de microcodecontrole aan haar eigen waarschuwing toekomt17. Hoe dan ook, pve8to9 is een controle, geen slagboom. Hij voert de upgrade niet uit en kan er ook geen tegenhouden, dus een upgrade vaart er zo langs.

Doet dat er in de praktijk toe? Hier zijn twee gevallen waarin het dat doet, en het eerste is van mij.

Die Intel-node is een Celeron N5100. Zijn sources list had non-free-firmware al, dus het pakket was één commando verwijderd, en tot 27 oktober 2026 had niemand dat commando gedraaid. De kernel merkte het, ook al deed verder niemand dat:

# dmesg | grep -i microcode
[    0.000000] x86/CPU: Running old microcode
[    0.497219] microcode: Current revision: 0x0000001d
# lscpu | grep -i 'old microcode'
Vulnerability Old microcode:             Vulnerable

De kernel houdt “a table of released microcode” bij, en een CPU die op iets ouders opstartte “will say ‘Vulnerable’”18. Hoe oud is oud? De release notes van Intel geven daar voor deze chip antwoord op19:

RevisieIntel-releaseOp deze host
0x1dmicrocode-20210608wat de firmware van het bord vandaag laadt
0x2400001fmicrocode-20220207
0x24000023microcode-20220510uit, zes maanden voordat de BIOS van dit bord werd gebouwd
0x24000024microcode-20230214
0x24000026microcode-20240312in intel-microcode 3.20251111.1~deb13u1 van Debian

De BIOS is versie 5.19, gedateerd 8 november 2022, en laadt nog steeds de allereerste microcode die Intel ooit voor dit onderdeel uitbracht, terwijl er bij het bouwen al twee nieuwere uit waren. Dat is precies het geval waarvoor de route met vroeg laden bestaat: vier updates in een pakket dat de host al kon zien. Ik heb het geïnstalleerd terwijl ik dit schreef, en wat dat deed staat onder Aanzetten, omdat het een addertje laat zien.

Het tweede geval is dat van AMD. Zen 5-processors hebben een bug in de RDSEED-instructie20. De release notes van Proxmox 9.1 leggen vast wat er daarna gebeurt: kernels vanaf 6.17.9, “without active microcode update will disable the RDSEED32 CPU-bit, and will fail to run Qemu guests with a CPU type that exposes that bit (for example EPYC or EPYC-v4)”21. De fix is amd64-microcode 3.20251202.1~bpo13+1 of nieuwer, en dat is de versie van de Proxmox-repository, niet die van Debian.

Daarbinnen zit nog een tweede valkuil. Op Zen 5-borden waarvan de BIOS ouder is dan de fix voor AMD’s Entrysign-kwetsbaarheid, weigert de kernel de nieuwe microcode en logt hij No sha256 digest for patch ID, en het advies van Proxmox is een BIOS-update21. Op die hardware werkt de OS-route dus pas als de bordleverancier zijn deel heeft gedaan.

Aanzetten

Leg eerst vast waar je staat. Op de host, als root:

pveversion
grep -m1 vendor_id /proc/cpuinfo                 # GenuineIntel or AuthenticAMD
grep microcode /proc/cpuinfo | uniq              # revision running now
dpkg -l intel-microcode amd64-microcode 2>/dev/null | grep ^ii
dmesg | grep -i microcode
lscpu > /root/lscpu-before.txt                   # vulnerabilities and mitigations

Toont dpkg het passende pakket al als ii, dan is de host klaar en kun je doorgaan naar het controleren van het resultaat.

Zet de component aan. De apt van trixie geeft de voorkeur aan het deb822-formaat .sources, en de upgradehandleiding van Proxmox wijst naar apt modernize-sources om de oude eenregelige bestanden om te zetten, waarbij de originelen als .bak bewaard blijven22. Voeg daarna non-free-firmware toe aan de Components:-regel van zowel de hoofd- als de security-stanza in /etc/apt/sources.list.d/debian.sources. Dit is het bestand op mijn host, dat van de installer kwam:

Types: deb
URIs: http://deb.debian.org/debian/
Suites: trixie trixie-updates
Components: main contrib non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

Types: deb
URIs: http://security.debian.org/debian-security/
Suites: trixie-security
Components: main contrib non-free-firmware
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

Beide stanza’s, omdat Debian microcode via beide routes naar stable levert. Het security-archief heeft intel-microcode 3.20250812.1~deb13u1, terwijl het hoofdarchief al door is naar 3.20251111.1~deb13u123, en je wilt de nieuwste van de twee.

Installeer degene die bij de CPU past.

apt update
apt install intel-microcode     # Intel
apt install amd64-microcode     # AMD

Alleen die voor jouw leverancier. Vanaf dan komt nieuwe microcode binnen met gewone apt full-upgrade-runs, en elke nieuwe versie vraagt net als de eerste een herstart.

Het installeren bouwt de initramfs opnieuw, want daar moet vroege microcode staan. De kernel leest hem uit een ongecomprimeerd archief vooraan in de initrd, als kernel/x86/microcode/GenuineIntel.bin of AuthenticAMD.bin15, en het installatiescript van het pakket roept de initramfs-trigger aan om hem daar te zetten24. Dit is mijn Intel-node die het pakket kreeg terwijl dit stuk geschreven werd:

# grep -A6 'Setting up intel-microcode' /var/log/apt/term.log
Setting up intel-microcode (3.20251111.1~deb13u1) ...
intel-microcode: microcode will be updated at next boot
Processing triggers for man-db (2.13.1-1) ...
Processing triggers for initramfs-tools (0.148.4) ...
update-initramfs: Generating /boot/initrd.img-7.0.14-24-pve
Running hook script 'zz-proxmox-boot'..
Re-executing '/etc/kernel/postinst.d/zz-proxmox-boot' in new private mount namespace..

zz-proxmox-boot is de hook van Proxmox. Op een host waarvan de EFI-partities door proxmox-boot-tool worden bijgehouden, kopieert hij het nieuwe image daarheen; deze heeft er geen om te synchroniseren.

Kijk nu welk image hij genereerde. Zonder opgegeven kernel bouwt update-initramfs -u alleen de nieuwste opnieuw: “The default is the latest kernel version”25. Dezelfde node, direct daarna:

# uname -r
7.0.14-23-pve
# for f in /boot/initrd.img-*; do echo "$f: $(lsinitramfs $f 2>/dev/null | grep -c GenuineIntel.bin)"; done
/boot/initrd.img-7.0.12-1-pve: 0
/boot/initrd.img-7.0.14-11-pve: 0
/boot/initrd.img-7.0.14-12-pve: 0
/boot/initrd.img-7.0.14-19-pve: 0
/boot/initrd.img-7.0.14-23-pve: 0
/boot/initrd.img-7.0.14-24-pve: 1
/boot/initrd.img-7.0.14-8-pve: 0

Eén image op de zeven bevat de microcode, en het is niet het image dat de host draait.

Volgende bootInitramfs bevat de microcodeRevisie waar de CPU op uitkomt
7.0.14-24, het standaarditemja0x24000026 uit het pakket
7.0.14-23, vastgepind of het terugvalitemnee0x1d uit de BIOS
alles oudernee0x1d uit de BIOS

Bouw dus na het installeren elk image opnieuw, en opnieuw na elke microcode-update, omdat elke update dezelfde herbouw van alleen de nieuwste kernel start. Draai daarna de lus hierboven nog eens om het te bewijzen:

update-initramfs -u -k all

Herstart en controleer. Dit is mijn AMD 9.2-host nadat het pakket uit de Proxmox-repository erop stond:

# grep microcode /proc/cpuinfo | uniq
microcode	: 0xa500012
# dmesg | grep -i microcode
[    0.587928] microcode: Current revision: 0x0a500012
[    0.587930] microcode: Updated early from: 0x0a50000d

Updated early from is de regel die het bewijst. De eigen beheerdershandleiding van Proxmox toont nog de oudere formulering, microcode updated early to revision13; de huidige kernel print de twee regels hierboven26. Beide vormen betekenen dat het gelukt is.

Geen zo’n regel is op zich geen fout. Hij verschijnt alleen als het pakket iets nieuwers bevat dan zowel de ingebouwde revisie van de CPU als de revisie die de BIOS laadde. Een pakket dekt heel veel CPU-modellen, en de handleiding heeft gelijk dat de datum erop je niet vertelt wanneer jouw model voor het laatst iets kreeg13.

Uitrollen over een cluster

De repositorywijziging en de installatie kunnen op alle nodes tegelijk. Er verandert niets tot een herstart. De herstarts gaan één node tegelijk, en elke node is gezond voordat de volgende neergaat.

Een rollende microcodeherstart, één node per rondePer node, dan de volgendeControlerenquorum, Ceph OKOnderhoudgasten vertrekkennooutoptioneelHerstartendmesg nakijkenWachtenOSD's up en inVrijgevenuitzetten, terugvolgende node, zelfde stappen
Eén node per ronde. De twee Ceph-stappen gelden alleen voor hypergeconvergeerde clusters, en het noout-paar is optioneel.
StapCommandoKlaar als
Cluster gezondpvecm status, ceph -squorum, HEALTH_OK
Node leeghalenha-manager crm-command node-maintenance enable <node>, niet-HA-gasten met de hand migrerengeen gasten meer op de node
Optioneel, Cephceph osd set nooutflag zichtbaar in ceph -s
Herstarten, controlerendmesg | grep -i microcodenieuwe revisie zichtbaar
Ceph hersteldceph -salle OSD’s up en in, HEALTH_OK
Vrijgevennode-maintenance disable <node>, ceph osd unset nooutHA-gasten teruggezet

HA-onderhoudsmodus houdt bij waar elke HA-gast vandaan kwam en zet hem terug zodra de node uit onderhoud is27. Niet-HA-gasten zijn jouw werk.

Over noout verschillen de meningen, en beide kanten hebben een punt. Ceph markeert een stille OSD snel als down, maar pas als out na mon_osd_down_out_interval, standaard tien minuten28, en het is out dat de herverdeling start. Een normale herstart is ruim binnen die tijd terug. Een server met een lange POST, een firmwareprompt of een trage RAID-controller misschien niet. Met noout groeit een trage herstart niet uit tot een herverdeling. De prijs is dat je moet onthouden hem weer uit te zetten, en een vergeten noout verbergt later een echte storing.

Doe het hele cluster in één venster. Nodes met verschillende microcoderevisies zijn precies de situatie waarin een gast met CPU-type host, die de functies van de fysieke CPU rechtstreeks ziet, live kan migreren naar een node die een andere set meldt.

Als een microcode-update misgaat

Zeldzaam, maar het gebeurt, en de handleiding van Proxmox behandelt het degelijk13.

SituatieDoe ditWaarom
Je verdenkt de nieuwe microcodestart één keer met dis_ucode_ldrzet de loader alleen voor die boot uit29
Oude revisie goed, nieuwe nietinstalleer de eerdere versie en zet hem op holdeen purge kan een nog oudere BIOS-revisie laten draaien
Een paar weken laterapt-mark unhold, dan full-upgradeeen fix elders kan het verhelpen bij dezelfde microcodeversie

Voor die eenmalige boot: GRUB-menu (houd Shift ingedrukt als het verborgen is), E op het Proxmox-item, voeg dis_ucode_ldr toe aan de regel die met linux begint, en dan Ctrl+X. Een host op systemd-boot in plaats van GRUB staat in het hoofdstuk over bootloaders van de beheerdershandleiding.

Het downgraden, op Intel:

apt list -a intel-microcode               # what versions exist
apt install intel-microcode=<version>     # pick the earlier one
apt-mark hold intel-microcode             # stop the next upgrade undoing it
reboot

Gebruik amd64-microcode op AMD. Downgraden, nooit purgen.

Een standaard is een belofte aan wie het verwachte pad nam

Geen van beide is een bug. Proxmox deed beide keren het verstandige: de functie aanzetten waar het veilig is, uit laten waar het dat misschien niet is, en de virtuele hardware vastpinnen waar de gast kieskeurig over is. De installer is verbeterd, de upgradecontrole meldt het, de changelog zegt wat er veranderde en wanneer. Proxmox heeft zijn deel gedaan.

Maar een standaard is een belofte aan degene die het deed zoals de leverancier verwachtte. Verse installatie, juist OS-type, VM aangemaakt na juli. Iedereen wiens omgeving een geschiedenis heeft, en dat is iedereen die iets echts draait, valt deels buiten die belofte, en het gat kondigt zichzelf niet aan. Het duikt op als een gast die wat traag is, een VBS-bevriezing die niemand aan een machineversie koppelt, of een Zen 5-node waar de EPYC-gasten na een kernelupdate niet meer starten.

Release notes beschrijven wat een nieuwe installatie krijgt. Over wat je hosts werkelijk draaien zeggen ze niks, en dat zijn verschillende vragen. De enige manier om de tweede te beantwoorden is gaan kijken: qm showcmd op de gasten, dmesg op de hosts, de machineregel in de configuratie. Niets daarvan kost meer dan een minuut per machine.

Die minuut is het werk. Proxmox geeft je het gereedschap om te controleren, en als zodanig is het gat tussen wat je aannam en wat er draait aan jou om te dichten, niet aan hen.


  1. QEMU documentation — Hyper-V Enlightenments — “No Hyper-V enlightenments are enabled by default by either KVM or QEMU”; beschrijvingen per flag; hv-evmcs “The feature is Intel-only” en “some virtualization features (e.g. Posted Interrupts) are disabled when hv-evmcs is enabled”. ↩︎ ↩︎ ↩︎

  2. Proxmox qemu-server — CPUConfig.pm — get_hyperv_enlightenments: de OVMF- en versiepoorten, de bewakingen op machineversie, en de GenuineIntel-controle voor hv_evmcs. Hier gedraaid vanuit qemu-server 9.2.11. ↩︎

  3. Proxmox VE admin guide — Qemu/KVM Virtual Machines — “You can choose between the default Intel 440FX or the Q35 chipset” en “switch from the default SeaBIOS to OVMF”; “For Windows guests, the machine version is pinned during creation, because Windows is sensitive to changes in the virtual hardware - even between cold boots”; de eigenschap level en de standaarden voor cet-ibt/cet-ss bij die gasten. ↩︎ ↩︎ ↩︎ ↩︎

  4. Proxmox qemu-server — Debian changelog — 9.2.0 (15 juli 2026) zet hv-evmcs aan voor 11/2022/2025-gasten op Intel vanaf machine 11.0+pve2; 9.1.14 maakt level beschikbaar; 9.1.12 zet cet-ibt en cet-ss uit; vastpinnen bij het omzetten naar een Microsoft Windows-OS-type (januari 2025); 6.0-6 (23 juli 2019) “Make sometimes problematic ‘hv-tlbflush’ and ‘hv-evmcs’ CPU flags optional”. ↩︎ ↩︎ ↩︎ ↩︎

  5. Proxmox qemu-server — Machine.pm — can_run_pve_machine_version geeft false terug als de QEMU-major.minor van de machine nieuwer is dan de geïnstalleerde binary; de +pveN-revisies staan in hetzelfde bestand. ↩︎

  6. Proxmox qemu-server 9.2.0 — debian/control — bij de commit “bump version to 9.2.0” van 15 juli 2026 is de runtime-afhankelijkheid pve-qemu-kvm (>= 7.1~). ↩︎

  7. Proxmox VE Roadmap — 9.0, Installation ISO — “Install the microcode package matching the current platform… This also means that installations now have the non-free-firmware repository enabled.”; dezelfde release noemt “QEMU 10.0.2” ↩︎ ↩︎

  8. Proxmox pve-qemu — Debian changelog — 10.0.2-1 (17 juni 2025) “update QEMU and downstream patches for 10.0.2 release”, die de upstream-fix uit 10.0 hieronder meebrengt; 10.1.2-3 “a regression with VNC clipboard breaking mouse pointer in Windows guests”; 10.1.2-5 de io_uring-fix voor “backup with TPM disk potentially getting stuck”; 11.0.0-1 “regression when using fuse export for swtpm”; 11.0.2-1 “recognize Hyper-V enlightenments in the list of supported CPUID flags”. ↩︎

  9. QEMU upstream changelogs, 10.0 — “Workaround ‘PCI Label Id’ Windows bug, which is normally harmless but on localized versions can lead to guest hangs”; 10.1, 10.2 en 11.0 voor de VSS- en freeze-fixes van de guest agent, waaronder “Fix guest-fs-freeze cause ‘Access denied Event ID 8194’ in Event Viewer”. ↩︎ ↩︎

  10. Proxmox VE wiki — Qemu-guest-agent — voor die gast: “First you have to download the virtio-win driver iso”. ↩︎

  11. Proxmox qemu-server — CPUFlags.pm — de lijst met flags per VM, met de hierboven geciteerde omschrijvingen van hv-tlbflush en hv-evmcs. ↩︎

  12. Proxmox pve-manager — OSDefaults.js — het item win11 zet machine: 'q35' en bios: 'ovmf'; de overige Microsoft Windows-items erven generic, dat geen machine zet. ↩︎

  13. Proxmox VE admin guide — CPU Microcode Updates — vroege updates via het OS, de BIOS/UEFI-route als aanbevolen, geen OS-pakket voor arm64, de procedure met dis_ucode_ldr, en downgraden in plaats van purgen. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  14. Proxmox VE pve-no-subscription repository for trixie — bevat amd64-microcode 3.20251202.1~bpo13+1 en geen intel-microcode, gelezen op 27 oktober 2026. ↩︎

  15. Linux kernel documentation — The Linux Microcode Loader — “Since kernel 5.19, late loading is not enabled by default”, en de sectie “Why is late loading dangerous?”. ↩︎ ↩︎

  16. Debian Wiki — Microcode — de “opaque” updatedata van de CPU-leverancier “is non-free, and its contents are unknown to Debian”. ↩︎

  17. Proxmox pve-manager — pve8to9.pm — check_cpu_microcode_package logt de waarschuwing; de $get_pkg-lookup die het eerst aanroept logt “unable to determine installed $pkg version.” als fout voor elk pakket dat niet geïnstalleerd is. ↩︎

  18. Linux kernel documentation — Old Microcode — “The kernel keeps a table of released microcode. Systems that had microcode older than this at boot will say ‘Vulnerable’.” ↩︎

  19. Intel — Linux Processor Microcode Data Files, release notes — de JSL-rijen voor 06-9c-00/01, “Celeron N4500/N4505/N5100/N5105”, over de releases 20210608 tot en met 20240312; 0x24000026 gelezen uit de header van 06-9c-00 in het pakket van Debian. ↩︎

  20. AMD security bulletin AMD-SB-7055 — het RDSEED-probleem op Zen 5-processors. ↩︎

  21. Proxmox VE Roadmap — 9.1 known issues, AMD Zen5 CPU issue with RDSEED — de mislukte gaststart, de versie van het gerepareerde pakket, en de melding No sha256 digest op borden zonder de Entrysign-fix in de BIOS. ↩︎ ↩︎

  22. Proxmox VE wiki — Upgrade from 8 to 9 — apt modernize-sources zet om naar deb822 en bewaart de oude bestanden met het achtervoegsel .bak. ↩︎

  23. Debian packages — intel-microcode in trixie — de versies in stable en security, gecontroleerd met apt-cache policy op de host. ↩︎

  24. Debian sources — intel-microcode.postinst — dpkg-trigger --no-await update-initramfs, daarna “microcode will be updated at next boot”; amd64-microcode doet hetzelfde. ↩︎

  25. Debian manual — update-initramfs(8) — voor -k: “The default is the latest kernel version”, en “all” werkt “on all installed kernel versions that already have an initramfs (with -d or -u)”. ↩︎

  26. Linux kernel source — arch/x86/kernel/cpu/microcode/core.c — print “Current revision: 0x%08x” en “Updated early from: 0x%08x”. ↩︎

  27. Proxmox VE admin guide — High Availability, maintenance mode — HA-services worden weggezet, en teruggezet “automatically once the maintenance mode is disabled and the node is back online”. ↩︎

  28. Ceph documentation — Configuring Monitor/OSD Interaction — mon_osd_down_out_interval, “The number of seconds Ceph waits before marking a Ceph OSD Daemon down and out”, standaard 10 minuten. ↩︎

  29. Linux kernel documentation — kernel parameters — dis_ucode_ldr: “Disable the microcode loader.” ↩︎