feat: patched qemu 11.1.2 identity series with macos support
This commit is contained in:
+93
-1
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user