feat: patched qemu 11.1.2 identity series with macos support

This commit is contained in:
2026-10-10 01:11:44 +02:00
parent f99ff1400a
commit d47e1d5fa0
15 changed files with 606 additions and 59 deletions
+93 -1
View File
@@ -5,7 +5,7 @@ says *why*, with the source references. Written 2026-09-03 at 2/85, revised 2026
on both VMAware v2.8.1 and VMAware HEAD (commit 95fecc2) - the one survivor is `GPU_CAPABILITIES`,
and VMAware's own verdict is "Running on bare metal", likeliness 20%, confirmation false.
Source read against: VMAware `src/vmaware.hpp`, QEMU 11.1.1, kernel 7.2.3 `arch/x86/kvm`.
Source read against: VMAware `src/vmaware.hpp`, QEMU 11.1.2, kernel 7.2.3 `arch/x86/kvm`.
---
@@ -125,6 +125,98 @@ WAET and never did: `build_waet()` has zero call sites, so its `grep -q build_wa
satisfied by the definition alone and the insert never ran. Guard on a call site, not on a
definition.
**The chain grew.** `firmware()` returns on its first hit, so clearing one link only exposes the
next, and current VMAware has added links past the eight above. `09-firmware-chain` clears the
rest, measured to 0 detections on both v2.8.1 and HEAD:
| Link | Fix |
| --- | --- |
| IQST/IQCR + PRR0/PRRI interrupt-query methods | renamed PSTA/PCRS/PRS0/PRSI |
| TPM PPI regions/method TPP2/TPP3/TPFN | renamed PPI2/PPI3/PPIF |
| zeroed `_S5` SLP_TYP package | 2-element package form |
| `ACPI0006` `_HID` in `\_GPE` | declared by full path `\_GPE._HID`; dropping it stops macOS powering off |
| Q35 MMCONFIG reservation device `MCFG` | renamed `PCMM` |
| synthetic GSI link devices, empty `_DIS`/`_SRS` | gave the no-op methods a body |
| PCIe `_OSC` `And(CDW3, 0x1F, ..)` mask | swapped the `And()` operands (commutative) |
| PIRQ link `_PRS` fixed IRQ 5/10/11 | listed the same set as `{11, 10, 5}` |
A q35 guest also needs a named USB controller in the DSDT (the ICH9 EHCI/UHCI set, declared `EHC1`/
`UHC1`), or the release flags "complete absence of USB controller declarations"; that is a domain
choice, not a QEMU patch.
### CLEARED - the CPU-hotplug I/O signature that macOS forced back in (`11-macos-cpu-hotplug`)
macOS references `\_SB.CPUS.Cxxx` from its own CpuPlug SSDT, so the guest must carry QEMU's
`build_cpus_aml` output (the `\_SB.PCI0.PRES` controller plus the `\_SB.CPUS` `Processor` objects)
or it hangs in ACPI namespace init. `01-firmware` had dropped that whole block, which is why macOS
lived in an opt-in patch: the block reintroduces exactly one FIRMWARE tell, so a macOS-capable build
scored 2/85 on v2.8.1 while HEAD stayed clean.
The tell is a single check. v2.8.1 `firmware()` carries `cpu_hotplug_io[] = {0x0B, 0xD8, 0x0C}` and
byte-matches it anywhere in the tables. Those three bytes are `WordData 0x0CD8` - the CPU-hotplug
register port that `build_cpus_aml` writes into the `PRST` `OperationRegion` base
(`ICH9_CPU_HOTPLUG_IO_BASE`). Confirmed by dumping the macOS-build DSDT: the bytes appear only at the
`OperationRegion` operand, never in the `_CRS`. A small-resource `IO` descriptor encodes `0x0CD8` as
`0x47 0x01 0xD8 0x0C 0xD8 0x0C 0x01 0x0C` - the `0xD8 0x0C` runs are preceded by `0x01`/`0x0C`, never
`0x0B` - so the `_CRS` is not what matches and does not need touching. The renamed `_UID` ("Reserved
resources C") already dodges the separate `"CPU Hotplug resources"` string check; it was never the
live tell. HEAD has no `cpu_hotplug_io` check, so it never flagged the block.
**Relocating the base does not work.** The obvious fix - move `ICH9_CPU_HOTPLUG_IO_BASE` off `0x0CD8`
so the pattern changes - clears the scanner but hangs every SMM/OVMF guest: macOS spins ~10 cores at
boot and never reaches login, Windows the same. `OvmfPkg/Include/IndustryStandard/Q35MchIch9.h`
hardcodes `ICH9_CPU_HOTPLUG_BASE 0x0CD8` and OVMF's SMM code reads the register block at that fixed
port, independent of the AML. The non-SMM path (plain OVMF, a bare Linux boot) survives a move; the
SMM guests we actually run do not. A/B confirmed it: macOS reaches login on `0x0CD8`, spins on
`0x0CE4`. Patching OVMF is already on the rejected list.
**The fix keeps the port and hides only the AML operand.** `11` emits the `OperationRegion` base for
a SystemIO region as `Add(0x0C00, 0xD8)` instead of the literal `0x0CD8`. It evaluates to the
identical `0x0CD8` at namespace load - the port QEMU decodes, the port in `_CRS`, and the port OVMF
reads are all unchanged - but the AML is `0x72 0x0B 0x00 0x0C 0x0A 0xD8 ..`, so the `0x0B 0xD8 0x0C`
run never appears. macOS's interpreter evaluates the computed base without complaint.
Verified on QEMU 11.1.2 with this fix in the default series: the DSDT keeps `\_SB.CPUS`/`PRES`/
`Processor(C000..)` and `0x0CD8`, with no `0x0B 0xD8 0x0C` anywhere (iasl-clean); macOS boots to
login and powers off via S5 in ~12 s; VMAware v2.8.1 and HEAD both report `detected=0` / `FIRMWARE=0`
on the stealth guest; Windows (secboot + SMM) and Linux boot unchanged. The opt-in split is gone.
---
## CLEARED - CTYPE and SMBIOS_VM_BIT (the SMBIOS QEMU synthesises)
On Linux, VMAware reads SMBIOS four ways: `DMIDECODE` and `DMI_SCAN` match VM vendor strings in
`dmidecode -t system` and seven `/sys/class/dmi/id` files, `SMBIOS_VM_BIT` tests bit 4 of type 0
byte 19, and `CTYPE` fires on chassis type 1, Other (HEAD e1a9786, vmaware.hpp:8272, :8948, :9023,
:8234). On Windows, `FIRMWARE` also scans the raw tables (`RSMB`, :10369) for `pc-q35` and `Q35 +`
(:9726). The strings are domain identity. The bit, the chassis type and the default strings are
what QEMU emits by itself.
QEMU synthesises every required structure the domain does not supply. Switching that off
(`smbios_defaults = false`) leaves only what the domain passes: either a complete real dump through
`-smbios file=`, or a table with no processor, memory or end-of-table structures. `10-smbios` keeps
it on and fixes what the synthesised structures leak:
| Leak | Fix |
| --- | --- |
| type 3 chassis type hard-coded to 1 (Other) | defaults to 3 (Desktop), set with `-smbios type=3,chassis-type=N` |
| type 0 VM bit set whenever type 0 fields are given | `vm` defaults off; libvirt `<sysinfo>` cannot pass `vm=off` |
| unset product and version strings `Standard PC (Q35 + ICH9, 2009)`, `pc-q35-<ver>` | `Unknown`, like the manufacturer from `04-fw-cfg` |
Measured on a Linux q35 guest, the same score on VMAware v2.8.1 and HEAD:
| SMBIOS from the domain | QEMU | Score |
| --- | --- | --- |
| complete real dump, 52 `file=` structures | defaults off | 0/85 |
| the same dump | defaults on | 0/85, `dmidecode` byte-identical |
| field arguments for types 0-4 with `vm=off` | defaults on, builders unpatched | 1/85, `CTYPE` |
| field arguments for types 0-4, no `vm=off`, `chassis-type` set | `10-smbios` | 0/85 |
Identity is authored as field arguments. A dump through `-smbios file=` adds what field arguments
cannot express (memory module detail, OEM structures, battery) and mixes with them per type: a type
given as `file=` cannot also take field arguments. Windows and macOS guests are not yet measured
against this patch.
---
## OPEN - GPU_CAPABILITIES (weight 20)