@@ -322,6 +322,267 @@ index 7f589b4146..d311c57cca 100644
322322- -
3233232.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+ =======
325586From c874e68e5a1635326f8a2f52320b8dbe82f6be51 Mon Sep 17 00:00:00 2001
326587From: osy <50960678+osy@users.noreply.github.com>
327588Date: Fri, 30 Dec 2022 20:24:00 -0800
0 commit comments