From 0979d72234b10088cfcd3b3b6bf3614c7ccb6067 Mon Sep 17 00:00:00 2001 From: Ruby Iris Juric Date: Wed, 19 Feb 2025 13:43:43 +1100 Subject: [PATCH 1/6] codegen: Handle JIT memory pages on Apple Silicon macOS on Apple Silicon does not allow memory pages to be marked as RWX. Instead, to achieve the same behaviour, pages be allocated with the MAP_JIT flag, and the permissions are dynamically switched between RW and RX using the pthread_jit_write_protect function.[1] Most of this commit is derived from upstream work in [2], with changes as necessary to apply onto this older tree. [1]: https://developer.apple.com/documentation/apple-silicon/porting-just-in-time-compilers-to-apple-silicon [2]: https://gitlab.com/qemu-project/qemu/-/commit/653b87eb36045b506b79f0bb433016ef1c54bc9a Signed-off-by: Ruby Iris Juric --- cpu-exec.c | 1 + include/exec/exec-all.h | 1 + include/qemu/osdep.h | 23 +++++++++++++++++++++++ tcg/tcg.c | 1 + translate-all.c | 13 +++++++++++++ 5 files changed, 39 insertions(+) diff --git a/cpu-exec.c b/cpu-exec.c index c88d0ffdcdb..ce312388337 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -154,6 +154,7 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr) #endif /* DEBUG_DISAS */ cpu->can_do_io = !use_icount; + qemu_thread_jit_execute(); next_tb = tcg_qemu_tb_exec(env, tb_ptr); cpu->can_do_io = 1; trace_exec_tb_exit((void *) (next_tb & ~TB_EXIT_MASK), diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index d900b0d078b..23b510967dc 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -324,6 +324,7 @@ static inline void tb_add_jump(TranslationBlock *tb, int n, { /* NOTE: this test is only needed for thread safety */ if (!tb->jmp_next[n]) { + qemu_thread_jit_write(); /* patch the native jump address */ tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr); diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index 84e84ac700c..80785c7d547 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -69,6 +69,11 @@ #include "sysemu/os-posix.h" #endif +#ifdef CONFIG_DARWIN +#include +#include +#endif + #include "qapi/error.h" #if defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10 @@ -315,4 +320,22 @@ int qemu_read_password(char *buf, int buf_size); */ pid_t qemu_fork(Error **errp); +#if defined(CONFIG_DARWIN) && defined(__aarch64__) +static inline void qemu_thread_jit_execute(void) +{ + if (__builtin_available(macOS 11.0, *)) { + pthread_jit_write_protect_np(true); + } +} +static inline void qemu_thread_jit_write(void) +{ + if (__builtin_available(macOS 11.0, *)) { + pthread_jit_write_protect_np(false); + } +} +#else +static inline void qemu_thread_jit_execute(void) {} +static inline void qemu_thread_jit_write(void) {} +#endif + #endif diff --git a/tcg/tcg.c b/tcg/tcg.c index a163541d3c1..dfed92a99e7 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -373,6 +373,7 @@ void tcg_prologue_init(TCGContext *s) s->code_gen_prologue = buf0; /* Generate the prologue. */ + qemu_thread_jit_write(); tcg_target_qemu_prologue(s); buf1 = s->code_ptr; flush_icache_range((uintptr_t)buf0, (uintptr_t)buf1); diff --git a/translate-all.c b/translate-all.c index 042a8576ac5..6f8172d1525 100644 --- a/translate-all.c +++ b/translate-all.c @@ -672,6 +672,13 @@ static inline void *alloc_code_gen_buffer(void) # endif # endif +#if defined(CONFIG_DARWIN) && defined(__aarch64__) + // A change to mprotect in macOS 11.2 on Apple Silicon prevents the call from working on + // regions without the MAP_JIT flag. There's also some manual switching required between + // RW and RX perms needed - see calls to qemu_thread_jit_(write|execute). + flags |= MAP_JIT; +#endif + buf = mmap((void *)start, size + qemu_real_host_page_size, PROT_NONE, flags, -1, 0); if (buf == MAP_FAILED) { @@ -975,6 +982,8 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr) tb_page_addr_t phys_pc; TranslationBlock *tb1, *tb2; + qemu_thread_jit_write(); + /* remove the TB from the hash list */ phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK); h = tb_phys_hash_func(phys_pc); @@ -1022,6 +1031,8 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr) tb->jmp_first = (TranslationBlock *)((uintptr_t)tb | 2); /* fail safe */ tcg_ctx.tb_ctx.tb_phys_invalidate_count++; + + qemu_thread_jit_execute(); } static void build_page_bitmap(PageDesc *p) @@ -1068,6 +1079,8 @@ TranslationBlock *tb_gen_code(CPUState *cpu, int64_t ti; #endif + qemu_thread_jit_write(); + phys_pc = get_page_addr_code(env, pc); if (use_icount && !(cflags & CF_IGNORE_ICOUNT)) { cflags |= CF_USE_ICOUNT; From 745fb61f6602a821f37f30e21042b92670c7b9b3 Mon Sep 17 00:00:00 2001 From: Ruby Iris Juric Date: Wed, 19 Feb 2025 14:25:31 +1100 Subject: [PATCH 2/6] memfd: Update includes for memfd_create At some point, sys/memfd.h was removed from most systems.[1] Instead, the definitions we need from it can now be found in sys/mman.h. [1]: https://stackoverflow.com/questions/56615488/getting-gcc-error-sys-memfd-h-no-such-file-or-directory Signed-off-by: Ruby Iris Juric --- configure | 2 +- util/memfd.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 8420de7f441..1254b23edd2 100755 --- a/configure +++ b/configure @@ -3615,7 +3615,7 @@ fi # check if memfd is supported memfd=no cat > $TMPC << EOF -#include +#include int main(void) { diff --git a/util/memfd.c b/util/memfd.c index 7c406914c59..3636f0d9fd4 100644 --- a/util/memfd.c +++ b/util/memfd.c @@ -34,9 +34,7 @@ #include "qemu/memfd.h" -#ifdef CONFIG_MEMFD -#include -#elif defined CONFIG_LINUX +#if defined CONFIG_LINUX && !defined CONFIG_MEMFD #include #include From cf43996fc5b5a1a8efe43117584c249448fc8217 Mon Sep 17 00:00:00 2001 From: Ruby Iris Juric Date: Wed, 19 Feb 2025 14:28:24 +1100 Subject: [PATCH 3/6] hw/arm/stm32: Add missing includes Without these includes, the build fails on some systems due to missing declarations for qemu_system_reset_request, which live in sysemu/sysemu.h. Signed-off-by: Ruby Iris Juric --- hw/arm/stm32f2xx.c | 1 + hw/arm/stm32f4xx.c | 1 + hw/arm/stm32f7xx.c | 1 + 3 files changed, 3 insertions(+) diff --git a/hw/arm/stm32f2xx.c b/hw/arm/stm32f2xx.c index d8397d95495..2d43fd28829 100644 --- a/hw/arm/stm32f2xx.c +++ b/hw/arm/stm32f2xx.c @@ -26,6 +26,7 @@ #include "hw/ssi.h" #include "hw/block/flash.h" #include "sysemu/blockdev.h" // drive_get +#include "sysemu/sysemu.h" static const char *stm32f2xx_periph_name_arr[] = { ENUM_STRING(STM32_UART1), diff --git a/hw/arm/stm32f4xx.c b/hw/arm/stm32f4xx.c index 711cc7c8818..28ca9ed5d3b 100644 --- a/hw/arm/stm32f4xx.c +++ b/hw/arm/stm32f4xx.c @@ -26,6 +26,7 @@ #include "hw/ssi.h" #include "hw/block/flash.h" #include "sysemu/blockdev.h" // drive_get +#include "sysemu/sysemu.h" static const char *stm32f4xx_periph_name_arr[] = { ENUM_STRING(STM32_UART1), diff --git a/hw/arm/stm32f7xx.c b/hw/arm/stm32f7xx.c index 5e5ccc8fbf8..adf68ad04ea 100644 --- a/hw/arm/stm32f7xx.c +++ b/hw/arm/stm32f7xx.c @@ -28,6 +28,7 @@ #include "hw/ssi.h" #include "hw/block/flash.h" #include "sysemu/blockdev.h" // drive_get +#include "sysemu/sysemu.h" static const char *stm32f7xx_periph_name_arr[] = { ENUM_STRING(STM32_UART1), From bd902a9daaedb87e22fc6dda5537615ead595cda Mon Sep 17 00:00:00 2001 From: Ruby Iris Juric Date: Wed, 19 Feb 2025 14:32:17 +1100 Subject: [PATCH 4/6] qga: Update includes for major Similarly to 745fb61, it seems some definitions may have been moved around in the C stdlib, and accessing major requires explicitly including sys/sysmacros.h. Signed-off-by: Ruby Iris Juric --- qga/commands-posix.c | 1 + 1 file changed, 1 insertion(+) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index c2ff97021ff..fb8cd375b90 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -45,6 +45,7 @@ extern char **environ; #include #include #include +#include #include #ifdef FIFREEZE From 0907fedff1d71a74cb705d1b8580056e2405df16 Mon Sep 17 00:00:00 2001 From: Ruby Iris Juric Date: Wed, 19 Feb 2025 14:40:38 +1100 Subject: [PATCH 5/6] version: Rename VERSION file to prevent header name collisions Somewhere in the macOS build, there's an #include for . Because the root source directory is added to the include path during build, that include picks up this VERSION file, which makes the build fail since it doesn't contain valid C code. Renaming the file to prevent the name collision allows the build to proceed as normal. Signed-off-by: Ruby Iris Juric --- VERSION => QEMU_VERSION | 0 configure | 10 +++++----- 2 files changed, 5 insertions(+), 5 deletions(-) rename VERSION => QEMU_VERSION (100%) diff --git a/VERSION b/QEMU_VERSION similarity index 100% rename from VERSION rename to QEMU_VERSION diff --git a/configure b/configure index 1254b23edd2..bf1a2406b4a 100755 --- a/configure +++ b/configure @@ -753,7 +753,7 @@ for opt do case "$opt" in --help|-h) show_help=yes ;; - --version|-V) exec cat $source_path/VERSION + --version|-V) exec cat $source_path/QEMU_VERSION ;; --prefix=*) prefix="$optarg" ;; @@ -1413,7 +1413,7 @@ fi # Consult white-list to determine whether to enable werror # by default. Only enable by default for git builds -z_version=`cut -f3 -d. $source_path/VERSION` +z_version=`cut -f3 -d. $source_path/QEMU_VERSION` if test -z "$werror" ; then if test -d "$source_path/.git" -a \ @@ -4647,7 +4647,7 @@ if test "$guest_agent_msi" = "yes"; then fi if test "$QEMU_GA_VERSION" = ""; then - QEMU_GA_VERSION=`cat $source_path/VERSION` + QEMU_GA_VERSION=`cat $source_path/QEMU_VERSION` fi QEMU_GA_MSI_MINGW_DLL_PATH="-D Mingw_dlls=`$pkg_config --variable=prefix glib-2.0`/bin" @@ -4900,7 +4900,7 @@ if test "$bigendian" = "yes" ; then fi if test "$mingw32" = "yes" ; then echo "CONFIG_WIN32=y" >> $config_host_mak - rc_version=`cat $source_path/VERSION` + rc_version=`cat $source_path/QEMU_VERSION` version_major=${rc_version%%.*} rc_version=${rc_version#*.} version_minor=${rc_version%%.*} @@ -5008,7 +5008,7 @@ fi if test "$xfs" = "yes" ; then echo "CONFIG_XFS=y" >> $config_host_mak fi -qemu_version=`head $source_path/VERSION` +qemu_version=`head $source_path/QEMU_VERSION` echo "VERSION=$qemu_version" >>$config_host_mak echo "PKGVERSION=$pkgversion" >>$config_host_mak echo "SRC_PATH=$source_path" >> $config_host_mak From 6b5da588ebc6321f87fdf563cb0ea97a1085a940 Mon Sep 17 00:00:00 2001 From: Ruby Iris Juric Date: Wed, 19 Feb 2025 15:29:56 +1100 Subject: [PATCH 6/6] submodule: Update URLs All of the old submodules are currently dead, either because of dropping support for the old git:// scheme (like GitHub), or because the repos have been moved to a new location. Signed-off-by: Ruby Iris Juric --- .gitmodules | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.gitmodules b/.gitmodules index 9da9ede2616..2ef424e862c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,33 +1,33 @@ [submodule "roms/vgabios"] path = roms/vgabios - url = git://git.qemu-project.org/vgabios.git/ + url = https://gitlab.com/qemu-project/vgabios.git [submodule "roms/seabios"] path = roms/seabios - url = git://git.qemu-project.org/seabios.git/ + url = https://gitlab.com/qemu-project/seabios.git [submodule "roms/SLOF"] path = roms/SLOF - url = git://git.qemu-project.org/SLOF.git + url = https://gitlab.com/qemu-project/SLOF.git [submodule "roms/ipxe"] path = roms/ipxe - url = git://git.qemu-project.org/ipxe.git + url = https://gitlab.com/qemu-project/ipxe.git [submodule "roms/openbios"] path = roms/openbios - url = git://git.qemu-project.org/openbios.git + url = https://gitlab.com/qemu-project/openbios.git [submodule "roms/openhackware"] path = roms/openhackware - url = git://git.qemu-project.org/openhackware.git + url = https://gitlab.com/qemu-project/openhackware.git [submodule "roms/qemu-palcode"] path = roms/qemu-palcode - url = git://github.com/rth7680/qemu-palcode.git + url = https://github.com/rth7680/qemu-palcode.git [submodule "roms/sgabios"] path = roms/sgabios - url = git://git.qemu-project.org/sgabios.git + url = https://gitlab.com/qemu-project/sgabios.git [submodule "pixman"] path = pixman - url = git://anongit.freedesktop.org/pixman + url = https://gitlab.freedesktop.org/pixman/pixman.git [submodule "dtc"] path = dtc - url = git://git.qemu-project.org/dtc.git + url = https://gitlab.com/qemu-project/dtc.git [submodule "roms/u-boot"] path = roms/u-boot - url = git://git.qemu-project.org/u-boot.git + url = https://gitlab.com/qemu-project/u-boot.git