> if you have root (and presumably you can even write a different kernel), how do you make sure the TPM can verify what's actually running on the processor when you can just fake it?
On a PC architecture, the TPM is wired up to the CPU and other parts of the system, such that (for so-called "static root of trust") it gets initialized with a hash of the BIOS at bootup. The legitimate BIOS then adds in a hash of the boot sector, which adds in a hash of the kernel, which adds in a hash of anything the kernel thinks is worth verifying. Only if the final value of this TPM register (called a "PCR") matches up will the TPM allow a stored private key to be unlocked ("unsealed") and used.
Alternatively, for so-called "dynamic root of trust", there's a processor instruction that both clears all processor state (interrupts, paging, etc.) and a particular TPM PCR, and loads in a block of code. If the code is different, the key won't unseal. If someone is intercepting that processor instruction, the PCR won't get initialized correctly, and the key still won't unseal.
So it's mostly up to the kernel to verify everything that could possibly be relevant. (If you're thinking this is a hard engineering task, yes, that's one reason why this isn't in wide deployment, despite the technology all existing.) For instance, it might verify an entire read-only root filesystem, and then set things up so that on the work container or VM, nothing else can be installed, no additional executables or libraries or LD_PRELOADs get loaded, debuggers don't work, etc. In the personal-use container/VM, it can still run a normal OS.