Read the ipa-granule property (set by hvf_accel_init) and configure
the HVF stage-2 translation granule via hv_vm_config_set_ipa_granule()
on macOS 26+. When ipa-granule=4k, use HV_IPA_GRANULE_4KB to allow
HVF to map memory at 4KB granularity, matching 4KB-page guests on
hosts with larger page sizes.
If macOS < 26 and a sub-host-page granule was requested, warn and
fall back to the host page size.
Signed-off-by: Lucas Amaral <lucaaamaral@gmail.com>
---
target/arm/hvf/hvf.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 1ba5bbf3..e3b1e3e1 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -1269,6 +1269,38 @@ hv_return_t hvf_arch_vm_create(MachineState *ms, uint32_t pa_range)
}
chosen_ipa_bit_size = pa_range;
+ /*
+ * Configure IPA granule from the ipa-granule property.
+ * hvf_get_map_granule() was set by hvf_accel_init() before this call.
+ */
+ {
+ uint64_t granule = hvf_get_map_granule();
+ bool granule_set = false;
+
+#if defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
+ (__MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_26_0)
+ if (__builtin_available(macOS 26, *)) {
+ hv_ipa_granule_t hv_gran = (granule <= 4 * KiB)
+ ? HV_IPA_GRANULE_4KB : HV_IPA_GRANULE_16KB;
+ ret = hv_vm_config_set_ipa_granule(config, hv_gran);
+ if (ret != HV_SUCCESS) {
+ error_report("HVF: failed to set IPA granule: %s",
+ hvf_return_string(ret));
+ goto cleanup;
+ }
+ granule_set = true;
+ }
+#endif
+
+ if (!granule_set && granule < qemu_real_host_page_size()) {
+ warn_report("HVF: ipa-granule=%zuKB requested but macOS < 26; "
+ "falling back to host page size (%zuKB)",
+ (size_t)(granule / KiB),
+ (size_t)(qemu_real_host_page_size() / KiB));
+ hvf_set_map_granule(qemu_real_host_page_size());
+ }
+ }
+
ret = hv_vm_create(config);
cleanup:
--
2.52.0