Windows 11 without workarounds
What you get
Turn on TPM for a VM (in the wizard, or "tpm": true in its configuration) and keelOS does the rest. On first boot it creates the TPM's identity: endorsement key, certificates, a SHA-256 PCR bank. It starts a fresh TPM emulator every time the VM starts or resumes. The TPM's permanent state lives in the VM's own ZFS dataset, so snapshots and copies include it.
How it works
The VM sees a standard CRB TPM interface. Behind it is swtpm, the TPM emulator that QEMU and Proxmox also use. keelOS connects both of its channels: the data channel for TPM commands and the control channel for power-on, reset and saving the state. So the TPM is reset when the guest reboots, and its volatile state (PCRs, sessions, loaded keys) is saved into the VM's checkpoint on suspend and loaded into a new emulator on resume. That checkpoint is the same one used when the host restarts.
The TPM code in upstream bhyve was also made sturdier. A malformed command gets a TPM error instead of disabling the TPM; unimplemented registers are ignored as on real hardware instead of stopping the VM; if the emulator dies, the guest gets a TPM error and keeps running.
What was tested
- Windows 11 25H2: the installer's own TPM 2.0 and Secure Boot check passes with no bypass.
- BitLocker encrypts the system disk with the TPM protector.
- Windows restarts: the TPM unseals by itself, no recovery key asked.
- Suspend and resume with a new emulator process: 3.7 seconds of pause, TPM and BitLocker fine.
- PCR values are the same before and after a resume, and are measured again from zero when the guest reboots.
Along the way: new VMs put all vCPUs in one socket (Windows 11 Pro uses at most two sockets), and an e1000 interrupt bug that hung Windows on restart was fixed.
Not done yet
- The TPM state file is not encrypted. It sits on the same machine as the disk, so encryption would protect little here.
- Microsoft's Secure Boot keys are not preloaded.
- TPM requests that the firmware should carry out at next boot, such as "Clear TPM" in Windows, are lost. Upstream bhyve has the same gap.
- A bootable installer ISO must be removed before BitLocker is turned on; Windows refuses otherwise.