From: Mohamed Mediouni <mohamed@unpredictable.fr>
To: qemu-devel@nongnu.org
Cc: qemu-arm@nongnu.org, Phil Dennis-Jordan <phil@philjordan.eu>,
Alexander Graf <agraf@csgraf.de>,
Roman Bolshakov <rbolshakov@ddn.com>,
Peter Maydell <peter.maydell@linaro.org>,
Mohamed Mediouni <mohamed@unpredictable.fr>
Subject: [PATCH 2/3] hvf: arm: add experimental VHE toggle
Date: Thu, 3 Sep 2026 06:01:56 +0200 [thread overview]
Message-ID: <20260903040157.74627-3-mohamed@unpredictable.fr> (raw)
In-Reply-To: <20260903040157.74627-1-mohamed@unpredictable.fr>
macOS 27.0 ships with an experimental VHE enablement
private API. Expose support for it as x-vhe.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
---
accel/hvf/hvf-all.c | 2 +
include/system/hvf_int.h | 1 +
target/arm/hvf/hvf.c | 89 ++++++++++++++++++++++++++++++++++++++++
target/i386/hvf/hvf.c | 4 ++
4 files changed, 96 insertions(+)
diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c
index 8bd9154a50..bbff3c6867 100644
--- a/accel/hvf/hvf-all.c
+++ b/accel/hvf/hvf-all.c
@@ -282,6 +282,8 @@ static void hvf_accel_class_init(ObjectClass *oc, const void *data)
NULL, NULL);
object_class_property_set_description(oc, "kernel-irqchip",
"Configure HVF irqchip");
+
+ hvf_arch_accel_class_init(oc);
}
static const TypeInfo hvf_accel_type = {
diff --git a/include/system/hvf_int.h b/include/system/hvf_int.h
index a01691ce17..44ae2e7c4c 100644
--- a/include/system/hvf_int.h
+++ b/include/system/hvf_int.h
@@ -110,5 +110,6 @@ int hvf_update_guest_debug(CPUState *cpu);
bool hvf_arch_cpu_realize(CPUState *cpu, Error **errp);
uint32_t hvf_arch_get_default_ipa_bit_size(void);
uint32_t hvf_arch_get_max_ipa_bit_size(void);
+void hvf_arch_accel_class_init(ObjectClass *oc);
#endif
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index f881d6cc67..b61554e108 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -22,6 +22,7 @@
#include "cpu-sysregs.h"
#include <mach/mach_time.h>
+#include <dlfcn.h>
#include "system/address-spaces.h"
#include "system/memory.h"
@@ -39,6 +40,7 @@
#include "target/arm/trace.h"
#include "trace.h"
#include "migration/vmstate.h"
+#include "migration/blocker.h"
#include "gdbstub/enums.h"
@@ -1132,6 +1134,60 @@ static void clamp_id_aa64mmfr0_parange_to_ipa_size(ARMISARegisters *isar)
SET_IDREG(isar, ID_AA64MMFR0, id_aa64mmfr0);
}
+bool hvf_vhe;
+
+static void hvf_set_vhe(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ OnOffAuto mode;
+
+ if (!visit_type_OnOffAuto(v, name, &mode, errp)) {
+ return;
+ }
+
+ switch (mode) {
+ case ON_OFF_AUTO_ON:
+ if (__builtin_available(macOS 27.0, *)) {
+ hvf_vhe = true;
+ } else {
+ error_report("VHE emulation not supported on this system.");
+ }
+ break;
+
+ case ON_OFF_AUTO_OFF:
+ hvf_vhe = false;
+ break;
+
+ case ON_OFF_AUTO_AUTO:
+ /* Experimental feature as of macOS 27.0 */
+ hvf_vhe = false;
+ break;
+ default:
+ /*
+ * The value was checked in visit_type_OnOffAuto() above. If
+ * we get here, then something is wrong in QEMU.
+ */
+ abort();
+ }
+}
+
+static bool hvf_get_vhe(void)
+{
+ return hvf_vhe;
+}
+
+void hvf_arch_accel_class_init(ObjectClass *oc)
+{
+ hvf_vhe = false;
+
+ object_class_property_add(oc, "x-vhe", "OnOffAuto",
+ NULL, hvf_set_vhe,
+ NULL, NULL);
+ object_class_property_set_description(oc, "x-vhe",
+ "Configure experimental VHE enablement");
+}
+
static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
{
ARMISARegisters host_isar = {};
@@ -1227,6 +1283,9 @@ static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
if (hvf_nested_virt_enabled()) {
/* SME is not implemented with nested virt on the Apple side */
FIELD_DP64_IDREG(&host_isar, ID_AA64PFR1, SME, 0);
+ if (hvf_get_vhe()) {
+ FIELD_DP64_IDREG(&host_isar, ID_AA64MMFR1, VH, 0x1);
+ }
}
/*
@@ -1357,6 +1416,36 @@ hv_return_t hvf_arch_vm_create(MachineState *ms, uint32_t pa_range)
}
}
+ if (hvf_get_vhe()) {
+ Error *vhe_migration_blocker = NULL;
+ Error* errp;
+
+ void* hvf = dlopen("/System/Library/Frameworks/Hypervisor.framework/Versions/A/Hypervisor", RTLD_LOCAL);
+
+ if (!hvf) {
+ /* Unreachable. */
+ error_report("Failed to dlopen() Hypervisor.framework.");
+ goto cleanup;
+ }
+
+ /* Experimental API: might change before release. */
+ hv_return_t (*_hv_vm_config_set_vhe_enabled)(hv_vm_config_t cfg, bool vhe) = dlsym(hvf, "_hv_vm_config_set_vhe_enabled");
+ if (!_hv_vm_config_set_vhe_enabled) {
+ error_report("_hv_vm_config_set_vhe_enabled API not available.");
+ goto cleanup;
+ }
+ _hv_vm_config_set_vhe_enabled(config, true);
+
+ error_setg(&vhe_migration_blocker,
+ "Live migration disabled because VHE support is experimental");
+ if (migrate_add_blocker(&vhe_migration_blocker, &errp)) {
+ error_report("Failed to add migration blocker.");
+ goto cleanup;
+ }
+
+ dlclose(hvf);
+ }
+
ret = hv_vm_create(config);
if (hvf_irqchip_in_kernel()) {
if (__builtin_available(macOS 15.0, *)) {
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 150598418e..5a39a82492 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -1068,3 +1068,7 @@ void hvf_arch_remove_all_gdbstub_hw_breakpoints(void)
void hvf_arch_update_guest_debug(CPUState *cpu)
{
}
+
+void hvf_arch_accel_class_init(ObjectClass *oc)
+{
+}
--
2.54.0 (Apple Git-156)
next prev parent reply other threads:[~2026-09-03 4:02 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-03 4:01 [PATCH 0/3] hvf: arm: add experimental VHE (x-vhe) toggle Mohamed Mediouni
2026-09-03 4:01 ` [PATCH 1/3] hvf: arm: advertise ID_AA64PFR0_EL1.GIC Mohamed Mediouni
2026-09-03 4:01 ` Mohamed Mediouni [this message]
2026-09-03 4:01 ` [PATCH 3/3] hvf: arm: advertise EL3 support when VHE is on Mohamed Mediouni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260903040157.74627-3-mohamed@unpredictable.fr \
--to=mohamed@unpredictable.fr \
--cc=agraf@csgraf.de \
--cc=peter.maydell@linaro.org \
--cc=phil@philjordan.eu \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=rbolshakov@ddn.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox