|
@@ -27,6 +27,9 @@
|
|
#include "disas/disas.h"
|
|
#include "disas/disas.h"
|
|
#include "exec/exec-all.h"
|
|
#include "exec/exec-all.h"
|
|
#include "tcg/tcg.h"
|
|
#include "tcg/tcg.h"
|
|
|
|
+#if defined(CONFIG_DARWIN)
|
|
|
|
+#include "tcg/tcg-apple-jit.h"
|
|
|
|
+#endif
|
|
#if defined(CONFIG_USER_ONLY)
|
|
#if defined(CONFIG_USER_ONLY)
|
|
#include "qemu.h"
|
|
#include "qemu.h"
|
|
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
|
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
|
@@ -76,6 +79,9 @@ extern kern_return_t mach_vm_remap(vm_map_t target_task,
|
|
);
|
|
);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+static bool tb_exec_is_locked(void);
|
|
|
|
+static void tb_exec_change(bool locked);
|
|
|
|
+
|
|
/* #define DEBUG_TB_INVALIDATE */
|
|
/* #define DEBUG_TB_INVALIDATE */
|
|
/* #define DEBUG_TB_FLUSH */
|
|
/* #define DEBUG_TB_FLUSH */
|
|
/* make various TB consistency checks */
|
|
/* make various TB consistency checks */
|
|
@@ -1245,6 +1251,7 @@ void tcg_exec_init(unsigned long tb_size, bool mirror_rwx)
|
|
page_init();
|
|
page_init();
|
|
tb_htable_init();
|
|
tb_htable_init();
|
|
code_gen_alloc(tb_size, mirror_rwx);
|
|
code_gen_alloc(tb_size, mirror_rwx);
|
|
|
|
+ tb_exec_unlock();
|
|
#if defined(CONFIG_SOFTMMU)
|
|
#if defined(CONFIG_SOFTMMU)
|
|
/* There's no guest base to take into account, so go ahead and
|
|
/* There's no guest base to take into account, so go ahead and
|
|
initialize the prologue now. */
|
|
initialize the prologue now. */
|
|
@@ -1521,8 +1528,11 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
|
|
PageDesc *p;
|
|
PageDesc *p;
|
|
uint32_t h;
|
|
uint32_t h;
|
|
tb_page_addr_t phys_pc;
|
|
tb_page_addr_t phys_pc;
|
|
|
|
+ bool code_gen_locked;
|
|
|
|
|
|
assert_memory_lock();
|
|
assert_memory_lock();
|
|
|
|
+ code_gen_locked = tb_exec_is_locked();
|
|
|
|
+ tb_exec_unlock();
|
|
|
|
|
|
/* make sure no further incoming jumps will be chained to this TB */
|
|
/* make sure no further incoming jumps will be chained to this TB */
|
|
qemu_spin_lock(&tb->jmp_lock);
|
|
qemu_spin_lock(&tb->jmp_lock);
|
|
@@ -1535,6 +1545,7 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
|
|
tb->trace_vcpu_dstate);
|
|
tb->trace_vcpu_dstate);
|
|
if (!(tb->cflags & CF_NOCACHE) &&
|
|
if (!(tb->cflags & CF_NOCACHE) &&
|
|
!qht_remove(&tb_ctx.htable, tb, h)) {
|
|
!qht_remove(&tb_ctx.htable, tb, h)) {
|
|
|
|
+ tb_exec_change(code_gen_locked);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1567,6 +1578,8 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
|
|
|
|
|
|
qatomic_set(&tcg_ctx->tb_phys_invalidate_count,
|
|
qatomic_set(&tcg_ctx->tb_phys_invalidate_count,
|
|
tcg_ctx->tb_phys_invalidate_count + 1);
|
|
tcg_ctx->tb_phys_invalidate_count + 1);
|
|
|
|
+
|
|
|
|
+ tb_exec_change(code_gen_locked);
|
|
}
|
|
}
|
|
|
|
|
|
static void tb_phys_invalidate__locked(TranslationBlock *tb)
|
|
static void tb_phys_invalidate__locked(TranslationBlock *tb)
|
|
@@ -2807,3 +2820,41 @@ void tcg_flush_softmmu_tlb(CPUState *cs)
|
|
tlb_flush(cs);
|
|
tlb_flush(cs);
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+#if defined(CONFIG_DARWIN) && !defined(CONFIG_TCG_INTERPRETER)
|
|
|
|
+static bool tb_exec_is_locked(void)
|
|
|
|
+{
|
|
|
|
+ return tcg_ctx->code_gen_locked;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void tb_exec_change(bool locked)
|
|
|
|
+{
|
|
|
|
+#if defined(HAVE_PTHREAD_JIT_PROTECT)
|
|
|
|
+ if (__builtin_available(macOS 11, iOS 14, watchOS 7, tvOS 14, *)) {
|
|
|
|
+ pthread_jit_write_protect_np(locked);
|
|
|
|
+ } else
|
|
|
|
+#endif
|
|
|
|
+ if (jit_write_protect_supported()) {
|
|
|
|
+ jit_write_protect(locked);
|
|
|
|
+ }
|
|
|
|
+ tcg_ctx->code_gen_locked = locked;
|
|
|
|
+}
|
|
|
|
+#else /* not needed on non-Darwin platforms */
|
|
|
|
+static bool tb_exec_is_locked(void)
|
|
|
|
+{
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void tb_exec_change(bool locked) {}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+void tb_exec_lock(void)
|
|
|
|
+{
|
|
|
|
+ /* assumes sys_icache_invalidate already called */
|
|
|
|
+ tb_exec_change(true);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void tb_exec_unlock(void)
|
|
|
|
+{
|
|
|
|
+ tb_exec_change(false);
|
|
|
|
+}
|