tpm: remove spurious TPM-establishment check at startup

Emulator::new() refused to start the VMM unless the TPM Establishment
bit (TPM_LOC_STATE.tpmEstablished, bit 0) was already set, aborting
with "TPM not in established state" otherwise.

That gate is not justified by the TCG PC Client Platform TPM Profile
(PTP) specification:

  * tpmEstablished == 0 is the defined default state after a cold
    reset of the TPM.
  * The bit transitions to 1 only after a TPM2_Startup is issued from
    Locality 3 or 4 -- something the guest firmware/OS may or may not
    ever do, and which has not happened by the time the VMM is wiring
    up the device.

So the check was rejecting the spec-defined normal case. It also had
inverted internal naming (the boolean called "established_flag" was
true when the bit was 0), which is what made the conditional read as
if it were testing the opposite of what it actually tested.

In practice the check happened to pass on KVM and fail on MSHV (issue
socket, but the bug is independent of the backend: the VMM has no
business gating startup on tpmEstablished at all.

Drop the check. The bit is still surfaced to the guest from
Tpm::read() when CRB_LOC_STATE is read, which is the only place the
PTP spec requires it to be visible.

Assisted-by: Copilot:GPT-5.5
Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
Wei Liu
2026-05-29 20:26:11 -07:00
parent ff5a6dcdb9
commit 746b760f69

View File

@@ -116,11 +116,12 @@ impl Emulator {
)));
}
if !emulator.get_established_flag() {
return Err(Error::InitializeEmulator(anyhow!(
"TPM not in established state"
)));
}
// Note: The TPM establishment flag can only be queried after the TPM
// has been initialized via CMD_INIT. swtpm rejects most control
// commands (returning PTM_BAD_ORDINAL = 0x0A) before initialization,
// so we defer the establishment-flag check to `get_established_flag()`
// which is invoked later (e.g. on guest reads of CRB_LOC_STATE) after
// `Tpm::reset()` has issued CMD_INIT.
Ok(emulator)
}