Zwei Einstellungen, einmal gesetzt und vergessen

Proxmox VE 9 tut zwei nützliche Dinge für dich, ohne dass du fragst. Es gibt einem Gast mit Fisher-Price OS (Windows) die paravirtuellen Funktionen, die er braucht, um auf KVM ordentlich zu laufen, und es lädt beim Booten aktuellen CPU-Microcode.

Beides passiert automatisch. Beides hängt aber auch an einer Entscheidung, die du einmal getroffen hast, vielleicht vor Jahren, und seitdem nicht mehr angesehen hast.

Das Erste hängt am OS Type, den du beim Anlegen der VM gewählt hast. Wähl einen der Einträge unter Microsoft Windows, und Proxmox fügt bei jedem Start die Hyper-V-Enlightenments hinzu. Lass ihn auf Other, was leicht passiert, wenn du eine Disk importierst oder etwas Altes klonst, und der Gast bekommt keines davon. Er bootet, er läuft, er ist langsamer, und nichts sagt es dir.

Das Zweite hängt daran, wie der Host zu Version 9 gekommen ist. Der 9.0-Installer schaltet Debians Firmware-Komponente ein und installiert das Microcode-Paket für deine CPU. Ein von 8.x aktualisierter Host behält die Repositories, die er hatte, und auf den meisten heißt das: gar kein Microcode-Paket. Auf einem AMD-Zen-5-Host mit Kernel 6.17.9 oder neuer ist das keine theoretische Lücke: Gäste mit den EPYC-CPU-Typen starten nicht mehr.

Zwei Voreinstellungen, zwei vergessene EntscheidungenEine VM: entschieden durch ihren OS-TypOS-Typ, einmal gesetztMicrosoft WindowsOther oder Linuxhv_-Flags hinzugefügtbei jedem Startgar keineund keine WarnungEin Host: entschieden durch den Weg zu 9Proxmox-VE-9-Host9.x-Installervon 8.x aktualisiertMicrocode-Paketinstalliertkein Paketpve8to9 warnt nur
Beide Voreinstellungen hängen an einer Wahl, die lange vor dem ersten Problem getroffen wurde. Der rechte Pfad ist jeweils der, vor dem dich nichts warnt.

Der Rest dieses Beitrags nimmt sich beide nacheinander vor: was es ist, welche Regel Proxmox genau anwendet, wie du es einschaltest, wo es fehlt, und wie du nachweist, dass es gegriffen hat. Die Regeln stammen aus dem Code von qemu-server und pve-manager auf einem laufenden 9.2-Host, nicht aus dem Gedächtnis, denn zwei davon sind nicht das, was die meisten raten würden.

Was ein Enlightenment eigentlich ist

Ein Gastbetriebssystem, das für echte Hardware geschrieben ist, steckt viel Aufwand in Dinge, die in einer VM Verschwendung sind. Es programmiert Timer über emulierte Chips, dreht sich in Schleifen um Locks, die eine vCPU hält, die gerade nicht einmal eingeplant ist, und löst Watchdogs aus, wenn der Host ein paar Millisekunden abzwackt.

Paravirtualisierung behebt das, indem sie den Gast wissen lässt, dass er ein Gast ist, und ihn direkt mit dem Hypervisor reden lässt. Linux macht das über KVMs eigene Schnittstellen. Das Fisher-Price OS (Windows) spricht nur einen paravirtuellen Dialekt, den von Hyper-V, also implementiert KVM diesen Dialekt und erzählt dem Gast, er laufe auf einem Hyper-V-kompatiblen Hypervisor. Jedes Stück davon heißt Enlightenment.

Nichts davon ist an, solange niemand danach fragt. QEMUs Dokumentation sagt es klar: „No Hyper-V enlightenments are enabled by default by either KVM or QEMU“1. Auf Proxmox ist es qemu-server, das fragt, und es fragt nur, wenn der OS-Typ einer der Einträge unter Microsoft Windows ist.

Den Unterschied siehst du auf jedem Host. Das hier ist eine Linux-VM auf meinem 9.2-Knoten, ostype: l26, CPU-Typ host:

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

Zwei KVM-Flags für Linux’ eigene paravirtuelle Interrupt- und Spinlock-Behandlung, und überhaupt keine hv_-Flags. Richtig für Linux. Falsch für einen Gast, der nur Hyper-V versteht.

Was jedes Enlightenment tut, nach QEMUs Beschreibungen1:

FlagWas der Gast bekommtWas es einspart
hv_timeHyper-V-Referenzuhr und TSC-PageZeitstempel lesen ohne Exit
hv_relaxedAnweisung, Watchdog-Timeouts abzuschaltenfalsche Timeouts, wenn eine vCPU nicht eingeplant ist
hv_vapicVP-Assist-Page für den APICEnd-of-Interrupt ohne Exit
hv_spinlocksparavirtuelle Spinlocks, Wiederholungen, bevor der Host Bescheid bekommtKreiseln um ein Lock, dessen Halter nicht läuft
hv_vpindexseinen eigenen virtuellen ProzessorindexVoraussetzung für die nächsten vier
hv_runtimewie lange jede vCPU tatsächlich liefein ehrlicher Blick auf gestohlene Zeit
hv_synic, hv_stimersynthetischen Interrupt-Controller und Timeremulierte Timer-Hardware
hv_ipiIPIs an viele vCPUs mit einem Hypercallein APIC-Exit pro Ziel-CPU
hv_resetReset über den Hypervisor
hv_evmcsEnlightened VMCS, nur Intelschnellere verschachtelte Virtualisierung
hv_tlbflushparavirtuellen TLB-ShootdownWarten auf vCPUs, die nicht laufen

Der OS-Typ ist der Schalter

Die Regel steckt in einer einzigen Funktion, get_hyperv_enlightenments in qemu-servers CPUConfig.pm2. Der OS-Typ wird zuerst in eine Versionsnummer umgewandelt: win11 wird 11, win10 wird 10, w2k8 und wvista werden beide 6, und die Typen für XP und 2003 werden 5. Linux, Other und alles andere werden 0.

Dann laufen die Prüfungen der Reihe nach.

Welche hv_-Flags qemu-server hinzufügt, Prüfung für PrüfungVom OS-Typ zu hv_-Flags, in der Reihenfolge des CodesOS-Typ-Version unter 6?jaStopp: nichts hinzugefügtOVMF-Firmware und Version unter 8?jaStopp: nichts hinzugefügtMachine 2.3, dann 2.6 oder neuerfügt hinzuspinlocks vapic time reset vpindex runtimeVersion 7 oder höherfügt hinzurelaxed synic stimer ipiIntel-Host, Version 11, Machine 11.0+pve2fügt hinzuevmcs
Die Reihenfolge, in der qemu-server sie anwendet. Eine Version unter 6 bleibt an der ersten Prüfung hängen, ein UEFI-Gast mit einem Typ älter als 8.x an der zweiten, und es kommt überhaupt nichts dazu.

Eine Regel zu lesen ist das eine. Sie auszuführen ist besser. Also habe ich die installierte CPUConfig.pm auf zwei 9.2-Hosts geladen, meinem AMD-Ryzen-Knoten für die AMD-Zeilen und einem Knoten mit Intel Celeron N5100 für die Intel-Zeilen, und die Funktion mit jeder Kombination aufgerufen:

OS-TypFirmwareMachine-VersionHostHinzugefügte Enlightenments
l26 oder otherbeliebigbeliebigbeliebigkeine
wxp (5)SeaBIOS11.0beliebigkeine
w2k8 (Vista/2008)SeaBIOS11.0beliebigspinlocks, vapic, time, reset, vpindex, runtime
win7SeaBIOS11.0beliebigdie sechs oben plus relaxed, synic, stimer, ipi
win7OVMF11.0beliebigkeine
win10OVMF11.0+pve2Intelalle zehn, kein evmcs
win11OVMF11.0+pve1Intelalle zehn, kein evmcs
win11OVMF11.0+pve2Intelalle zehn plus evmcs
win11SeaBIOS11.0+pve2AMDalle zehn, kein evmcs

Drei Dinge darin solltest du wissen, bevor du in die GUI gehst.

Ein UEFI-Gast mit einem OS-Typ älter als 8.x bekommt nichts. Der Code kehrt früh zurück, wenn die Firmware OVMF ist und die Version unter 8 liegt. Ein 7/2008r2-Gast, den du auf UEFI umgestellt hast, hat still und leise jedes Enlightenment verloren, das er hatte.

hv_evmcs will drei Dinge gleichzeitig. Einen Intel-Host, den OS-Typ 11/2022/2025 und Machine-Version 11.0+pve2 oder neuer. Ein 10/2016/2019-Gast bekommt es nie per Voreinstellung, egal wie neu seine Machine-Version ist.

Der Host-Hersteller wird beim Start der VM gelesen. Die Prüfung ruft read_cpuinfo auf dem Knoten auf, der startet, nicht auf dem, auf dem die VM angelegt wurde. In einem gemischten Cluster aus Intel und AMD bekommt dieselbe VM auf einem Knoten hv_evmcs und auf dem anderen nicht, bei jedem Kaltstart neu entschieden.

Die älteren Prüfungen auf die Machine-Version (2.3, 2.6, 2.12, 3.1) betreffen nur VMs, die auf Maschinen aus QEMUs ferner Vergangenheit festgenagelt sind. Alles, was du heute anlegen würdest, kommt da durch.

Also wähl den OS-Typ, der dem Gast am nächsten kommt, nicht den neuesten in der Liste. Ein 10/2016/2019-Gast gehört auf 10/2016/2019. Proxmox’ Dokumentation nennt einen zweiten Grund, warum der Typ über diese Flags hinaus zählt: Er legt auch Dinge fest wie die Frage, ob die virtuelle RTC auf Ortszeit läuft3.

Warum deine älteren VMs den Juli-Fix verpassen

hv_evmcs per Voreinstellung ist neu. Es kam mit qemu-server 9.2.0 am 15. Juli 2026, um „mitigate guest freezes and 100% CPU usage seen on certain Intel CPUs with Windows guests that use Virtualization-Based Security (VBS)“4, und es ist an Machine-Version 11.0+pve2 gebunden.

Genau diese Bindung ist der Haken, denn Proxmox nagelt die Machine-Version jeder VM mit einem OS-Typ unter Microsoft Windows in dem Moment fest, in dem sie angelegt wird. Die Dokumentation nennt den Grund: „Windows is sensitive to changes in the virtual hardware - even between cold boots“3. Das ist eine vernünftige Entscheidung. Sie heißt aber auch, dass eine VM, die im Juni 2026 angelegt wurde, auf 11.0+pve1 oder älter sitzt und dort bleibt, bis jemand sie verschiebt.

Wird das jemand für dich tun? Nein. Die neue Voreinstellung gilt für neue VMs und für VMs, die du bewusst hochstufst, und für nix sonst.

Wenn du Intel-Hosts mit 11/2022/2025-Gästen und eingeschaltetem VBS hast und einer davon schon bei 100 % CPU eingefroren ist, prüfst du als Erstes das hier:

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

Ein ostype: win11 mit einer machine:-Zeile unter pc-q35-11.0+pve2 muss hochgestuft werden, um den Fix zu bekommen. Das Hochstufen ändert die virtuelle Hardware, die der Gast sieht, und genau davor schützt das Pinning. Also mach es in einem Wartungsfenster, mit vorher gezogenem Backup oder Snapshot, über Hardware → Machine → Edit, Haken bei Advanced, und wähl die Version.

Beginnt die Zeile stattdessen mit pc-i440fx-, ist die Version das kleinere Problem: Dieser Gast gehört überhaupt nicht auf i440fx, aus den Gründen in Immer Q35, nicht i440fx, und Einstellen, und nachweisen, dass es gegriffen hat weiter unten behandelt das.

Zwei verwandte Voreinstellungen kamen in denselben paar Monaten dazu, und es lohnt sich, sie zu kennen, wenn du schon mal da drin bist. qemu-server 9.1.12 hat die Flags cet-ibt und cet-ss für den Typ 11/2022/2025 abgeschaltet, weil Gäste mit VBS unter QEMU 11.0 und den 7.x-Kerneln, die sie anbieten, nicht mehr booteten4. Und 9.1.14 hat die CPU-Eigenschaft level freigegeben, die die Dokumentation als „a known workaround for Hyper-V boot failures of Windows guests on recent Intel hosts when the CPU type is host or max“ beschreibt3.

Die QEMU-Seite, Version für Version

qemu-server baut die Kommandozeile. pve-qemu-kvm ist das QEMU, das sie ausführt, und der Juli-Fix braucht beide.

Machine-Version 11.0+pve2 lässt sich nur wählen, wenn ein QEMU-11.0-Binary installiert ist, denn qemu-server lehnt jede Machine-Version ab, die neuer ist als das QEMU, das es auf dem Host findet5. Das +pve2 ist der eigene Revisionszähler von qemu-server, nicht der von QEMU, also genügt jeder 11.0-Build. Am Tag, an dem 9.2.0 erschien, sah das Paar so aus:

PaketVersionErschienenWas es mitbringt
qemu-server9.2.015. Juli 2026die Voreinstellung hv-evmcs und Machine 11.0+pve2
pve-qemu-kvm11.0.2-11. Juli 2026QEMU 11.0.2, an dem Tag aktuell
pve-qemu-kvm, Minimum11.0.0-15. Mai 2026der erste QEMU-11.0-Build

Sorgt apt dafür, dass du beides hast? Nein. qemu-server 9.2.0 verlangt nichts Strengeres als pve-qemu-kvm (>= 7.1~)6, also nimmt ein Node, dessen QEMU auf 10.x zurückgehalten wird, das neue qemu-server ohne Murren an und kann danach die Machine-Version nicht anbieten, an der der Fix hängt. Prüf beide, auf jedem Node. So steht mein 9.2-Host heute da, bei beiden längst weiter:

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

Jede QEMU-Version, seit Proxmox VE 9.0 mit 10.0.2 erschien7, hat eigene Fixes für Gäste mit Fisher-Price OS (Windows) mitgebracht. Das hier sind die, die den Gast betreffen, aus Proxmox’ Paket-Changelog8 und den Upstream-Changelogs von QEMU9:

QEMUProxmox-BuildWas es für den Gast behoben hat
10.010.0.2-1, 17. Juni 2025den „PCI Label Id“-Fehler, auf Englisch harmlos, in lokalisierten Installationen aber imstande, den Gast hängen zu lassen
10.110.1.2-3, 17. November 2025eine Regression in der VNC-Zwischenablage, die den Mauszeiger kaputt machte
10.110.1.2-5, 22. Dezember 2025hängende Backups einer VM mit TPM-Disk, ein io_uring-Fix
11.011.0.0-1, 5. Mai 2026eine Regression im FUSE-Export, den swtpm für den TPM-Zustand nutzt
11.011.0.2-1, 1. Juli 2026Hyper-V-Enlightenments als CPUID-Flags erkannt, damit ein eigenes CPU-Modell sie tragen kann

QEMU 11.0 hat auch etwas kaputt gemacht: Es fing an, cet-ibt und cet-ss anzubieten, und genau das hat VBS-Gäste am Booten gehindert und qemu-server 9.1.12 dazu gebracht, sie abzuschalten, wie oben beschrieben.

Mit den Fixes am Gast-Agenten in denselben Versionen ist es eine andere Sache. QEMU 10.1, 10.2 und 11.0 haben jeweils Teile der VSS- und Filesystem-Freeze-Behandlung des Gast-Agenten repariert, darunter das „Access denied Event ID 8194“, das 11.0 kuriert hat9. Nichts davon kommt mit pve-qemu-kvm. Der Agent für diesen Gast liegt auf der virtio-win-Treiber-ISO10, also ändert er sich nur, wenn du den Agenten in der VM aktualisierst.

Die zwei Flags, die du von Hand setzen kannst

Proxmox lässt dich einer VM keine beliebigen CPU-Flags geben. Hardware → Processors → Edit, Haken bei Advanced, und Extra CPU Flags bietet eine feste Liste an, definiert in CPUFlags.pm11. Zwei Einträge auf dieser Liste sind Enlightenments, und es sind genau die zwei, die Proxmox nicht per Voreinstellung setzt, oder bis Juli nicht gesetzt hat.

FlagProxmox’ eigene BeschreibungWann du es setzt
hv-tlbflush„Improve performance in overcommitted Windows guests. May lead to guest bluescreens on old CPUs.“Optional. Erst eine VM ausprobieren und beobachten.
hv-evmcs„Improve performance for nested virtualization. Only supported on Intel CPUs.“Verschachteltes Hyper-V, WSL2 oder VBS im Gast, auf Intel. Für 11/2022/2025 auf 11.0+pve2 schon an.

Beide wurden in qemu-server 6.0-6 am 23. Juli 2019 zum Opt-in gemacht, im Changelog als „sometimes problematic“ beschrieben4. hv-tlbflush ist seit sieben Jahren so geblieben. Das ist ein ziemlich deutlicher Hinweis darauf, wie viel Testen es braucht, bevor du es über einen Cluster ausrollst.

QEMUs eigene Anmerkung zu hv-evmcs lautet, dass es nur auf Intel geht und dass „some virtualization features (e.g. Posted Interrupts) are disabled when hv-evmcs is enabled“1. Es von Hand auf einem Gast einzuschalten, der keine verschachtelte Virtualisierung macht, bringt dir nichts und kostet dich genau das.

Einstellen, und nachweisen, dass es gegriffen hat

Für eine neue VM: Create VM → OS, Type auf Microsoft Windows und Version auf den nächstliegenden Eintrag.

Für eine bestehende: Options → OS Type → Edit, Version wählen, OK. Proxmox nagelt die Machine-Version fest, wenn du eine bestehende VM auf einen Typ unter Microsoft Windows umstellst, genau wie beim Anlegen4, also rechne damit, dass sich die machine:-Zeile in der Konfiguration auch ändert.

Und stell sie auf q35. Ein Gast mit Enlightenments hat auf pc-i440fx nichts verloren. Das ist der Chipsatz ohne PCIe-Bus, und die Gründe reichen weit über Passthrough hinaus; sie stehen alle in Immer Q35, nicht i440fx.

Der Assistent hält dich nicht auf, und bei den meisten Typen unter Microsoft Windows bringt er dich genau dorthin. Proxmox’ eigene Dokumentation nennt Intel 440FX „the default“3, und die OS-Voreinstellungen der GUI überschreiben das für genau einen Eintrag: 11/2022/2025 bekommt machine: 'q35' und bios: 'ovmf'12. Jeder andere Typ unter Microsoft Windows erbt die generischen Voreinstellungen, die überhaupt keine Machine setzen. Ein 10/2016/2019-Gast, angelegt durch Klicken auf Next, landet also auf i440fx, mit Enlightenments und zugleich auf dem falschen Chipsatz.

Im Assistenten gewählter OS-TypMachine, die er bekommtFirmware, die er bekommt
11/2022/2025q35OVMF
10/2016/2019 und jeder ältere Typ unter Microsoft Windowsi440fxSeaBIOS
Other, Linuxi440fxSeaBIOS

Stell es auf dem Tab System um, bevor du den Assistenten abschließt. Bei einer VM, die es schon gibt, ist ein Wechsel des Chipsatzes eine größere Änderung an der virtuellen Hardware als ein Hochstufen der Machine-Version, also gelten dieselben Regeln für Wartungsfenster und Backup, und der q35-Beitrag behandelt, was der Gast damit macht.

Dann halte sie richtig an. Die Enlightenments sind Argumente auf der QEMU-Kommandozeile, und diese Zeile wird nur gebaut, wenn der QEMU-Prozess startet. Ein Neustart aus dem Gast heraus behält denselben Prozess, also auch die alten Flags. Herunterfahren, auf stopped warten, dann Start.

Weise es vom Host aus nach, denn dort liegt die Antwort:

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

Das gibt aus, was qemu-server beim nächsten Start an QEMU übergibt. Ein 11/2022/2025-Gast auf 11.0+pve2 auf Intel sollte elf auflisten: hv_evmcs, hv_ipi, hv_relaxed, hv_reset, hv_runtime, hv_spinlocks=0x1fff, hv_stimer, hv_synic, hv_time, hv_vapic und hv_vpindex. Derselbe Gast auf AMD listet zehn. Eine leere Ausgabe heißt, dass der OS-Typ keiner unter Microsoft Windows ist oder dass es ein Typ vor 8.x auf UEFI ist.

Wenn ein Gast nach der Änderung nicht bootet, stell den OS-Typ für einen Start zurück auf Other, um die Enlightenments als Ursache ein- oder auszuschließen. Ohne sie läuft er. Nur schlechter.

Microcode: was er behebt und woher er kommt

Die zweite Voreinstellung sitzt unter dem Hypervisor, nicht darüber.

CPU-Microcode ist die Firmware des Herstellers für den Prozessor selbst. Updates beheben Sicherheitslücken und ernste CPU-Fehler, und Proxmox’ Admin-Guide bringt den Punkt, der für jeden zählt, der sich um die Geschwindigkeit sorgt: „a patched microcode is usually still more performant than an unpatched microcode where the kernel itself has to do mitigations“13.

Es gibt drei Quellen, und sie sind voneinander unabhängig.

QuelleAngewendetLiefert ihnAuf meinem 9.2-Host heute
BIOS/UEFI-Update des Boardsbei jedem Einschalten, dauerhaftder Board- oder Serverherstellerwas das letzte BIOS mitgebracht hat
Debian non-free-firmwarefrüh beim Booten, aus dem InitramfsDebianintel-microcode 3.20251111.1~deb13u1, amd64-microcode 3.20250311.1
Proxmox-VE-Repositoryfrüh beim Booten, aus dem InitramfsProxmoxamd64-microcode 3.20251202.1~bpo13+1, kein Intel-Paket

Den BIOS-Weg nennt Proxmox den empfohlenen13. Das frühe Laden ist das Sicherheitsnetz für den Fall, dass der Boardhersteller keine BIOS-Updates mehr liefert, was er bei allem, was ein paar Jahre alt ist, meistens nicht mehr tut.

Die dritte Zeile hat mich überrascht. Proxmox führt in seinem eigenen Repository ein neueres amd64-microcode als Debian in trixie14, mit derselben Pin-Priorität, also nimmt apt das von Proxmox. Auf einem AMD-Host mit eingerichtetem Proxmox-Repository ist das die Version, die am Ende läuft, und wie der nächste Abschnitt zeigt, ist es die Version, auf die es ankommt.

Wo Microcode beim Booten angewendet wirdEin Bootvorgang, von links nach rechtsEinschaltenBIOS-MicrocodeBootloaderlädt InitramfsKernel startetfrühes UpdateHost läuftGäste startenSpätes Ladengesperrtdauerhaft,Boardherstelleraus dem Initramfs,Debian oder ProxmoxBlacklist in/etc/modprobe.d
Frühes Laden passiert, bevor der Kernel irgendetwas anderes gestartet hat. Spätes Laden auf einem laufenden System ist der Weg, den Debian sperrt, und er bleibt gesperrt.

Frühes Laden ist das, was dieser Beitrag einrichtet. Der Microcode kommt ins Initramfs, und der Kernel wendet ihn ganz am Anfang des Bootens an, bevor irgendetwas anderes läuft.

Spätes Laden wendet ihn auf ein laufendes System an. Die Kernel-Dokumentation hat einen eigenen Abschnitt mit dem Titel „Why is late loading dangerous?“, und seit 5.19 ist es nicht mehr per Voreinstellung eingeschaltet15. Debian sperrt es zusätzlich. Das ist die Datei auf meinem Host, wörtlich:

# 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

Lass sie in Ruhe. Der Host oben hat sie und zeigt trotzdem ein erfolgreiches frühes Update, sie steht also nichts im Weg.

Beide Wege brauchen einen Neustart. Daran führt kein Weg vorbei.

Und es gilt nur für x86. Proxmox’ Guide sagt rundheraus: „There is no equivalent operating-system-level microcode package for arm64“13.

Warum ein aktualisierter Host keinen hat

„Non-free“ in non-free-firmware bezieht sich auf die Lizenz, nicht auf Geld und nicht auf ein Proxmox-Abo. Debians Wiki erklärt es: Die Kernel-Seite ist freie Software, aber die Update-Daten des Herstellers sind „opaque“, „and its contents are unknown to Debian“16. Deshalb liegen sie in einer eigenen Komponente, und deshalb bekommt ein Debian-System sie nicht, solange die Komponente nicht eingeschaltet ist.

Der Installer von Proxmox VE 9.0 schaltet sie ein. Die Release Notes sagen, das ISO werde „Install the microcode package matching the current platform“, und dass „installations now have the non-free-firmware repository enabled“7. Ein Upgrade tut weder das eine noch das andere, weil es die Repository-Zeilen behält, die du auf 8.x hattest.

Frische 9.x-InstallationVon 8.x aktualisiert
non-free-firmwarevom Installer eingeschaltetwas 8.x hatte, oft gar nicht
Microcode-Paketfür die erkannte CPU installiertkeins, bis du die Komponente hinzufügst
Was es dir sagtnicht nötigpve8to9, als FAIL und als WARN, und nur, wenn du es laufen lässt
Spätere Updatesapt full-upgrade und ein Neustartdasselbe, sobald das Paket drauf ist

Das Prüfprogramm meldet es durchaus, und lauter, als ich erwartet hatte. So sieht es auf meinem Intel-Knoten aus, der von 8.x hochgekommen ist:

# 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

Das FAIL ist ein Nebeneffekt: Die Versionsabfrage protokolliert einen Fehler für jedes Paket, das nicht installiert ist, bevor die Microcode-Prüfung zu ihrer eigenen Warnung kommt17. So oder so ist pve8to9 ein Prüfprogramm, keine Schranke. Es führt das Upgrade nicht aus und kann keins aufhalten, also rauscht das Upgrade direkt daran vorbei.

Spielt das in der Praxis eine Rolle? Hier sind zwei Fälle, in denen es das tut, und der erste ist meiner.

Dieser Intel-Knoten ist ein Celeron N5100. Seine Paketquellen hatten non-free-firmware schon drin, das Paket war also einen Befehl entfernt, und bis zum 27. Oktober 2026 hatte ihn niemand ausgeführt. Der Kernel hat es bemerkt, auch wenn sonst keiner:

# 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

Der Kernel führt „a table of released microcode“, und eine CPU, die mit etwas Älterem gebootet hat, „will say ‚Vulnerable‘“18. Wie alt ist alt? Intels Release Notes beantworten das für diesen Chip19:

RevisionIntel-ReleaseAuf diesem Host
0x1dmicrocode-20210608was die Board-Firmware heute lädt
0x2400001fmicrocode-20220207
0x24000023microcode-20220510sechs Monate vor dem BIOS dieses Boards erschienen
0x24000024microcode-20230214
0x24000026microcode-20240312in Debians intel-microcode 3.20251111.1~deb13u1

Das BIOS ist Version 5.19 vom 8. November 2022, und es lädt immer noch den ersten Microcode, den Intel je für das Teil herausgebracht hat, obwohl beim Bau schon zwei neuere draußen waren. Genau für diesen Fall gibt es den Weg über das frühe Laden: vier Updates in einem Paket, das der Host schon sehen konnte. Ich habe es installiert, während ich das hier geschrieben habe, und was dabei passiert ist, steht unter Einschalten, weil es einen Haken zeigt.

Der zweite Fall ist AMDs. Zen-5-Prozessoren haben einen Fehler in der RDSEED-Instruktion20. Die Release Notes von Proxmox 9.1 halten fest, was als Nächstes passiert: Kernel ab 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. Die Lösung ist amd64-microcode 3.20251202.1~bpo13+1 oder neuer, und das ist die Version aus dem Proxmox-Repository, nicht die von Debian.

In dieser Falle steckt noch eine zweite. Auf Zen-5-Boards, deren BIOS älter ist als der Fix für AMDs Entrysign-Schwachstelle, lehnt der Kernel den neuen Microcode ab und protokolliert No sha256 digest for patch ID, und Proxmox rät zu einem BIOS-Update21. Auf dieser Hardware funktioniert der Weg über das Betriebssystem also erst, wenn der Boardhersteller seinen Teil erledigt hat.

Einschalten

Halte zuerst fest, wo du stehst. Auf dem 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

Wenn dpkg das passende Paket schon als ii zeigt, ist der Host fertig, und du kannst direkt zur Prüfung des Ergebnisses springen.

Die Komponente einschalten. Das apt von Trixie bevorzugt das deb822-Format .sources, und Proxmox’ Upgrade-Anleitung verweist auf apt modernize-sources, um die alten einzeiligen Dateien umzuwandeln, wobei die Originale als .bak erhalten bleiben22. Dann trägst du non-free-firmware in die Components:-Zeile sowohl des Haupt- als auch des Security-Abschnitts in /etc/apt/sources.list.d/debian.sources ein. Das ist die Datei auf meinem Host, die vom Installer kam:

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 Abschnitte, weil Debian Microcode für Stable über beide Wege ausliefert. Das Security-Archiv führt intel-microcode 3.20250812.1~deb13u1, während das Hauptarchiv schon bei 3.20251111.1~deb13u1 ist23, und du willst den jeweils neuesten.

Das Paket installieren, das zur CPU passt.

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

Nur das für deinen Hersteller. Ab dann kommt neuer Microcode mit ganz normalen apt full-upgrade-Läufen, und jede neue Version braucht einen Neustart wie die erste.

Die Installation baut die Initramfs neu, weil früher Microcode genau dort liegen muss. Der Kernel liest ihn aus einem unkomprimierten Archiv am Anfang der initrd, als kernel/x86/microcode/GenuineIntel.bin oder AuthenticAMD.bin15, und das Installationsskript des Pakets löst den Initramfs-Trigger aus, um ihn dort hineinzulegen24. Das ist mein Intel-Knoten, der das Paket bekommt, während dieser Beitrag entstand:

# 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 ist der Hook von Proxmox. Auf einem Host, dessen EFI-Partitionen von proxmox-boot-tool gepflegt werden, kopiert er das neue Image hinüber; dieser hier hat keine zum Abgleichen.

Jetzt schau, welches Image er erzeugt hat. Ohne angegebenen Kernel baut update-initramfs -u nur das neueste neu: „The default is the latest kernel version“25. Derselbe Knoten, direkt danach:

# 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

Eins von sieben Images enthält den Microcode, und es ist nicht das, mit dem der Host läuft.

Nächster BootInitramfs enthält den MicrocodeRevision, auf der die CPU landet
7.0.14-24, der Standardeintragjadie 0x24000026 aus dem Paket
7.0.14-23, festgepinnt oder der Fallback-Eintragneindie 0x1d aus dem BIOS
alles Ältereneindie 0x1d aus dem BIOS

Bau also nach der Installation jedes Image neu, und nach jedem Microcode-Update wieder, weil jedes denselben Neubau nur des neuesten Kernels auslöst. Dann lass die Schleife oben noch einmal laufen, um es nachzuweisen:

update-initramfs -u -k all

Neu starten und prüfen. Das ist mein AMD-Host mit 9.2, nachdem das Paket aus dem Proxmox-Repository drauf war:

# 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 ist die Zeile, die es beweist. Proxmox’ eigener Admin-Guide zeigt noch den älteren Wortlaut, microcode updated early to revision13; der aktuelle Kernel gibt die zwei Zeilen oben aus26. Beide Formen heißen, dass es funktioniert hat.

Fehlt die Zeile, ist das für sich allein kein Fehler. Sie erscheint nur, wenn das Paket etwas Neueres enthält als sowohl die eingebaute Revision der CPU als auch die, die das BIOS geladen hat. Ein Paket deckt sehr viele CPU-Modelle ab, und der Guide hat recht, dass das Datum darauf nichts darüber sagt, wann dein Modell zuletzt etwas bekommen hat13.

Über einen Cluster ausrollen

Die Repository-Änderung und die Installation können auf allen Knoten gleichzeitig passieren. Bis zu einem Neustart ändert sich nichts. Die Neustarts laufen Knoten für Knoten, und jeder Knoten ist gesund, bevor der nächste heruntergefahren wird.

Ein Rolling Reboot für Microcode, ein Knoten pro DurchgangPro Knoten, dann der nächstePrüfenQuorum, Ceph OKWartungGäste ziehen umnooutoptionalNeustartdmesg prüfenWartenOSDs up und inFreigebenunset, zurücknächster Knoten, gleiche Schritte
Ein Knoten pro Durchgang. Die zwei Ceph-Schritte gelten nur für hyperkonvergente Cluster, und das noout-Paar ist optional.
SchrittBefehlFertig, wenn
Cluster gesundpvecm status, ceph -squorate, HEALTH_OK
Knoten leerenha-manager crm-command node-maintenance enable <node>, Nicht-HA-Gäste von Hand migrierenkeine Gäste mehr drauf
Optional, Cephceph osd set nooutFlag in ceph -s sichtbar
Neustart, prüfendmesg | grep -i microcodeneue Revision sichtbar
Ceph erholtceph -salle OSDs up und in, HEALTH_OK
Freigebennode-maintenance disable <node>, ceph osd unset nooutHA-Gäste zurückverschoben

Der HA-Wartungsmodus merkt sich, woher jeder HA-Gast kam, und verschiebt ihn zurück, sobald der Knoten aus der Wartung ist27. Nicht-HA-Gäste sind deine Aufgabe.

Bei noout gehen die Meinungen auseinander, und beide Seiten haben einen Punkt. Ceph markiert eine stumme OSD schnell als down, aber erst nach mon_osd_down_out_interval als out, was per Voreinstellung zehn Minuten sind28, und erst out löst die Umverteilung aus. Ein normaler Neustart ist weit innerhalb dieser Zeit zurück. Ein Server mit langem POST, einer Firmware-Abfrage oder einem langsamen RAID-Controller vielleicht nicht. noout zu setzen verhindert, dass aus einem langsamen Neustart eine Umverteilung wird. Der Preis ist, dass du daran denken musst, es wieder zurückzunehmen, und ein vergessenes noout verdeckt später einen echten Ausfall.

Mach den ganzen Cluster in einem Fenster. Knoten mit unterschiedlichen Microcode-Revisionen sind genau die Lage, in der ein Gast mit CPU-Typ host, der die Funktionen der physischen CPU direkt sieht, per Live-Migration auf einen Knoten wandern kann, der einen anderen Satz meldet.

Wenn ein Microcode-Update schiefgeht

Selten, aber es kommt vor, und Proxmox’ Guide behandelt es ordentlich13.

LageTu dasWarum
Du verdächtigst den neuen Microcodeeinmal mit dis_ucode_ldr bootenschaltet den Loader nur für diesen einen Boot ab29
Alte Revision gut, neue nichtdie frühere Version installieren und festhaltenein Purge kann eine noch ältere BIOS-Revision laufen lassen
Ein paar Wochen späterapt-mark unhold, dann full-upgradeein Fix an anderer Stelle kann es bei derselben Microcode-Version beheben

Für den einmaligen Boot: GRUB-Menü (Shift gedrückt halten, wenn es versteckt ist), E auf dem Proxmox-Eintrag, dis_ucode_ldr an die Zeile anhängen, die mit linux beginnt, dann Ctrl+X. Ein Host mit systemd-boot statt GRUB wird im Bootloader-Kapitel des Admin-Guides behandelt.

Das Downgrade, auf 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

Auf AMD setzt du amd64-microcode ein. Downgrade, nie Purge.

Eine Voreinstellung ist ein Versprechen an den, der den erwarteten Weg gegangen ist

Keins von beiden ist ein Bug. Proxmox hat beide Male das Vernünftige getan: die Funktion einschalten, wo sie sicher ist, sie auslassen, wo sie es vielleicht nicht ist, und die virtuelle Hardware festnageln, bei der der Gast empfindlich ist. Der Installer wurde korrigiert, das Upgrade-Prüfprogramm meldet es, das Changelog sagt, was sich wann geändert hat. Proxmox hat seinen Teil getan.

Aber eine Voreinstellung ist ein Versprechen an die Person, die die Dinge so gemacht hat, wie der Hersteller es erwartet hat. Frische Installation, richtiger OS-Typ, VM nach Juli angelegt. Wessen Bestand eine Geschichte hat, und das ist jeder, der irgendetwas Echtes betreibt, steht teilweise außerhalb dieses Versprechens, und die Lücke kündigt sich nicht an. Sie zeigt sich als Gast, der ein bisschen langsam ist, als VBS-Freeze, den niemand mit einer Machine-Version in Verbindung bringt, oder als Zen-5-Knoten, auf dem die EPYC-Gäste nach einem Kernel-Update nicht mehr starten.

Release Notes beschreiben, was eine neue Installation bekommt. Sie sagen nix darüber, was deine Hosts tatsächlich fahren, und das sind zwei verschiedene Fragen. Die zweite beantwortest du nur, indem du hingehst und nachsiehst: qm showcmd auf den Gästen, dmesg auf den Hosts, die machine-Zeile in der Konfiguration. Nichts davon dauert länger als eine Minute pro Kiste.

Diese Minute ist die Arbeit. Proxmox gibt dir die Werkzeuge zum Prüfen, und als solches ist die Lücke zwischen dem, was du angenommen hast, und dem, was läuft, deine zu schließen, nicht ihre.


  1. QEMU documentation — Hyper-V Enlightenments — „No Hyper-V enlightenments are enabled by default by either KVM or QEMU“; Beschreibungen der einzelnen Flags; hv-evmcs „The feature is Intel-only“ und „some virtualization features (e.g. Posted Interrupts) are disabled when hv-evmcs is enabled“. ↩︎ ↩︎ ↩︎

  2. Proxmox qemu-server — CPUConfig.pm — get_hyperv_enlightenments: die Prüfungen auf OVMF und Version, die Schranken für die Machine-Version und die GenuineIntel-Prüfung für hv_evmcs. Hier ausgeführt mit 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“ und „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“; die Eigenschaft level und die Voreinstellungen für cet-ibt/cet-ss bei diesen Gästen. ↩︎ ↩︎ ↩︎ ↩︎

  4. Proxmox qemu-server — Debian changelog — 9.2.0 (15. Juli 2026) schaltet hv-evmcs für 11/2022/2025-Gäste auf Intel ab Machine 11.0+pve2 ein; 9.1.14 gibt level frei; 9.1.12 schaltet cet-ibt und cet-ss ab; Pinning beim Umstellen auf einen OS-Typ unter Microsoft Windows (Januar 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 gibt false zurück, wenn Major.Minor der QEMU-Version einer Machine neuer ist als das installierte Binary; die +pveN-Revisionen stehen in derselben Datei. ↩︎

  6. Proxmox qemu-server 9.2.0 — debian/control — beim Commit „bump version to 9.2.0“ vom 15. Juli 2026 lautet die Laufzeitabhängigkeit 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.“; dieselbe Version nennt „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“, das den Upstream-Fix aus 10.0 unten mitbringt; 10.1.2-3 „a regression with VNC clipboard breaking mouse pointer in Windows guests“; 10.1.2-5 der io_uring-Fix für „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 und 11.0 für die VSS- und Freeze-Fixes des Gast-Agenten, darunter „Fix guest-fs-freeze cause ‚Access denied Event ID 8194‘ in Event Viewer“. ↩︎ ↩︎

  10. Proxmox VE wiki — Qemu-guest-agent — für diesen Gast: „First you have to download the virtio-win driver iso“. ↩︎

  11. Proxmox qemu-server — CPUFlags.pm — die Flag-Liste pro VM, mit den oben zitierten Beschreibungen von hv-tlbflush und hv-evmcs. ↩︎

  12. Proxmox pve-manager — OSDefaults.js — der Eintrag win11 setzt machine: 'q35' und bios: 'ovmf'; die übrigen Einträge unter Microsoft Windows erben generic, das keine Machine setzt. ↩︎

  13. Proxmox VE admin guide — CPU Microcode Updates — frühe Updates über das Betriebssystem, der BIOS/UEFI-Weg als empfohlen, kein OS-Paket für arm64, das Vorgehen mit dis_ucode_ldr und Downgrade statt Purge. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  14. Proxmox VE pve-no-subscription repository for trixie — führt amd64-microcode 3.20251202.1~bpo13+1 und kein intel-microcode, gelesen am 27. Oktober 2026. ↩︎

  15. Linux kernel documentation — The Linux Microcode Loader — „Since kernel 5.19, late loading is not enabled by default“, und der Abschnitt „Why is late loading dangerous?“. ↩︎ ↩︎

  16. Debian Wiki — Microcode — über die vom CPU-Hersteller gelieferten, „opaque“ Update-Daten: „is non-free, and its contents are unknown to Debian“. ↩︎

  17. Proxmox pve-manager — pve8to9.pm — check_cpu_microcode_package protokolliert die Warnung; der vorher aufgerufene Lookup $get_pkg protokolliert „unable to determine installed $pkg version.“ als Fehler für jedes Paket, das nicht installiert ist. ↩︎

  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 — die JSL-Zeilen für 06-9c-00/01, „Celeron N4500/N4505/N5100/N5105“, über die Releases 20210608 bis 20240312; 0x24000026 aus dem Header von 06-9c-00 in Debians Paket gelesen. ↩︎

  20. AMD security bulletin AMD-SB-7055 — das RDSEED-Problem auf Zen-5-Prozessoren. ↩︎

  21. Proxmox VE Roadmap — 9.1 known issues, AMD Zen5 CPU issue with RDSEED — der Startfehler der Gäste, die korrigierte Paketversion und die Meldung No sha256 digest auf Boards ohne den Entrysign-BIOS-Fix. ↩︎ ↩︎

  22. Proxmox VE wiki — Upgrade from 8 to 9 — apt modernize-sources wandelt nach deb822 um und behält die alten Dateien mit der Endung .bak. ↩︎

  23. Debian packages — intel-microcode in trixie — die Versionen in Stable und Security, gegengeprüft mit apt-cache policy auf dem Host. ↩︎

  24. Debian sources — intel-microcode.postinst — dpkg-trigger --no-await update-initramfs, dann „microcode will be updated at next boot“; amd64-microcode macht dasselbe. ↩︎

  25. Debian manual — update-initramfs(8) — für -k „The default is the latest kernel version“, und „all“ arbeitet „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 — gibt „Current revision: 0x%08x“ und „Updated early from: 0x%08x“ aus. ↩︎

  27. Proxmox VE admin guide — High Availability, maintenance mode — HA-Dienste werden wegverschoben und „automatically once the maintenance mode is disabled and the node is back online“ zurückverschoben. ↩︎

  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“, Voreinstellung 10 Minuten. ↩︎

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