UTM 5.0.4 aborts when starting an AArch64 VM after explicit IPA-size configuration
- Dominant language
- Swift
- Stars
- 35.5k
- Forks
- 1.8k
- Avg merge
- 5d 5h
- Merged PRs (30d)
- 7
Description
## Summary
UTM 5.0.4 opens normally on a jailbroken Apple Silicon iPad, but starting an AArch64 Omarchy/Linux VM immediately terminates the UTM process before the guest begins booting.
This is a regression from UTM 4.7.5. On the same device, UTM 4.7.5 can create the HVF VM and proceed through the Omarchy installation flow. UTM 5.0.4 aborts during `hvf_accel_init()`.
Eight device crash reports reproduce the same `SIGABRT` stack. A Vulkan-disabled A/B test removes Venus and the explicit 4 KiB IPA granule from the QEMU command line, but the crash remains unchanged. The leading source-level regression candidate in the private VM-create path is that QEMU now creates an `hv_vm_config_t` and attempts to set a 36-bit IPA size instead of calling `hv_vm_create(NULL)`.
## Environment
- Device identifier: `iPad13,11` (`J523xAP`)
- OS: iPadOS 16.3 (`20D47`), jailbroken
- UTM: 5.0.4, build 123
- Bundle ID: `com.utmapp.UTM`
- UTM executable UUID: `E6434751-43C6-3A50-8125-ED96417AA42B`
- `qemu-aarch64-softmmu` UUID: `AB3F367D-F020-3E94-BF2E-B06F8344E74A`
- Guest: AArch64 Omarchy/Linux image
- Accelerator: HVF, `-cpu host`
- TSO: not enabled
The QEMU UUID in all eight device crash reports matches the QEMU binary in the official UTM 5.0.4 `UTM-HV.ipa` release asset.
## Steps to reproduce
1. Open UTM 5.0.4. The application itself opens and remains stable.
2. Open the existing AArch64 Omarchy VM configuration.
3. Ensure Hypervisor is enabled.
4. Start the VM.
5. UTM terminates before any guest boot output appears.
The failure reproduces on every attempt tested.
## Expected result
HVF creates the VM and the guest begins booting, as it does with UTM 4.7.5 on the same device.
## Actual result
UTM terminates with `EXC_CRASH / SIGABRT`. Every captured report has the same faulting stack:
```text
__pthread_kill
pthread_kill
abort
assert_hvf_ok_impl
hvf_accel_init
accel_init_machine
do_configure_accelerator
qemu_opts_foreach
qemu_init
```
The abort occurs during HVF accelerator initialization, before guest execution. This is not a Jetsam termination, guest failure, or crash in a Metal, ANGLE, VirGL, SPICE, or Venus rendering thread.
## Reproductions
| Time | Incident ID | Result |
| --- | --- | --- |
| 17:38:05 | `5865837E-68F1-4F83-A079-9AE0CC662C36` | `EXC_CRASH / SIGABRT` |
| 17:38:13 | `663F5C04-0B49-48CC-9397-DDC3FA1D9AE9` | `EXC_CRASH / SIGABRT` |
| 18:00:40 | `2173F0B8-663C-46AB-8AAF-26B77F73B4C7` | `EXC_CRASH / SIGABRT` |
| 18:00:42 | `5520DF80-34DB-4EE3-936A-E82CAEE94FA6` | `EXC_CRASH / SIGABRT` |
| 18:00:45 | `17C91169-BF02-4719-85FC-6541AAA1806B` | `EXC_CRASH / SIGABRT` |
| 18:02:20 | `4AF63224-31D1-4DB9-9D1F-181226A41A2A` | `EXC_CRASH / SIGABRT` |
| 18:19:56 | `3AB85087-DC3B-4456-8119-828A80285809` | `EXC_CRASH / SIGABRT` |
| 18:20:19 | `E38B96E6-3542-4A51-BB76-888EF2FEF0ED` | `EXC_CRASH / SIGABRT` |
## Vulkan/Venus A/B test
With the global Vulkan Driver setting at its default, UTM launches QEMU with arguments including:
```text
-device virtio-gpu-gl-pci,hostmem=256M,blob=true,venus=true
-machine virt
-accel hvf,ipa-granule-size=0x1000
```
The initial hypothesis was that iPadOS 16.3 rejected the requested 4 KiB IPA granule.
I then changed **Settings > UTM > Vulkan Driver** to **Disabled** and restarted the same VM. Live `QEMULogging` confirmed that the new launch contained only:
```text
-device virtio-gpu-gl-pci
-machine virt
-accel hvf
```
The following arguments were no longer present:
```text
hostmem=256M
blob=true
venus=true
ipa-granule-size=0x1000
```
UTM still aborted with the exact same stack. Therefore, Venus and the 4 KiB IPA granule are not required to trigger this failure.
## IPA capability values
The device reports:
```text
kern.hv.ipa_size_4k: 68719476736
kern.hv.ipa_size_16k: 68719476736
```
Both values are `2^36`, or a 36-bit/64 GiB IPA space.
For the iOS build, QEMU 10.0.12 performs the following calculation:
1. `hvf_arm_get_default_ipa_bit_size()` returns `0` because the public macOS API is unavailable on iOS.
2. `ctz64(2^36)` returns `36` for both sysctls.
3. `36` is already a valid ARM PARange value, so no further rounding occurs.
4. The `virt` machine selects `pa_range = 36`.
5. The private iOS path attempts to resolve `_hv_vm_config_set_ipa_size` with `dlsym(RTLD_NEXT, ...)` and, if resolution succeeds, calls it as `_hv_vm_config_set_ipa_size(config, 1ULL << 36)`.
If the private setter resolves as expected, the value written into the private configuration is:
```text
0x1000000000 = 68719476736 bytes
```
This rules out the previously considered 52-bit fallback and an arithmetic conversion error in the current QEMU source. It does not establish what unit or additional constraints iPadOS 16.3/XNU 22 expects for this private field.
With Vulkan disabled and TSO off, the source and release-binary disassembly imply the following VM-create arguments if the private setter resolves:
```text
min_ipa = 0
ipa_size = 0x1000000000
granule = 0
flags = 0
isa = 1
```
The known-working UTM 4.7.5 path sends the default values instead:
```text
min_ipa = 0
ipa_size = 0
granule = 0
flags = 0
isa = 1
```
Within the derived private VM-create tuple, the leading remaining difference is therefore `ipa_size: 0 -> 2^36`. This statement is limited to this HVF initialization path; UTM 4.7.5 and 5.0.4 contain many other changes.
## Version/source comparison
The dependency pins are:
| UTM version | QEMU | Hypervisor shim |
| --- | --- | --- |
| 4.7.5 | `v10.0.2-utm` (`37ba092d`) | `f8fc8d8f` |
| 5.0.4 | `v10.0.12-utm` (`6601422e`) | `b2c910fb` |
References:
- [UTM 4.7.5 dependency pins](https://github.com/utmapp/UTM/blob/v4.7.5/patches/sources#L26-L51)
- [UTM 5.0.4 dependency pins](https://github.com/utmapp/UTM/blob/v5.0.4/patches/sources#L26-L62)
- [QEMU commit adding the private IPA-size path](https://github.com/utmapp/qemu/commit/9f81c6232fbb3ea1d9e43cb67fe5e029723d2ed5)
- [Hypervisor shim commit adding IPA base/size setters](https://github.com/utmapp/Hypervisor/commit/b2c910fb9f687929a50e5a7d62e59e43a006d47d)
In QEMU 10.0.2, the iOS `CONFIG_HVF_PRIVATE` path uses a null configuration unless TSO is enabled:
```c
hv_vm_config_t config = NULL;
#if defined(CONFIG_HVF_PRIVATE)
if (hvf_tso_mode) {
config = hv_vm_config_create();
_hv_vm_config_set_isa(config, HV_VM_CONFIG_ISA_PRIVATE);
}
#endif
ret = hv_vm_create(config);
```
For this AArch64 VM, TSO is disabled, so UTM 4.7.5 effectively calls:
```c
hv_vm_create(NULL);
```
QEMU 10.0.12 always creates a configuration and sets the IPA size:
```c
hv_vm_config_t config = hv_vm_config_create();
ret = hvf_set_ipa_size(config, pa_range);
if (ret != HV_SUCCESS) {
goto cleanup;
}
if (ipa_granule_size) {
ret = hvf_set_ipa_granule(config, ipa_granule_size);
if (ret != HV_SUCCESS) {
goto cleanup;
}
}
ret = hv_vm_create(config);
```
The two Hypervisor shim revisions use the same `hv_vm_config_private` layout, the same 0x20-byte kernel argument layout, and the same `HV_CALL_VM_CREATE` selector. The newer shim only adds setters that write non-zero values into fields that already existed. This does not appear to be a struct-layout mismatch between the two bundled shim versions.
The private IPA-size setter itself only writes the value and returns success for a non-null configuration. If `dlsym` resolves it, validation of the resulting tuple occurs when the configuration reaches the Hypervisor VM-create path. If `dlsym` does not resolve it, QEMU instead returns `HV_UNSUPPORTED` before calling `hv_vm_create`.
## Assessment
The leading application-level regression candidate is the new explicit IPA-size configuration path in UTM 5.0.4/QEMU 10.0.12 on iOS.
The strongest explanation is that iPadOS 16.3/XNU 22 does not accept this explicit private VM-create configuration, even though its sysctls report a 36-bit maximum. The default `hv_vm_create(NULL)` path remains compatible, which explains why UTM 4.7.5 can create the VM.
There is one narrower unresolved possibility: `dlsym(RTLD_NEXT, "_hv_vm_config_set_ipa_size")` could fail at runtime, causing QEMU to return `HV_UNSUPPORTED` before calling `hv_vm_create`. However:
- the official 5.0.4 Hypervisor framework does export this symbol;
- the QEMU UUID from the official release exactly matches the device crash reports; and
- the QEMU framework directly depends on the bundled Hypervisor framework.
The `.ips` reports do not retain QEMU's stderr output, so the exact `HV_*` return code was not captured. `assert_hvf_ok()` produces this same stack for any non-success `hv_return_t`; the stack itself does not distinguish `HV_UNSUPPORTED` from another failure. `HV_UNSUPPORTED` remains a hypothesis informed by the related macOS reports below, not a return code directly confirmed on this device.
Issues #7579 and #7584 have a similar assertion and `HV_UNSUPPORTED` symptom, but their underlying cause is the separate macOS 26 availability-macro bug. They should not be treated as proof of the iPadOS 16.3 cause:
- https://github.com/utmapp/UTM/issues/7579
- https://github.com/utmapp/UTM/issues/7584
## Suggested minimal fix/test
For iOS `CONFIG_HVF_PRIVATE`, TSO disabled, and no supported custom IPA requirement, restore the UTM 4.7.5 behavior and allow the kernel to select its default configuration:
```c
hv_vm_create(NULL);
```
The smallest diagnostic build would:
1. keep Vulkan disabled;
2. skip the private IPA-size setter;
3. call `hv_vm_create(NULL)` under the same iOS/private-HVF conditions; and
4. leave all other UTM 5.0.4 behavior unchanged.
If that build passes `hvf_accel_init()`, it would directly confirm the explicit IPA-size path as the trigger. Support for explicit 4 KiB/16 KiB granules can then be tested separately and gated by the actual iOS/XNU capability.
It may also be useful to log the following before aborting on iOS:
- the `dlsym` result for each private setter;
- the setter return value;
- the final VM-create tuple; and
- the return value from `hv_vm_create`.
## Workarounds
- UTM 4.7.5 can create and start the HVF VM on this device.
- UTM 5.0.4 can avoid this HVF path by disabling Hypervisor and using TCG/JIT, with the expected performance cost.
- Disabling Vulkan alone does **not** fix the crash.
The separate failure encountered later in the Omarchy installation flow under UTM 4.7.5 occurs after guest startup and is outside the scope of this report.
## Crash report availability
All eight original `.ips` reports were copied without deleting them from the device. I have not attached the raw files here because they contain stable device identifiers, application-container UUIDs, and jailbreak-related filesystem paths. Redacted copies can be provided if needed; the incident IDs and binary UUIDs above can be used to correlate them.
Contributor guide
Research direction
Start in QEMU's hvf_accel_init path and compare the iOS CONFIG_HVF_PRIVATE behavior at the linked QEMU IPA-size commit with the UTM 4.7.5 path. Build a diagnostic version with Vulkan disabled that skips the private IPA-size setter and calls hv_vm_create(NULL), then capture the setter and VM-create results. Done means the AArch64 VM passes HVF initialization without aborting, or the failing HV_* result is identified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, ios
- Domain
- mobile-dev, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100