In the Linux kernel, the following vulnerability has been resolved:
x86/kvm: Force legacy PCI hole to UC when overriding MTRRs for TDX/SNP
When running as an SNP or TDX guest under KVM, force the legacy PCI hole, i.e. memory between Top of Lower Usable DRAM and 4GiB, to be mapped as UC via a forced variable MTRR range.
In most KVM-based setups, legacy devices such as the HPET and TPM are enumerated via ACPI. ACPI enumeration includes a Memory32Fixed entry, and optionally a SystemMemory descriptor for an OperationRegion, e.g. if the device needs to be accessed via a Control Method.
If a SystemMemory entry is present, then the kernel's ACPI driver will auto-ioremap the region so that it can be accessed at will. However, the ACPI spec doesn't provide a way to enumerate the memory type of SystemMemory regions, i.e. there's no way to tell software that a region must be mapped as UC vs. WB, etc. As a result, Linux's ACPI driver always maps SystemMemory regions using ioremap_cache(), i.e. as WB on x86.
The dedicated device drivers however, e.g. the HPET driver and TPM driver, want to map their associated memory as UC or WC, as accessing PCI devices using WB is unsupported.
On bare metal and non-CoCO, the conflicting requirements "work" as firmware configures the PCI hole (and other device memory) to be UC in the MTRRs. So even though the ACPI mappings request WB, they are forced to UC- in the kernel's tracking due to the kernel properly handling the MTRR overrides, and thus are compatible with the drivers' requested WC/UC-.
With force WB MTRRs on SNP and TDX guests, the ACPI mappings get their requested WB if the ACPI mappings are established before the dedicated driver code attempts to initialize the device. E.g. if acpi_init() runs before the corresponding device driver is probed, ACPI's WB mapping will "win", and result in the driver's ioremap() failing because the existing WB mapping isn't compatible with the requested WC/UC-.
E.g. when a TPM is emulated by the hypervisor (ignoring the security implications of relying on what is allegedly an untrusted entity to store measurements), the TPM driver will request UC and fail:
[ 1.730459] ioremap error for 0xfed40000-0xfed45000, requested 0x2, got 0x0 [ 1.732780] tpmtis MSFT0101:00: probe with driver tpmtis failed with error -12
Note, the '0x2' and '0x0' values refer to "enum pagecachemode", not x86's memtypes (which frustratingly are an almost pure inversion; 2 == WB, 0 == UC). E.g. tracing mapping requests for TPM TIS yields:
Mapping TPM TIS with reqtype = 0 WARNING: CPU: 22 PID: 1 at arch/x86/mm/pat/memtype.c:530 memtypereserve+0x2ab/0x460 Modules linked in: CPU: 22 UID: 0 PID: 1 Comm: swapper/0 Tainted: G W 6.16.0-rc7+ #2 VOLUNTARY Tainted: [W]=WARN Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/29/2025 RIP: 0010:memtypereserve+0x2ab/0x460 _ioremapcaller+0x16d/0x3d0 ioremapcache+0x17/0x30 x86acpiosioremap+0xe/0x20 acpiosmapiomem+0x1f3/0x240 acpiosmapmemory+0xe/0x20 acpiexsystemmemoryspacehandler+0x273/0x440 acpievaddressspacedispatch+0x176/0x4c0 acpiexaccessregion+0x2ad/0x530 acpiexfielddatumio+0xa2/0x4f0 acpiexextractfromfield+0x296/0x3e0 acpiexreaddatafromfield+0xd1/0x460 acpiexresolvenodetovalue+0x2ee/0x530 acpiexresolvetovalue+0x1f2/0x540 acpidsevaluatenamepath+0x11b/0x190 acpidsexecendop+0x456/0x960 acpipsparseloop+0x27a/0xa50 acpipsparseaml+0x226/0x600 acpipsexecutemethod+0x172/0x3e0 acpinsevaluate+0x175/0x5f0 acpievaluateobject+0x213/0x490 acpievaluateinteger+0x6d/0x140 acpibusgetstatus+0x93/0x150 acpiaddsingleobject+0x43a/0x7c0 acpibuscheckadd+0x149/0x3a0 acpibuscheckadd1+0x16/0x30 acpinswalknamespace+0x22c/0x360 acpiwalknamespace+0x15c/0x170 acpibusscan+0x1dd/0x200 acpiscaninit+0xe5/0x2b0 acpiinit+0x264/0x5b0 doone_i ---truncated---