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.
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:
| Flag | Was der Gast bekommt | Was es einspart |
|---|---|---|
hv_time | Hyper-V-Referenzuhr und TSC-Page | Zeitstempel lesen ohne Exit |
hv_relaxed | Anweisung, Watchdog-Timeouts abzuschalten | falsche Timeouts, wenn eine vCPU nicht eingeplant ist |
hv_vapic | VP-Assist-Page für den APIC | End-of-Interrupt ohne Exit |
hv_spinlocks | paravirtuelle Spinlocks, Wiederholungen, bevor der Host Bescheid bekommt | Kreiseln um ein Lock, dessen Halter nicht läuft |
hv_vpindex | seinen eigenen virtuellen Prozessorindex | Voraussetzung für die nächsten vier |
hv_runtime | wie lange jede vCPU tatsächlich lief | ein ehrlicher Blick auf gestohlene Zeit |
hv_synic, hv_stimer | synthetischen Interrupt-Controller und Timer | emulierte Timer-Hardware |
hv_ipi | IPIs an viele vCPUs mit einem Hypercall | ein APIC-Exit pro Ziel-CPU |
hv_reset | Reset über den Hypervisor | |
hv_evmcs | Enlightened VMCS, nur Intel | schnellere verschachtelte Virtualisierung |
hv_tlbflush | paravirtuellen TLB-Shootdown | Warten 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.
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-Typ | Firmware | Machine-Version | Host | Hinzugefügte Enlightenments |
|---|---|---|---|---|
l26 oder other | beliebig | beliebig | beliebig | keine |
wxp (5) | SeaBIOS | 11.0 | beliebig | keine |
w2k8 (Vista/2008) | SeaBIOS | 11.0 | beliebig | spinlocks, vapic, time, reset, vpindex, runtime |
win7 | SeaBIOS | 11.0 | beliebig | die sechs oben plus relaxed, synic, stimer, ipi |
win7 | OVMF | 11.0 | beliebig | keine |
win10 | OVMF | 11.0+pve2 | Intel | alle zehn, kein evmcs |
win11 | OVMF | 11.0+pve1 | Intel | alle zehn, kein evmcs |
win11 | OVMF | 11.0+pve2 | Intel | alle zehn plus evmcs |
win11 | SeaBIOS | 11.0+pve2 | AMD | alle 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:
| Paket | Version | Erschienen | Was es mitbringt |
|---|---|---|---|
qemu-server | 9.2.0 | 15. Juli 2026 | die Voreinstellung hv-evmcs und Machine 11.0+pve2 |
pve-qemu-kvm | 11.0.2-1 | 1. Juli 2026 | QEMU 11.0.2, an dem Tag aktuell |
pve-qemu-kvm, Minimum | 11.0.0-1 | 5. Mai 2026 | der 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:
| QEMU | Proxmox-Build | Was es für den Gast behoben hat |
|---|---|---|
| 10.0 | 10.0.2-1, 17. Juni 2025 | den „PCI Label Id“-Fehler, auf Englisch harmlos, in lokalisierten Installationen aber imstande, den Gast hängen zu lassen |
| 10.1 | 10.1.2-3, 17. November 2025 | eine Regression in der VNC-Zwischenablage, die den Mauszeiger kaputt machte |
| 10.1 | 10.1.2-5, 22. Dezember 2025 | hängende Backups einer VM mit TPM-Disk, ein io_uring-Fix |
| 11.0 | 11.0.0-1, 5. Mai 2026 | eine Regression im FUSE-Export, den swtpm für den TPM-Zustand nutzt |
| 11.0 | 11.0.2-1, 1. Juli 2026 | Hyper-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.
| Flag | Proxmox’ eigene Beschreibung | Wann 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-Typ | Machine, die er bekommt | Firmware, die er bekommt |
|---|---|---|
| 11/2022/2025 | q35 | OVMF |
| 10/2016/2019 und jeder ältere Typ unter Microsoft Windows | i440fx | SeaBIOS |
| Other, Linux | i440fx | SeaBIOS |
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.
| Quelle | Angewendet | Liefert ihn | Auf meinem 9.2-Host heute |
|---|---|---|---|
| BIOS/UEFI-Update des Boards | bei jedem Einschalten, dauerhaft | der Board- oder Serverhersteller | was das letzte BIOS mitgebracht hat |
Debian non-free-firmware | früh beim Booten, aus dem Initramfs | Debian | intel-microcode 3.20251111.1~deb13u1, amd64-microcode 3.20250311.1 |
| Proxmox-VE-Repository | früh beim Booten, aus dem Initramfs | Proxmox | amd64-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.
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-Installation | Von 8.x aktualisiert | |
|---|---|---|
non-free-firmware | vom Installer eingeschaltet | was 8.x hatte, oft gar nicht |
| Microcode-Paket | für die erkannte CPU installiert | keins, bis du die Komponente hinzufügst |
| Was es dir sagt | nicht nötig | pve8to9, als FAIL und als WARN, und nur, wenn du es laufen lässt |
| Spätere Updates | apt full-upgrade und ein Neustart | dasselbe, 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:
| Revision | Intel-Release | Auf diesem Host |
|---|---|---|
0x1d | microcode-20210608 | was die Board-Firmware heute lädt |
0x2400001f | microcode-20220207 | |
0x24000023 | microcode-20220510 | sechs Monate vor dem BIOS dieses Boards erschienen |
0x24000024 | microcode-20230214 | |
0x24000026 | microcode-20240312 | in 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 Boot | Initramfs enthält den Microcode | Revision, auf der die CPU landet |
|---|---|---|
| 7.0.14-24, der Standardeintrag | ja | die 0x24000026 aus dem Paket |
| 7.0.14-23, festgepinnt oder der Fallback-Eintrag | nein | die 0x1d aus dem BIOS |
| alles Ältere | nein | die 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.
| Schritt | Befehl | Fertig, wenn |
|---|---|---|
| Cluster gesund | pvecm status, ceph -s | quorate, HEALTH_OK |
| Knoten leeren | ha-manager crm-command node-maintenance enable <node>, Nicht-HA-Gäste von Hand migrieren | keine Gäste mehr drauf |
| Optional, Ceph | ceph osd set noout | Flag in ceph -s sichtbar |
| Neustart, prüfen | dmesg | grep -i microcode | neue Revision sichtbar |
| Ceph erholt | ceph -s | alle OSDs up und in, HEALTH_OK |
| Freigeben | node-maintenance disable <node>, ceph osd unset noout | HA-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.
| Lage | Tu das | Warum |
|---|---|---|
| Du verdächtigst den neuen Microcode | einmal mit dis_ucode_ldr booten | schaltet den Loader nur für diesen einen Boot ab29 |
| Alte Revision gut, neue nicht | die frühere Version installieren und festhalten | ein Purge kann eine noch ältere BIOS-Revision laufen lassen |
| Ein paar Wochen später | apt-mark unhold, dann full-upgrade | ein 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.
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“. ↩︎ ↩︎ ↩︎Proxmox qemu-server —
CPUConfig.pm—get_hyperv_enlightenments: die Prüfungen auf OVMF und Version, die Schranken für die Machine-Version und dieGenuineIntel-Prüfung fürhv_evmcs. Hier ausgeführt mit qemu-server 9.2.11. ↩︎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
levelund die Voreinstellungen fürcet-ibt/cet-ssbei diesen Gästen. ↩︎ ↩︎ ↩︎ ↩︎Proxmox qemu-server — Debian changelog — 9.2.0 (15. Juli 2026) schaltet
hv-evmcsfür 11/2022/2025-Gäste auf Intel ab Machine 11.0+pve2 ein; 9.1.14 gibtlevelfrei; 9.1.12 schaltetcet-ibtundcet-ssab; 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“. ↩︎ ↩︎ ↩︎ ↩︎Proxmox qemu-server —
Machine.pm—can_run_pve_machine_versiongibt false zurück, wenn Major.Minor der QEMU-Version einer Machine neuer ist als das installierte Binary; die+pveN-Revisionen stehen in derselben Datei. ↩︎Proxmox qemu-server 9.2.0 —
debian/control— beim Commit „bump version to 9.2.0“ vom 15. Juli 2026 lautet die Laufzeitabhängigkeitpve-qemu-kvm (>= 7.1~). ↩︎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“ ↩︎ ↩︎
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“. ↩︎
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“. ↩︎ ↩︎
Proxmox VE wiki — Qemu-guest-agent — für diesen Gast: „First you have to download the virtio-win driver iso“. ↩︎
Proxmox qemu-server —
CPUFlags.pm— die Flag-Liste pro VM, mit den oben zitierten Beschreibungen vonhv-tlbflushundhv-evmcs. ↩︎Proxmox pve-manager —
OSDefaults.js— der Eintragwin11setztmachine: 'q35'undbios: 'ovmf'; die übrigen Einträge unter Microsoft Windows erbengeneric, das keine Machine setzt. ↩︎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_ldrund Downgrade statt Purge. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎Proxmox VE
pve-no-subscriptionrepository for trixie — führtamd64-microcode3.20251202.1~bpo13+1und keinintel-microcode, gelesen am 27. Oktober 2026. ↩︎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?“. ↩︎ ↩︎
Debian Wiki — Microcode — über die vom CPU-Hersteller gelieferten, „opaque“ Update-Daten: „is non-free, and its contents are unknown to Debian“. ↩︎
Proxmox pve-manager —
pve8to9.pm—check_cpu_microcode_packageprotokolliert die Warnung; der vorher aufgerufene Lookup$get_pkgprotokolliert „unable to determine installed $pkg version.“ als Fehler für jedes Paket, das nicht installiert ist. ↩︎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‘.“ ↩︎
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;
0x24000026aus dem Header von06-9c-00in Debians Paket gelesen. ↩︎AMD security bulletin AMD-SB-7055 — das RDSEED-Problem auf Zen-5-Prozessoren. ↩︎
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 digestauf Boards ohne den Entrysign-BIOS-Fix. ↩︎ ↩︎Proxmox VE wiki — Upgrade from 8 to 9 —
apt modernize-sourceswandelt nach deb822 um und behält die alten Dateien mit der Endung.bak. ↩︎Debian packages —
intel-microcodein trixie — die Versionen in Stable und Security, gegengeprüft mitapt-cache policyauf dem Host. ↩︎Debian sources —
intel-microcode.postinst—dpkg-trigger --no-await update-initramfs, dann „microcode will be updated at next boot“;amd64-microcodemacht dasselbe. ↩︎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)“. ↩︎Linux kernel source —
arch/x86/kernel/cpu/microcode/core.c— gibt „Current revision: 0x%08x“ und „Updated early from: 0x%08x“ aus. ↩︎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. ↩︎
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. ↩︎Linux kernel documentation — kernel parameters —
dis_ucode_ldr: „Disable the microcode loader.“ ↩︎