Skip to content

Commit 31fee3d

Browse files
authored
Merge pull request #4866 from utmapp/feature/ios-rosetta
Add TSO support for jailbroken/Trollstore iOS Hypervisor
2 parents 811f27a + 305cfd5 commit 31fee3d

7 files changed

Lines changed: 292 additions & 3 deletions

File tree

Configuration/QEMUConstant.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,15 @@ extension QEMUArchitecture {
428428
return false
429429
#endif
430430
}
431+
432+
/// TSO is supported on jailbroken iOS devices with Hypervisor support
433+
var hasTSOSupport: Bool {
434+
#if os(iOS)
435+
return hasHypervisorSupport
436+
#else
437+
return false
438+
#endif
439+
}
431440
}
432441

433442
extension QEMUTarget {

Configuration/UTMQemuConfiguration+Arguments.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,10 @@ import Foundation
273273
system.architecture.hasHypervisorSupport && qemu.hasHypervisor
274274
}
275275

276+
private var isTSOUsed: Bool {
277+
system.architecture.hasTSOSupport && qemu.hasTSO
278+
}
279+
276280
private var isUsbUsed: Bool {
277281
system.architecture.hasUsbSupport && system.target.hasUsbSupport && input.usbBusSupport != .disabled
278282
}
@@ -283,7 +287,11 @@ import Foundation
283287
f(machineProperties)
284288
if isHypervisorUsed {
285289
f("-accel")
286-
f("hvf")
290+
"hvf"
291+
if isTSOUsed {
292+
"tso=on"
293+
}
294+
f()
287295
} else {
288296
f("-accel")
289297
"tcg"

Configuration/UTMQemuConfigurationQEMU.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ struct UTMQemuConfigurationQEMU: Codable {
4242
/// If true, use HVF hypervisor instead of TCG emulation.
4343
var hasHypervisor: Bool = false
4444

45+
/// If true, enable total store ordering.
46+
var hasTSO: Bool = false
47+
4548
/// If true, attempt to sync RTC with the local time.
4649
var hasRTCLocalTime: Bool = false
4750

Platform/Shared/VMConfigQEMUView.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ struct VMConfigQEMUView: View {
8282
#endif
8383
Toggle("Use Hypervisor", isOn: $config.hasHypervisor)
8484
.help("Only available if host architecture matches the target. Otherwise, TCG emulation is used.")
85+
.disabled(!system.architecture.hasHypervisorSupport)
86+
#if os(iOS)
87+
if config.hasHypervisor {
88+
Toggle("Use TSO", isOn: $config.hasTSO)
89+
.help("Only available when Hypervisor is used on supported hardware. TSO speeds up Intel emulation in the guest at the cost of decreased performance in general.")
90+
.disabled(!system.architecture.hasTSOSupport)
91+
}
92+
#endif
8593
Toggle("Use local time for base clock", isOn: $config.hasRTCLocalTime)
8694
.help("If checked, use local time for RTC which is required for Windows. Otherwise, use UTC clock.")
8795
Toggle("Force PS/2 controller", isOn: $config.hasPS2Controller)

patches/qemu-7.2.0-utm.patch

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,267 @@ index 7f589b4146..d311c57cca 100644
322322
--
323323
2.28.0
324324

325+
From 531da34587b38c64787cb25b1de1c5d13f75def8 Mon Sep 17 00:00:00 2001
326+
From: osy <50960678+osy@users.noreply.github.com>
327+
Date: Wed, 28 Dec 2022 16:50:49 -0800
328+
Subject: [PATCH] hvf: support TSO mode (private feature)
329+
330+
Apple Silicon supports TSO mode which can be used for emulating strong
331+
memory ordering in the guest. This feature requires the private entitlement
332+
`com.apple.private.hypervisor` as well as a private function to modify
333+
ACTLR_EL1 not exposed by the public Hypervisor framework.
334+
---
335+
accel/hvf/hvf-accel-ops.c | 51 ++++++++++++++++++++++++++---------
336+
include/sysemu/hvf_int.h | 13 +++++++++
337+
meson.build | 1 +
338+
meson_options.txt | 2 ++
339+
scripts/meson-buildoptions.sh | 3 +++
340+
target/arm/hvf/hvf.c | 28 +++++++++++++++++++
341+
target/i386/hvf/hvf.c | 5 ++++
342+
7 files changed, 90 insertions(+), 13 deletions(-)
343+
344+
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
345+
index 24913ca9c4..b414e240ec 100644
346+
--- a/accel/hvf/hvf-accel-ops.c
347+
+++ b/accel/hvf/hvf-accel-ops.c
348+
@@ -57,13 +57,10 @@
349+
#include "sysemu/hvf_int.h"
350+
#include "sysemu/runstate.h"
351+
#include "qemu/guest-random.h"
352+
+#include "hw/boards.h"
353+
354+
HVFState *hvf_state;
355+
356+
-#ifdef __aarch64__
357+
-#define HV_VM_DEFAULT NULL
358+
-#endif
359+
-
360+
/* Memory slots */
361+
362+
hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
363+
@@ -319,25 +316,44 @@ bool hvf_allowed;
364+
365+
static int hvf_accel_init(MachineState *ms)
366+
{
367+
- int x;
368+
hv_return_t ret;
369+
- HVFState *s;
370+
+ HVFState *s = HVF_STATE(ms->accelerator);
371+
372+
- ret = hv_vm_create(HV_VM_DEFAULT);
373+
+ ret = hvf_arch_vm_create(s);
374+
assert_hvf_ok(ret);
375+
376+
- s = g_new0(HVFState, 1);
377+
+ hvf_state = s;
378+
+ memory_listener_register(&hvf_memory_listener, &address_space_memory);
379+
+
380+
+ return hvf_arch_init();
381+
+}
382+
+
383+
+#if defined(CONFIG_HVF_PRIVATE) && defined(__aarch64__)
384+
+
385+
+static bool hvf_get_tso(Object *obj, Error **errp)
386+
+{
387+
+ HVFState *s = HVF_STATE(obj);
388+
+ return s->tso_mode;
389+
+}
390+
+
391+
+static void hvf_set_tso(Object *obj, bool value, Error **errp)
392+
+{
393+
+ HVFState *s = HVF_STATE(obj);
394+
+ s->tso_mode = value;
395+
+}
396+
+
397+
+#endif
398+
+
399+
+static void hvf_accel_instance_init(Object *obj)
400+
+{
401+
+ int x;
402+
+ HVFState *s = HVF_STATE(obj);
403+
404+
s->num_slots = ARRAY_SIZE(s->slots);
405+
for (x = 0; x < s->num_slots; ++x) {
406+
s->slots[x].size = 0;
407+
s->slots[x].slot_id = x;
408+
}
409+
-
410+
- hvf_state = s;
411+
- memory_listener_register(&hvf_memory_listener, &address_space_memory);
412+
-
413+
- return hvf_arch_init();
414+
}
415+
416+
static void hvf_accel_class_init(ObjectClass *oc, void *data)
417+
@@ -346,12 +362,21 @@ static void hvf_accel_class_init(ObjectClass *oc, void *data)
418+
ac->name = "HVF";
419+
ac->init_machine = hvf_accel_init;
420+
ac->allowed = &hvf_allowed;
421+
+
422+
+#if defined(CONFIG_HVF_PRIVATE) && defined(__aarch64__)
423+
+ object_class_property_add_bool(oc, "tso",
424+
+ hvf_get_tso, hvf_set_tso);
425+
+ object_class_property_set_description(oc, "tso",
426+
+ "Set on/off to enable/disable total store ordering mode");
427+
+#endif
428+
}
429+
430+
static const TypeInfo hvf_accel_type = {
431+
.name = TYPE_HVF_ACCEL,
432+
.parent = TYPE_ACCEL,
433+
+ .instance_init = hvf_accel_instance_init,
434+
.class_init = hvf_accel_class_init,
435+
+ .instance_size = sizeof(HVFState),
436+
};
437+
438+
static void hvf_type_init(void)
439+
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
440+
index 6545f7cd61..9f550b9f8b 100644
441+
--- a/include/sysemu/hvf_int.h
442+
+++ b/include/sysemu/hvf_int.h
443+
@@ -17,6 +17,15 @@
444+
#include <Hypervisor/hv.h>
445+
#endif
446+
447+
+#if defined(CONFIG_HVF_PRIVATE) && defined(__aarch64__)
448+
+extern hv_return_t _hv_vm_config_set_isa(hv_vm_config_t config, uint32_t isa);
449+
+extern hv_return_t _hv_vcpu_get_actlr(hv_vcpu_t vcpu, uint64_t* value);
450+
+extern hv_return_t _hv_vcpu_set_actlr(hv_vcpu_t vcpu, uint64_t value);
451+
+
452+
+#define HV_VM_CONFIG_ISA_PRIVATE (3)
453+
+#define ACTLR_EL1_TSO_ENABLE_MASK ((1 << 1) | (1 << 9))
454+
+#endif
455+
+
456+
/* hvf_slot flags */
457+
#define HVF_SLOT_LOG (1 << 0)
458+
459+
@@ -45,6 +54,9 @@ struct HVFState {
460+
461+
hvf_vcpu_caps *hvf_caps;
462+
uint64_t vtimer_offset;
463+
+#if defined(CONFIG_HVF_PRIVATE) && defined(__aarch64__)
464+
+ bool tso_mode;
465+
+#endif
466+
};
467+
extern HVFState *hvf_state;
468+
469+
@@ -56,6 +68,7 @@ struct hvf_vcpu_state {
470+
};
471+
472+
void assert_hvf_ok(hv_return_t ret);
473+
+hv_return_t hvf_arch_vm_create(HVFState *s);
474+
int hvf_arch_init(void);
475+
int hvf_arch_init_vcpu(CPUState *cpu);
476+
void hvf_arch_vcpu_destroy(CPUState *cpu);
477+
diff --git a/meson.build b/meson.build
478+
index 00fccfc676..ab6a60d1a8 100644
479+
--- a/meson.build
480+
+++ b/meson.build
481+
@@ -440,6 +440,7 @@ if get_option('hvf').allowed()
482+
required: get_option('hvf'))
483+
if hvf.found()
484+
accelerators += 'CONFIG_HVF'
485+
+ config_host_data.set('CONFIG_HVF_PRIVATE', get_option('hvf_private'))
486+
endif
487+
endif
488+
if get_option('hax').allowed()
489+
diff --git a/meson_options.txt b/meson_options.txt
490+
index 43916078c8..8415d45071 100644
491+
--- a/meson_options.txt
492+
+++ b/meson_options.txt
493+
@@ -72,6 +72,8 @@ option('whpx', type: 'feature', value: 'auto',
494+
description: 'WHPX acceleration support')
495+
option('hvf', type: 'feature', value: 'auto',
496+
description: 'HVF acceleration support')
497+
+option('hvf_private', type: 'boolean', value: 'false',
498+
+ description: 'HVF private features (entitlements required)')
499+
option('nvmm', type: 'feature', value: 'auto',
500+
description: 'NVMM acceleration support')
501+
option('xen', type: 'feature', value: 'auto',
502+
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
503+
index 2496991056..010515ac98 100644
504+
--- a/scripts/meson-buildoptions.sh
505+
+++ b/scripts/meson-buildoptions.sh
506+
@@ -26,6 +26,7 @@ meson_options_help() {
507+
printf "%s\n" ' --enable-fuzzing build fuzzing targets'
508+
printf "%s\n" ' --enable-gcov Enable coverage tracking.'
509+
printf "%s\n" ' --enable-gprof QEMU profiling with gprof'
510+
+ printf "%s\n" ' --enable-hvf-private HVF private features (entitlements required)'
511+
printf "%s\n" ' --enable-lto Use link time optimization'
512+
printf "%s\n" ' --enable-malloc=CHOICE choose memory allocator to use [system] (choices:'
513+
printf "%s\n" ' jemalloc/system/tcmalloc)'
514+
@@ -289,6 +290,8 @@ _meson_option_parse() {
515+
--disable-hax) printf "%s" -Dhax=disabled ;;
516+
--enable-hvf) printf "%s" -Dhvf=enabled ;;
517+
--disable-hvf) printf "%s" -Dhvf=disabled ;;
518+
+ --enable-hvf-private) printf "%s" -Dhvf_private=true ;;
519+
+ --disable-hvf-private) printf "%s" -Dhvf_private=false ;;
520+
--iasl=*) quote_sh "-Diasl=$2" ;;
521+
--enable-iconv) printf "%s" -Diconv=enabled ;;
522+
--disable-iconv) printf "%s" -Diconv=disabled ;;
523+
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
524+
index 2c0323fe7f..bb7a4d5004 100644
525+
--- a/target/arm/hvf/hvf.c
526+
+++ b/target/arm/hvf/hvf.c
527+
@@ -623,6 +623,18 @@ int hvf_arch_init_vcpu(CPUState *cpu)
528+
&arm_cpu->isar.id_aa64mmfr0);
529+
assert_hvf_ok(ret);
530+
531+
+#if defined(CONFIG_HVF_PRIVATE)
532+
+ /* enable TSO mode */
533+
+ if (hvf_state->tso_mode) {
534+
+ uint64_t actlr;
535+
+ ret = _hv_vcpu_get_actlr(cpu->hvf->fd, &actlr);
536+
+ assert_hvf_ok(ret);
537+
+ actlr |= ACTLR_EL1_TSO_ENABLE_MASK;
538+
+ ret = _hv_vcpu_set_actlr(cpu->hvf->fd, actlr);
539+
+ assert_hvf_ok(ret);
540+
+ }
541+
+#endif
542+
+
543+
return 0;
544+
}
545+
546+
@@ -1343,6 +1355,22 @@ static void hvf_vm_state_change(void *opaque, bool running, RunState state)
547+
}
548+
}
549+
550+
+hv_return_t hvf_arch_vm_create(HVFState *s)
551+
+{
552+
+#if defined(CONFIG_HVF_PRIVATE)
553+
+ hv_return_t ret;
554+
+ hv_vm_config_t config = hv_vm_config_create();
555+
+ if (s->tso_mode) {
556+
+ _hv_vm_config_set_isa(config, HV_VM_CONFIG_ISA_PRIVATE);
557+
+ }
558+
+ ret = hv_vm_create(config);
559+
+ os_release(config);
560+
+ return ret;
561+
+#else
562+
+ return hv_vm_create(NULL);
563+
+#endif
564+
+}
565+
+
566+
int hvf_arch_init(void)
567+
{
568+
hvf_state->vtimer_offset = mach_absolute_time();
569+
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
570+
index 8d2248bb3f..8283a9b761 100644
571+
--- a/target/i386/hvf/hvf.c
572+
+++ b/target/i386/hvf/hvf.c
573+
@@ -212,6 +212,11 @@ void hvf_kick_vcpu_thread(CPUState *cpu)
574+
cpus_kick_thread(cpu);
575+
}
576+
577+
+hv_return_t hvf_arch_vm_create(HVFState *s)
578+
+{
579+
+ return hv_vm_create(HV_VM_DEFAULT);
580+
+}
581+
+
582+
int hvf_arch_init(void)
583+
{
584+
return 0;
585+
=======
325586
From c874e68e5a1635326f8a2f52320b8dbe82f6be51 Mon Sep 17 00:00:00 2001
326587
From: osy <50960678+osy@users.noreply.github.com>
327588
Date: Fri, 30 Dec 2022 20:24:00 -0800

patches/sources

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,4 @@ VIRGLRENDERER_COMMIT="d46413cf4797a33cfbe1c9f14e6d22ce563ef700"
4545

4646
# Decompiled Hypervisor for iOS
4747
HYPERVISOR_REPO="https://github.com/utmapp/Hypervisor.git"
48-
HYPERVISOR_COMMIT="c694e42468d2794b962714cdf76f180125e69f36"
48+
HYPERVISOR_COMMIT="b4eb0e00c03692016944fad3e8e3a6613839912e"

scripts/build_dependencies.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ ios* )
671671
SDK=iphoneos
672672
CFLAGS_MINVER="-miphoneos-version-min=$SDKMINVER"
673673
PLATFORM_FAMILY_PREFIX="iOS"
674-
HVF_FLAGS=""
674+
HVF_FLAGS="--enable-hvf-private"
675675
;;
676676
esac
677677
CFLAGS_TARGET=

0 commit comments

Comments
 (0)