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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.