Summary
We use Virtualization.framework to run macOS guests on Apple silicon. When the guest is updated from macOS 15.6.1 to 15.8.1 inside the VM, the update writes a new boot loader, mBoot-20457.1.29, into the VM's auxiliary storage. After the update, the guest kernel can use only about 1.75 GB of the configured memory. The kernel wires the rest as VM_KERN_COUNT_BOOT_STOLEN. The guest swaps all the time, and builds become 7 to 18 times slower.
The fault stays after a cold boot. The guest boot-args value is empty.
Environment
Host: macOS 26.7.2 (25G320), Apple M3 Pro, 36 GB
Guest before the update: macOS 15.6.1 (24G90), installed from the IPSW
Guest after the update: macOS 15.8.1 (24H32), installed with softwareupdate inside the guest
VM configuration: VZMacOSBootLoader with the default ROM, VZMacPlatformConfiguration, VZMacAuxiliaryStorage, memorySize = 15032385536 (14 GiB), CPUCount = 6
A customer sees the same fault on macOS 26.6.2 with an M2 Pro host.
Steps to reproduce
Create a macOS 15.6.1 VM from the IPSW. Set memory to 14 GiB.
Boot the guest and confirm the RAM. vm_stat accounts for about 14 GiB.
In the guest, run:
sudo softwareupdate --install "macOS Sequoia 15.8.1-24H32" --restart --agree-to-license --user <owner> --stdinpass
After the guest restarts, run sudo zprint | grep BOOT_STOLEN and vm_stat.
Shut down the VM, start it again, and do step 4 again.
Expected result
The guest can use about 14 GiB of RAM, as it could before the update.
Actual result
15.6.1, before the update
15.8.1, after the update and after a cold boot
hw.memsize
15032385536
15032385536
RAM accounted for by vm_stat (free + active + inactive + speculative + wired + compressor)
about 13.99 GiB
about 1.75 GiB
VM_KERN_COUNT_BOOT_STOLEN
not measured
12,845,072 KB (about 12.25 GiB)
Swap activity
Swapins 0, Swapouts 0
Swapins 225,835, Swapouts 267,316
nvram boot-args
empty
empty
Auxiliary storage contents after the update
The auxiliary storage has two boot loader slots. Each slot has a 16-byte HUFA header: magic, version, upgrade count, and slot offset from 0x4000.
Header offset
Upgrade count
Slot offset
Boot loader
0x4000
1
0x24000
iBoot-11881.140.96 (the original 15.6.1 boot loader)
0x5000
2
0x224000
mBoot-20457.1.29 (written by the 15.8.1 update)
The VM boots the slot with the higher count, which is mBoot-20457.1.29.
Workaround test (customer)
The customer worked on a copy of an affected VM. They copied the iBoot-11881.140.96 slot over the active mBoot-20457.1.29 slot in the auxiliary storage. macOS 15.8.1 then booted with about 14 GB of usable RAM, and the RAM stayed correct after cold boots. Their results:
Extraction and validation of nine Xcode versions: 9 to 10 minutes (it was 68 to 102 minutes).
Xcode 26.1.1 simulator installation and cache preparation: under 7 minutes (it was more than 2 hours).
This workaround changes Apple's signed firmware by hand... Not really a good idea.
Related report
A public report describes the same fault with UTM and the same boot loader version. It also says that the kernel computes the stolen value from the memSizeActual and memSize boot parameters that the boot loader supplies. The author filed FB24992831 (https://wadetregaskis.com/the-macos-sequoia-15-8-updater-stole-my-ram/)
Questions
Is this a known fault in mBoot-20457.1.29? Will a later update fix it?
Is there a supported way to make a VM boot a specific boot loader slot? Or a supported way to roll back the boot loader in VZMacAuxiliaryStorage?
Is there a configuration on the host or in the guest that makes mBoot pass the full memory size?
We'd prefer to not make nvram read only if the new mBoot is absolutely needed for some reason.
3
1
230