From 445d0a85ab75e06e36980f48b9d8c8065ea25d36 Mon Sep 17 00:00:00 2001 From: Liam McLoughlin Date: Thu, 13 Feb 2025 17:54:00 +0000 Subject: [PATCH 1/5] Changes to avoid JIT related crash on Apple Silicon Mostly adapted from https://gitlab.com/qemu-project/qemu/-/commit/653b87eb36045b506b79f0bb433016ef1c54bc9a. Signed-off-by: Liam McLoughlin --- 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 f4c95bf552bd346fe96f921a6dc350fffdda869c Mon Sep 17 00:00:00 2001 From: Liam McLoughlin Date: Thu, 13 Feb 2025 17:54:52 +0000 Subject: [PATCH 2/5] Fix duplicate memfd declaration Recent glibc added memfd_create in sys/mman.h. This conflicts with the definition in util/memfd.c: /builddir/build/BUILD/qemu-2.11.0-rc1/util/memfd.c:40:12: error: static declaration of memfd_create follows non-static declaration Fix the configure test, and remove the sys/memfd.h inclusion since the file actually does not exist---it is a typo in the memfd_create(2) man page. Signed-off-by: Liam McLoughlin --- 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 90c16074ff0326ad914dad3bdce23e9b7cccbf93 Mon Sep 17 00:00:00 2001 From: Liam McLoughlin Date: Thu, 13 Feb 2025 17:55:25 +0000 Subject: [PATCH 3/5] Add missing stm32 includes --- 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 0a4445a4b569f543cf0deea902bd11029ecf152e Mon Sep 17 00:00:00 2001 From: Liam McLoughlin Date: Thu, 13 Feb 2025 17:55:51 +0000 Subject: [PATCH 4/5] Rename VERSION to QEMU_VERSION to avoid it breaking the build Otherwise, it gets picked up as a header file. --- VERSION | 1 - configure | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 VERSION diff --git a/VERSION b/VERSION deleted file mode 100644 index 1bfdf8c235e..00000000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -2.5.0-pebble4 \ No newline at end of file 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 a7d64aa2a4fc5595cfe9b90299a636b17a3d50d1 Mon Sep 17 00:00:00 2001 From: Liam McLoughlin Date: Thu, 13 Feb 2025 17:57:53 +0000 Subject: [PATCH 5/5] Update DTC submodule URL --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 9da9ede2616..a52307c3c9b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -27,7 +27,7 @@ url = git://anongit.freedesktop.org/pixman [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