Skip to content

Commit 958ed09

Browse files
committed
No longer need SPRR and probe it runtime
1 parent b719926 commit 958ed09

File tree

4 files changed

+74
-24
lines changed

4 files changed

+74
-24
lines changed

qemu/accel/tcg/translate-all.c

+3-5
Original file line numberDiff line numberDiff line change
@@ -2172,21 +2172,19 @@ void tcg_flush_softmmu_tlb(struct uc_struct *uc)
21722172
}
21732173

21742174

2175-
#if defined(__APPLE__) && defined(HAVE_PTHREAD_JIT_PROTECT) && defined(HAVE_SPRR) && (defined(__arm__) || defined(__aarch64__))
2175+
#if defined(__APPLE__) && defined(HAVE_PTHREAD_JIT_PROTECT) && (defined(__arm__) || defined(__aarch64__))
21762176
static bool tb_exec_is_locked(struct uc_struct *uc)
21772177
{
21782178
return uc->current_executable;
21792179
}
21802180

21812181
static void tb_exec_change(struct uc_struct *uc, bool executable)
21822182
{
2183-
assert(uc->current_executable == thread_executable());
2183+
assert_executable(uc->current_executable);
21842184
if (uc->current_executable != executable) {
21852185
jit_write_protect(executable);
21862186
uc->current_executable = executable;
2187-
assert(
2188-
executable == thread_executable()
2189-
);
2187+
assert_executable(executable);
21902188
}
21912189
}
21922190
#else /* not needed on non-Darwin platforms */

qemu/configure

+6-1
Original file line numberDiff line numberDiff line change
@@ -2155,11 +2155,17 @@ int main() {
21552155
21562156
// In Apple Hypervisor, this value is not accessbile and
21572157
// pthread_jit_write_protect_np essentially is a no-op
2158+
2159+
/*
21582160
if (!commpage_sprr) {
21592161
return 1;
21602162
} else {
21612163
return 0;
21622164
}
2165+
*/
2166+
2167+
// Now it is accessible but always zero, let's probe it runtime.
2168+
return 0;
21632169
}
21642170
EOF
21652171
if ! compile_prog ""; then
@@ -2171,7 +2177,6 @@ EOF
21712177
have_sprr='yes'
21722178
else
21732179
have_sprr='no'
2174-
have_pthread_jit_protect='no'
21752180
fi
21762181
fi
21772182
fi

qemu/include/tcg/tcg-apple-jit.h

+63-15
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@
2525
#ifndef TCG_APPLE_JIT_H
2626
#define TCG_APPLE_JIT_H
2727

28-
#if defined(__APPLE__) && defined(HAVE_PTHREAD_JIT_PROTECT) && defined(HAVE_SPRR) && (defined(__arm__) || defined(__aarch64__))
28+
#include "assert.h"
29+
#include "stdint.h"
30+
#include "stdlib.h"
31+
#include "stdbool.h"
2932

30-
/* write protect enable = write disable */
31-
static inline void jit_write_protect(int enabled)
32-
{
33-
return pthread_jit_write_protect_np(enabled);
34-
}
33+
#if defined(__APPLE__) && defined(HAVE_SPRR) && (defined(__arm__) || defined(__aarch64__))
3534

3635
// Returns the S3_6_c15_c1_5 register's value
3736
// Taken from
3837
// https://stackoverflow.com/questions/70019553/lldb-how-to-read-the-permissions-of-a-memory-region-for-a-thread
3938
// https://blog.svenpeter.dev/posts/m1_sprr_gxf/
39+
// On Github Action (Virtualized environment), this shall always returns 0
4040
static inline uint64_t read_sprr_perm(void)
4141
{
4242
uint64_t v;
@@ -50,7 +50,11 @@ __attribute__((unused)) static inline uint8_t thread_mask()
5050
{
5151
uint64_t v = read_sprr_perm();
5252

53-
return (v >> 20) & 3;
53+
if (v == 0) {
54+
return 0;
55+
} else {
56+
return (v >> 20) & 3;
57+
}
5458
}
5559

5660
__attribute__((unused)) static inline bool thread_writeable()
@@ -63,25 +67,69 @@ __attribute__((unused)) static inline bool thread_executable()
6367
return thread_mask() == 1;
6468
}
6569

70+
static inline void assert_executable(bool executable) {
71+
uint64_t v = read_sprr_perm();
72+
73+
if (!v) {
74+
assert(executable == thread_executable());
75+
}
76+
}
77+
78+
#else
79+
80+
// Returns the S3_6_c15_c1_5 register's value
81+
// Taken from
82+
// https://stackoverflow.com/questions/70019553/lldb-how-to-read-the-permissions-of-a-memory-region-for-a-thread
83+
// https://blog.svenpeter.dev/posts/m1_sprr_gxf/
84+
static inline uint64_t read_sprr_perm(void)
85+
{
86+
return 0;
87+
}
88+
89+
__attribute__((unused)) static inline uint8_t thread_mask()
90+
{
91+
return 0;
92+
}
93+
94+
__attribute__((unused)) static inline bool thread_writeable()
95+
{
96+
return false;
97+
}
98+
99+
__attribute__((unused)) static inline bool thread_executable()
100+
{
101+
return false;
102+
}
103+
104+
static inline void assert_executable(bool executable) {
105+
}
106+
107+
#endif
108+
109+
110+
#if defined(__APPLE__) && defined(HAVE_PTHREAD_JIT_PROTECT) && defined(HAVE_SPRR) && (defined(__arm__) || defined(__aarch64__))
111+
112+
/* write protect enable = write disable */
113+
static inline void jit_write_protect(int enabled)
114+
{
115+
return pthread_jit_write_protect_np(enabled);
116+
}
117+
66118
#define JIT_CALLBACK_GUARD(x) \
67119
{ \
68120
bool executable = uc->current_executable; \
69-
assert (executable == thread_executable()); \
121+
assert_executable(executable); \
70122
x; \
71-
if (executable != thread_executable()) { \
72-
jit_write_protect(executable); \
73-
} \
123+
jit_write_protect(executable); \
74124
} \
75125

76126

77127
#define JIT_CALLBACK_GUARD_VAR(var, x) \
78128
{ \
79129
bool executable = uc->current_executable; \
80-
assert (executable == thread_executable()); \
130+
assert_executable(executable); \
81131
var = x; \
82-
if (executable != thread_executable()) { \
83-
jit_write_protect(executable); \
84-
} \
132+
jit_write_protect(executable); \
85133
} \
86134

87135

uc.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ static void clear_deleted_hooks(uc_engine *uc);
3535
static uc_err uc_snapshot(uc_engine *uc);
3636
static uc_err uc_restore_latest_snapshot(uc_engine *uc);
3737

38-
#if defined(__APPLE__) && defined(HAVE_PTHREAD_JIT_PROTECT) && \
39-
defined(HAVE_SPRR) && (defined(__arm__) || defined(__aarch64__))
38+
#if defined(__APPLE__) && defined(HAVE_PTHREAD_JIT_PROTECT) && (defined(__arm__) || defined(__aarch64__))
4039
static void save_jit_state(uc_engine *uc)
4140
{
4241
if (!uc->nested) {
@@ -51,7 +50,7 @@ static void restore_jit_state(uc_engine *uc)
5150
{
5251
assert(uc->nested > 0);
5352
if (uc->nested == 1) {
54-
assert(uc->current_executable == thread_executable());
53+
assert_executable(uc->current_executable);
5554
if (uc->current_executable != uc->thread_executable_entry) {
5655
if (uc->thread_executable_entry) {
5756
jit_write_protect(true);

0 commit comments

Comments
 (0)