1
The following changes since commit 1316b1ddc8a05e418c8134243f8bff8cccbbccb1:
1
The following changes since commit 813bac3d8d70d85cb7835f7945eb9eed84c2d8d0:
2
2
3
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2019-07-12 15:38:22 +0100)
3
Merge tag '2023q3-bsd-user-pull-request' of https://gitlab.com/bsdimp/qemu into staging (2023-08-29 08:58:00 -0400)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/rth7680/qemu.git tags/pull-tcg-20190714
7
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20230829
8
8
9
for you to fetch changes up to 52ba13f042714c4086416973fb88e2465e0888a1:
9
for you to fetch changes up to dad2f2f5afbaf58d6056f31dfd4b9edd0854b8ab:
10
10
11
tcg: Release mmap_lock on translation fault (2019-07-14 12:19:01 +0200)
11
tcg/sparc64: Disable TCG_TARGET_HAS_extr_i64_i32 (2023-08-29 09:57:39 -0700)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Fixes for 3 tcg bugs
14
softmmu: Use async_run_on_cpu in tcg_commit
15
tcg: Remove vecop_list check from tcg_gen_not_vec
16
tcg/sparc64: Disable TCG_TARGET_HAS_extr_i64_i32
15
17
16
----------------------------------------------------------------
18
----------------------------------------------------------------
17
Richard Henderson (7):
19
Richard Henderson (4):
18
tcg: Fix constant folding of INDEX_op_extract2_i32
20
softmmu: Assert data in bounds in iotlb_to_section
19
tcg/aarch64: Fix output of extract2 opcodes
21
softmmu: Use async_run_on_cpu in tcg_commit
20
include/qemu/atomic.h: Add signal_barrier
22
tcg: Remove vecop_list check from tcg_gen_not_vec
21
tcg: Introduce set/clear_helper_retaddr
23
tcg/sparc64: Disable TCG_TARGET_HAS_extr_i64_i32
22
tcg: Remove cpu_ld*_code_ra
23
tcg: Remove duplicate #if !defined(CODE_ACCESS)
24
tcg: Release mmap_lock on translation fault
25
24
26
include/exec/cpu_ldst.h | 20 ++++++++
25
include/exec/cpu-common.h | 1 -
27
include/exec/cpu_ldst_useronly_template.h | 40 ++++++++++------
26
tcg/sparc64/tcg-target.h | 2 +-
28
include/qemu/atomic.h | 11 +++++
27
accel/tcg/cpu-exec-common.c | 30 --------------------------
29
accel/tcg/user-exec.c | 77 +++++++++++++++++++++----------
28
softmmu/physmem.c | 50 ++++++++++++++++++++++++++++++++------------
30
target/arm/helper-a64.c | 8 ++--
29
tcg/tcg-op-vec.c | 7 +++----
31
target/arm/sve_helper.c | 43 +++++++++--------
30
tcg/sparc64/tcg-target.c.inc | 11 ----------
32
tcg/aarch64/tcg-target.inc.c | 2 +-
31
6 files changed, 41 insertions(+), 60 deletions(-)
33
tcg/optimize.c | 4 +-
34
8 files changed, 139 insertions(+), 66 deletions(-)
35
diff view generated by jsdifflib
Deleted patch
1
On a 64-bit host, discard any replications of the 32-bit
2
sign bit when performing the shift and merge.
3
1
4
Fixes: https://bugs.launchpad.net/bugs/1834496
5
Tested-by: Christophe Lyon <christophe.lyon@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
---
10
tcg/optimize.c | 4 ++--
11
1 file changed, 2 insertions(+), 2 deletions(-)
12
13
diff --git a/tcg/optimize.c b/tcg/optimize.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tcg/optimize.c
16
+++ b/tcg/optimize.c
17
@@ -XXX,XX +XXX,XX @@ void tcg_optimize(TCGContext *s)
18
if (opc == INDEX_op_extract2_i64) {
19
tmp = (v1 >> op->args[3]) | (v2 << (64 - op->args[3]));
20
} else {
21
- tmp = (v1 >> op->args[3]) | (v2 << (32 - op->args[3]));
22
- tmp = (int32_t)tmp;
23
+ tmp = (int32_t)(((uint32_t)v1 >> op->args[3]) |
24
+ ((uint32_t)v2 << (32 - op->args[3])));
25
}
26
tcg_opt_gen_movi(s, op, op->args[0], tmp);
27
break;
28
--
29
2.17.1
30
31
diff view generated by jsdifflib
Deleted patch
1
This patch fixes two problems:
2
(1) The inputs to the EXTR insn were reversed,
3
(2) The input constraints use rZ, which means that we need to use
4
the REG0 macro in order to supply XZR for a constant 0 input.
5
1
6
Fixes: 464c2969d5d
7
Reported-by: Peter Maydell <peter.maydell@linaro.org>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
13
tcg/aarch64/tcg-target.inc.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tcg/aarch64/tcg-target.inc.c
19
+++ b/tcg/aarch64/tcg-target.inc.c
20
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
21
22
case INDEX_op_extract2_i64:
23
case INDEX_op_extract2_i32:
24
- tcg_out_extr(s, ext, a0, a1, a2, args[3]);
25
+ tcg_out_extr(s, ext, a0, REG0(2), REG0(1), args[3]);
26
break;
27
28
case INDEX_op_add2_i32:
29
--
30
2.17.1
31
32
diff view generated by jsdifflib
Deleted patch
1
We have some potential race conditions vs our user-exec signal
2
handler that will be solved with this barrier.
3
1
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
---
7
include/qemu/atomic.h | 11 +++++++++++
8
1 file changed, 11 insertions(+)
9
10
diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
11
index XXXXXXX..XXXXXXX 100644
12
--- a/include/qemu/atomic.h
13
+++ b/include/qemu/atomic.h
14
@@ -XXX,XX +XXX,XX @@
15
#define smp_read_barrier_depends() barrier()
16
#endif
17
18
+/*
19
+ * A signal barrier forces all pending local memory ops to be observed before
20
+ * a SIGSEGV is delivered to the *same* thread. In practice this is exactly
21
+ * the same as barrier(), but since we have the correct builtin, use it.
22
+ */
23
+#define signal_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)
24
+
25
/* Sanity check that the size of an atomic operation isn't "overly large".
26
* Despite the fact that e.g. i686 has 64-bit atomic operations, we do not
27
* want to use them because we ought not need them, and this lets us do a
28
@@ -XXX,XX +XXX,XX @@
29
#define smp_read_barrier_depends() barrier()
30
#endif
31
32
+#ifndef signal_barrier
33
+#define signal_barrier() barrier()
34
+#endif
35
+
36
/* These will only be atomic if the processor does the fetch or store
37
* in a single issue memory operation
38
*/
39
--
40
2.17.1
41
42
diff view generated by jsdifflib
1
At present we have a potential error in that helper_retaddr contains
1
Acked-by: Alex Bennée <alex.bennee@linaro.org>
2
data for handle_cpu_signal, but we have not ensured that those stores
2
Suggested-by: Alex Bennée <alex.bennee@linaro.org>
3
will be scheduled properly before the operation that may fault.
4
5
It might be that these races are not in practice observable, due to
6
our use of -fno-strict-aliasing, but better safe than sorry.
7
8
Adjust all of the setters of helper_retaddr.
9
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
---
4
---
13
include/exec/cpu_ldst.h | 20 +++++++++++
5
softmmu/physmem.c | 10 ++++++++--
14
include/exec/cpu_ldst_useronly_template.h | 12 +++----
6
1 file changed, 8 insertions(+), 2 deletions(-)
15
accel/tcg/user-exec.c | 11 +++---
16
target/arm/helper-a64.c | 8 ++---
17
target/arm/sve_helper.c | 43 +++++++++++------------
18
5 files changed, 57 insertions(+), 37 deletions(-)
19
7
20
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
8
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
21
index XXXXXXX..XXXXXXX 100644
9
index XXXXXXX..XXXXXXX 100644
22
--- a/include/exec/cpu_ldst.h
10
--- a/softmmu/physmem.c
23
+++ b/include/exec/cpu_ldst.h
11
+++ b/softmmu/physmem.c
24
@@ -XXX,XX +XXX,XX @@ typedef target_ulong abi_ptr;
12
@@ -XXX,XX +XXX,XX @@ MemoryRegionSection *iotlb_to_section(CPUState *cpu,
25
13
int asidx = cpu_asidx_from_attrs(cpu, attrs);
26
extern __thread uintptr_t helper_retaddr;
14
CPUAddressSpace *cpuas = &cpu->cpu_ases[asidx];
27
15
AddressSpaceDispatch *d = qatomic_rcu_read(&cpuas->memory_dispatch);
28
+static inline void set_helper_retaddr(uintptr_t ra)
16
- MemoryRegionSection *sections = d->map.sections;
29
+{
17
+ int section_index = index & ~TARGET_PAGE_MASK;
30
+ helper_retaddr = ra;
18
+ MemoryRegionSection *ret;
31
+ /*
19
32
+ * Ensure that this write is visible to the SIGSEGV handler that
20
- return &sections[index & ~TARGET_PAGE_MASK];
33
+ * may be invoked due to a subsequent invalid memory operation.
21
+ assert(section_index < d->map.sections_nb);
34
+ */
22
+ ret = d->map.sections + section_index;
35
+ signal_barrier();
23
+ assert(ret->mr);
36
+}
24
+ assert(ret->mr->ops);
37
+
25
+
38
+static inline void clear_helper_retaddr(void)
39
+{
40
+ /*
41
+ * Ensure that previous memory operations have succeeded before
42
+ * removing the data visible to the signal handler.
43
+ */
44
+ signal_barrier();
45
+ helper_retaddr = 0;
46
+}
47
+
48
/* In user-only mode we provide only the _code and _data accessors. */
49
50
#define MEMSUFFIX _data
51
diff --git a/include/exec/cpu_ldst_useronly_template.h b/include/exec/cpu_ldst_useronly_template.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/include/exec/cpu_ldst_useronly_template.h
54
+++ b/include/exec/cpu_ldst_useronly_template.h
55
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
56
uintptr_t retaddr)
57
{
58
RES_TYPE ret;
59
- helper_retaddr = retaddr;
60
+ set_helper_retaddr(retaddr);
61
ret = glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(env, ptr);
62
- helper_retaddr = 0;
63
+ clear_helper_retaddr();
64
return ret;
65
}
66
67
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
68
uintptr_t retaddr)
69
{
70
int ret;
71
- helper_retaddr = retaddr;
72
+ set_helper_retaddr(retaddr);
73
ret = glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(env, ptr);
74
- helper_retaddr = 0;
75
+ clear_helper_retaddr();
76
return ret;
77
}
78
#endif
79
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
80
RES_TYPE v,
81
uintptr_t retaddr)
82
{
83
- helper_retaddr = retaddr;
84
+ set_helper_retaddr(retaddr);
85
glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(env, ptr, v);
86
- helper_retaddr = 0;
87
+ clear_helper_retaddr();
88
}
89
#endif
90
91
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/accel/tcg/user-exec.c
94
+++ b/accel/tcg/user-exec.c
95
@@ -XXX,XX +XXX,XX @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
96
* currently executing TB was modified and must be exited
97
* immediately. Clear helper_retaddr for next execution.
98
*/
99
- helper_retaddr = 0;
100
+ clear_helper_retaddr();
101
cpu_exit_tb_from_sighandler(cpu, old_set);
102
/* NORETURN */
103
104
@@ -XXX,XX +XXX,XX @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
105
* an exception. Undo signal and retaddr state prior to longjmp.
106
*/
107
sigprocmask(SIG_SETMASK, old_set, NULL);
108
- helper_retaddr = 0;
109
+ clear_helper_retaddr();
110
111
cc = CPU_GET_CLASS(cpu);
112
access_type = is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
113
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
114
if (unlikely(addr & (size - 1))) {
115
cpu_loop_exit_atomic(env_cpu(env), retaddr);
116
}
117
- helper_retaddr = retaddr;
118
- return g2h(addr);
119
+ void *ret = g2h(addr);
120
+ set_helper_retaddr(retaddr);
121
+ return ret;
26
+ return ret;
122
}
27
}
123
28
124
/* Macro to call the above, with local variables from the use context. */
29
static void io_mem_init(void)
125
#define ATOMIC_MMU_DECLS do {} while (0)
126
#define ATOMIC_MMU_LOOKUP atomic_mmu_lookup(env, addr, DATA_SIZE, GETPC())
127
-#define ATOMIC_MMU_CLEANUP do { helper_retaddr = 0; } while (0)
128
+#define ATOMIC_MMU_CLEANUP do { clear_helper_retaddr(); } while (0)
129
130
#define ATOMIC_NAME(X) HELPER(glue(glue(atomic_ ## X, SUFFIX), END))
131
#define EXTRA_ARGS
132
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/target/arm/helper-a64.c
135
+++ b/target/arm/helper-a64.c
136
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_le)(CPUARMState *env, uint64_t addr,
137
/* ??? Enforce alignment. */
138
uint64_t *haddr = g2h(addr);
139
140
- helper_retaddr = ra;
141
+ set_helper_retaddr(ra);
142
o0 = ldq_le_p(haddr + 0);
143
o1 = ldq_le_p(haddr + 1);
144
oldv = int128_make128(o0, o1);
145
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_le)(CPUARMState *env, uint64_t addr,
146
stq_le_p(haddr + 0, int128_getlo(newv));
147
stq_le_p(haddr + 1, int128_gethi(newv));
148
}
149
- helper_retaddr = 0;
150
+ clear_helper_retaddr();
151
#else
152
int mem_idx = cpu_mmu_index(env, false);
153
TCGMemOpIdx oi0 = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
154
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_be)(CPUARMState *env, uint64_t addr,
155
/* ??? Enforce alignment. */
156
uint64_t *haddr = g2h(addr);
157
158
- helper_retaddr = ra;
159
+ set_helper_retaddr(ra);
160
o1 = ldq_be_p(haddr + 0);
161
o0 = ldq_be_p(haddr + 1);
162
oldv = int128_make128(o0, o1);
163
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_be)(CPUARMState *env, uint64_t addr,
164
stq_be_p(haddr + 0, int128_gethi(newv));
165
stq_be_p(haddr + 1, int128_getlo(newv));
166
}
167
- helper_retaddr = 0;
168
+ clear_helper_retaddr();
169
#else
170
int mem_idx = cpu_mmu_index(env, false);
171
TCGMemOpIdx oi0 = make_memop_idx(MO_BEQ | MO_ALIGN_16, mem_idx);
172
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/target/arm/sve_helper.c
175
+++ b/target/arm/sve_helper.c
176
@@ -XXX,XX +XXX,XX @@ static intptr_t max_for_page(target_ulong base, intptr_t mem_off,
177
return MIN(split, mem_max - mem_off) + mem_off;
178
}
179
180
-static inline void set_helper_retaddr(uintptr_t ra)
181
-{
182
-#ifdef CONFIG_USER_ONLY
183
- helper_retaddr = ra;
184
+#ifndef CONFIG_USER_ONLY
185
+/* These are normally defined only for CONFIG_USER_ONLY in <exec/cpu_ldst.h> */
186
+static inline void set_helper_retaddr(uintptr_t ra) { }
187
+static inline void clear_helper_retaddr(void) { }
188
#endif
189
-}
190
191
/*
192
* The result of tlb_vaddr_to_host for user-only is just g2h(x),
193
@@ -XXX,XX +XXX,XX @@ static void sve_ld1_r(CPUARMState *env, void *vg, const target_ulong addr,
194
if (test_host_page(host)) {
195
mem_off = host_fn(vd, vg, host - mem_off, mem_off, mem_max);
196
tcg_debug_assert(mem_off == mem_max);
197
- set_helper_retaddr(0);
198
+ clear_helper_retaddr();
199
/* After having taken any fault, zero leading inactive elements. */
200
swap_memzero(vd, reg_off);
201
return;
202
@@ -XXX,XX +XXX,XX @@ static void sve_ld1_r(CPUARMState *env, void *vg, const target_ulong addr,
203
}
204
#endif
205
206
- set_helper_retaddr(0);
207
+ clear_helper_retaddr();
208
memcpy(vd, &scratch, reg_max);
209
}
210
211
@@ -XXX,XX +XXX,XX @@ static void sve_ld2_r(CPUARMState *env, void *vg, target_ulong addr,
212
addr += 2 * size;
213
} while (i & 15);
214
}
215
- set_helper_retaddr(0);
216
+ clear_helper_retaddr();
217
218
/* Wait until all exceptions have been raised to write back. */
219
memcpy(&env->vfp.zregs[rd], &scratch[0], oprsz);
220
@@ -XXX,XX +XXX,XX @@ static void sve_ld3_r(CPUARMState *env, void *vg, target_ulong addr,
221
addr += 3 * size;
222
} while (i & 15);
223
}
224
- set_helper_retaddr(0);
225
+ clear_helper_retaddr();
226
227
/* Wait until all exceptions have been raised to write back. */
228
memcpy(&env->vfp.zregs[rd], &scratch[0], oprsz);
229
@@ -XXX,XX +XXX,XX @@ static void sve_ld4_r(CPUARMState *env, void *vg, target_ulong addr,
230
addr += 4 * size;
231
} while (i & 15);
232
}
233
- set_helper_retaddr(0);
234
+ clear_helper_retaddr();
235
236
/* Wait until all exceptions have been raised to write back. */
237
memcpy(&env->vfp.zregs[rd], &scratch[0], oprsz);
238
@@ -XXX,XX +XXX,XX @@ static void sve_ldff1_r(CPUARMState *env, void *vg, const target_ulong addr,
239
if (test_host_page(host)) {
240
mem_off = host_fn(vd, vg, host - mem_off, mem_off, mem_max);
241
tcg_debug_assert(mem_off == mem_max);
242
- set_helper_retaddr(0);
243
+ clear_helper_retaddr();
244
/* After any fault, zero any leading inactive elements. */
245
swap_memzero(vd, reg_off);
246
return;
247
@@ -XXX,XX +XXX,XX @@ static void sve_ldff1_r(CPUARMState *env, void *vg, const target_ulong addr,
248
}
249
#endif
250
251
- set_helper_retaddr(0);
252
+ clear_helper_retaddr();
253
record_fault(env, reg_off, reg_max);
254
}
255
256
@@ -XXX,XX +XXX,XX @@ static void sve_st1_r(CPUARMState *env, void *vg, target_ulong addr,
257
addr += msize;
258
} while (i & 15);
259
}
260
- set_helper_retaddr(0);
261
+ clear_helper_retaddr();
262
}
263
264
static void sve_st2_r(CPUARMState *env, void *vg, target_ulong addr,
265
@@ -XXX,XX +XXX,XX @@ static void sve_st2_r(CPUARMState *env, void *vg, target_ulong addr,
266
addr += 2 * msize;
267
} while (i & 15);
268
}
269
- set_helper_retaddr(0);
270
+ clear_helper_retaddr();
271
}
272
273
static void sve_st3_r(CPUARMState *env, void *vg, target_ulong addr,
274
@@ -XXX,XX +XXX,XX @@ static void sve_st3_r(CPUARMState *env, void *vg, target_ulong addr,
275
addr += 3 * msize;
276
} while (i & 15);
277
}
278
- set_helper_retaddr(0);
279
+ clear_helper_retaddr();
280
}
281
282
static void sve_st4_r(CPUARMState *env, void *vg, target_ulong addr,
283
@@ -XXX,XX +XXX,XX @@ static void sve_st4_r(CPUARMState *env, void *vg, target_ulong addr,
284
addr += 4 * msize;
285
} while (i & 15);
286
}
287
- set_helper_retaddr(0);
288
+ clear_helper_retaddr();
289
}
290
291
#define DO_STN_1(N, NAME, ESIZE) \
292
@@ -XXX,XX +XXX,XX @@ static void sve_ld1_zs(CPUARMState *env, void *vd, void *vg, void *vm,
293
i += 4, pg >>= 4;
294
} while (i & 15);
295
}
296
- set_helper_retaddr(0);
297
+ clear_helper_retaddr();
298
299
/* Wait until all exceptions have been raised to write back. */
300
memcpy(vd, &scratch, oprsz);
301
@@ -XXX,XX +XXX,XX @@ static void sve_ld1_zd(CPUARMState *env, void *vd, void *vg, void *vm,
302
tlb_fn(env, &scratch, i * 8, base + (off << scale), oi, ra);
303
}
304
}
305
- set_helper_retaddr(0);
306
+ clear_helper_retaddr();
307
308
/* Wait until all exceptions have been raised to write back. */
309
memcpy(vd, &scratch, oprsz * 8);
310
@@ -XXX,XX +XXX,XX @@ static inline void sve_ldff1_zs(CPUARMState *env, void *vd, void *vg, void *vm,
311
tlb_fn(env, vd, reg_off, addr, oi, ra);
312
313
/* The rest of the reads will be non-faulting. */
314
- set_helper_retaddr(0);
315
+ clear_helper_retaddr();
316
}
317
318
/* After any fault, zero the leading predicated false elements. */
319
@@ -XXX,XX +XXX,XX @@ static inline void sve_ldff1_zd(CPUARMState *env, void *vd, void *vg, void *vm,
320
tlb_fn(env, vd, reg_off, addr, oi, ra);
321
322
/* The rest of the reads will be non-faulting. */
323
- set_helper_retaddr(0);
324
+ clear_helper_retaddr();
325
}
326
327
/* After any fault, zero the leading predicated false elements. */
328
@@ -XXX,XX +XXX,XX @@ static void sve_st1_zs(CPUARMState *env, void *vd, void *vg, void *vm,
329
i += 4, pg >>= 4;
330
} while (i & 15);
331
}
332
- set_helper_retaddr(0);
333
+ clear_helper_retaddr();
334
}
335
336
static void sve_st1_zd(CPUARMState *env, void *vd, void *vg, void *vm,
337
@@ -XXX,XX +XXX,XX @@ static void sve_st1_zd(CPUARMState *env, void *vd, void *vg, void *vm,
338
tlb_fn(env, vd, i * 8, base + (off << scale), oi, ra);
339
}
340
}
341
- set_helper_retaddr(0);
342
+ clear_helper_retaddr();
343
}
344
345
#define DO_ST1_ZPZ_S(MEM, OFS) \
346
--
30
--
347
2.17.1
31
2.34.1
348
32
349
33
diff view generated by jsdifflib
1
Turn helper_retaddr into a multi-state flag that may now also
1
After system startup, run the update to memory_dispatch
2
indicate when we're performing a read on behalf of the translator.
2
and the tlb_flush on the cpu. This eliminates a race,
3
In this case, release the mmap_lock before the longjmp back to
3
wherein a running cpu sees the memory_dispatch change
4
the main cpu loop, and thereby avoid a failing assert therein.
4
but has not yet seen the tlb_flush.
5
5
6
Fixes: https://bugs.launchpad.net/qemu/+bug/1832353
6
Since the update now happens on the cpu, we need not use
7
qatomic_rcu_read to protect the read of memory_dispatch.
8
9
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1826
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1834
11
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1846
7
Tested-by: Alex Bennée <alex.bennee@linaro.org>
12
Tested-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
15
---
11
include/exec/cpu_ldst_useronly_template.h | 20 +++++--
16
include/exec/cpu-common.h | 1 -
12
accel/tcg/user-exec.c | 66 ++++++++++++++++-------
17
accel/tcg/cpu-exec-common.c | 30 ----------------------------
13
2 files changed, 63 insertions(+), 23 deletions(-)
18
softmmu/physmem.c | 40 +++++++++++++++++++++++++++----------
19
3 files changed, 29 insertions(+), 42 deletions(-)
14
20
15
diff --git a/include/exec/cpu_ldst_useronly_template.h b/include/exec/cpu_ldst_useronly_template.h
21
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/include/exec/cpu_ldst_useronly_template.h
23
--- a/include/exec/cpu-common.h
18
+++ b/include/exec/cpu_ldst_useronly_template.h
24
+++ b/include/exec/cpu-common.h
19
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ static inline void cpu_physical_memory_write(hwaddr addr,
20
static inline RES_TYPE
21
glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr)
22
{
26
{
23
-#if !defined(CODE_ACCESS)
27
cpu_physical_memory_rw(addr, (void *)buf, len, true);
24
+#ifdef CODE_ACCESS
28
}
25
+ RES_TYPE ret;
29
-void cpu_reloading_memory_map(void);
26
+ set_helper_retaddr(1);
30
void *cpu_physical_memory_map(hwaddr addr,
27
+ ret = glue(glue(ld, USUFFIX), _p)(g2h(ptr));
31
hwaddr *plen,
28
+ clear_helper_retaddr();
32
bool is_write);
29
+ return ret;
33
diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c
30
+#else
34
index XXXXXXX..XXXXXXX 100644
31
trace_guest_mem_before_exec(
35
--- a/accel/tcg/cpu-exec-common.c
32
env_cpu(env), ptr,
36
+++ b/accel/tcg/cpu-exec-common.c
33
trace_mem_build_info(SHIFT, false, MO_TE, false));
37
@@ -XXX,XX +XXX,XX @@ void cpu_loop_exit_noexc(CPUState *cpu)
38
cpu_loop_exit(cpu);
39
}
40
41
-#if defined(CONFIG_SOFTMMU)
42
-void cpu_reloading_memory_map(void)
43
-{
44
- if (qemu_in_vcpu_thread() && current_cpu->running) {
45
- /* The guest can in theory prolong the RCU critical section as long
46
- * as it feels like. The major problem with this is that because it
47
- * can do multiple reconfigurations of the memory map within the
48
- * critical section, we could potentially accumulate an unbounded
49
- * collection of memory data structures awaiting reclamation.
50
- *
51
- * Because the only thing we're currently protecting with RCU is the
52
- * memory data structures, it's sufficient to break the critical section
53
- * in this callback, which we know will get called every time the
54
- * memory map is rearranged.
55
- *
56
- * (If we add anything else in the system that uses RCU to protect
57
- * its data structures, we will need to implement some other mechanism
58
- * to force TCG CPUs to exit the critical section, at which point this
59
- * part of this callback might become unnecessary.)
60
- *
61
- * This pair matches cpu_exec's rcu_read_lock()/rcu_read_unlock(), which
62
- * only protects cpu->as->dispatch. Since we know our caller is about
63
- * to reload it, it's safe to split the critical section.
64
- */
65
- rcu_read_unlock();
66
- rcu_read_lock();
67
- }
68
-}
34
-#endif
69
-#endif
35
return glue(glue(ld, USUFFIX), _p)(g2h(ptr));
70
-
36
+#endif
71
void cpu_loop_exit(CPUState *cpu)
72
{
73
/* Undo the setting in cpu_tb_exec. */
74
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/softmmu/physmem.c
77
+++ b/softmmu/physmem.c
78
@@ -XXX,XX +XXX,XX @@ address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr orig_addr,
79
IOMMUTLBEntry iotlb;
80
int iommu_idx;
81
hwaddr addr = orig_addr;
82
- AddressSpaceDispatch *d =
83
- qatomic_rcu_read(&cpu->cpu_ases[asidx].memory_dispatch);
84
+ AddressSpaceDispatch *d = cpu->cpu_ases[asidx].memory_dispatch;
85
86
for (;;) {
87
section = address_space_translate_internal(d, addr, &addr, plen, false);
88
@@ -XXX,XX +XXX,XX @@ MemoryRegionSection *iotlb_to_section(CPUState *cpu,
89
{
90
int asidx = cpu_asidx_from_attrs(cpu, attrs);
91
CPUAddressSpace *cpuas = &cpu->cpu_ases[asidx];
92
- AddressSpaceDispatch *d = qatomic_rcu_read(&cpuas->memory_dispatch);
93
+ AddressSpaceDispatch *d = cpuas->memory_dispatch;
94
int section_index = index & ~TARGET_PAGE_MASK;
95
MemoryRegionSection *ret;
96
97
@@ -XXX,XX +XXX,XX @@ static void tcg_log_global_after_sync(MemoryListener *listener)
98
}
37
}
99
}
38
100
39
#ifndef CODE_ACCESS
101
+static void tcg_commit_cpu(CPUState *cpu, run_on_cpu_data data)
40
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
102
+{
41
static inline int
103
+ CPUAddressSpace *cpuas = data.host_ptr;
42
glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr)
104
+
105
+ cpuas->memory_dispatch = address_space_to_dispatch(cpuas->as);
106
+ tlb_flush(cpu);
107
+}
108
+
109
static void tcg_commit(MemoryListener *listener)
43
{
110
{
44
-#if !defined(CODE_ACCESS)
111
CPUAddressSpace *cpuas;
45
+#ifdef CODE_ACCESS
112
- AddressSpaceDispatch *d;
46
+ int ret;
113
+ CPUState *cpu;
47
+ set_helper_retaddr(1);
114
48
+ ret = glue(glue(lds, SUFFIX), _p)(g2h(ptr));
115
assert(tcg_enabled());
49
+ clear_helper_retaddr();
116
/* since each CPU stores ram addresses in its TLB cache, we must
50
+ return ret;
117
reset the modified entries */
51
+#else
118
cpuas = container_of(listener, CPUAddressSpace, tcg_as_listener);
52
trace_guest_mem_before_exec(
119
- cpu_reloading_memory_map();
53
env_cpu(env), ptr,
120
- /* The CPU and TLB are protected by the iothread lock.
54
trace_mem_build_info(SHIFT, true, MO_TE, false));
121
- * We reload the dispatch pointer now because cpu_reloading_memory_map()
55
-#endif
122
- * may have split the RCU critical section.
56
return glue(glue(lds, SUFFIX), _p)(g2h(ptr));
123
+ cpu = cpuas->cpu;
57
+#endif
124
+
125
+ /*
126
+ * Defer changes to as->memory_dispatch until the cpu is quiescent.
127
+ * Otherwise we race between (1) other cpu threads and (2) ongoing
128
+ * i/o for the current cpu thread, with data cached by mmu_lookup().
129
+ *
130
+ * In addition, queueing the work function will kick the cpu back to
131
+ * the main loop, which will end the RCU critical section and reclaim
132
+ * the memory data structures.
133
+ *
134
+ * That said, the listener is also called during realize, before
135
+ * all of the tcg machinery for run-on is initialized: thus halt_cond.
136
*/
137
- d = address_space_to_dispatch(cpuas->as);
138
- qatomic_rcu_set(&cpuas->memory_dispatch, d);
139
- tlb_flush(cpuas->cpu);
140
+ if (cpu->halt_cond) {
141
+ async_run_on_cpu(cpu, tcg_commit_cpu, RUN_ON_CPU_HOST_PTR(cpuas));
142
+ } else {
143
+ tcg_commit_cpu(cpu, RUN_ON_CPU_HOST_PTR(cpuas));
144
+ }
58
}
145
}
59
146
60
#ifndef CODE_ACCESS
147
static void memory_map_init(void)
61
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/accel/tcg/user-exec.c
64
+++ b/accel/tcg/user-exec.c
65
@@ -XXX,XX +XXX,XX @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
66
CPUState *cpu = current_cpu;
67
CPUClass *cc;
68
unsigned long address = (unsigned long)info->si_addr;
69
- MMUAccessType access_type;
70
+ MMUAccessType access_type = is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
71
72
- /* We must handle PC addresses from two different sources:
73
- * a call return address and a signal frame address.
74
- *
75
- * Within cpu_restore_state_from_tb we assume the former and adjust
76
- * the address by -GETPC_ADJ so that the address is within the call
77
- * insn so that addr does not accidentally match the beginning of the
78
- * next guest insn.
79
- *
80
- * However, when the PC comes from the signal frame, it points to
81
- * the actual faulting host insn and not a call insn. Subtracting
82
- * GETPC_ADJ in that case may accidentally match the previous guest insn.
83
- *
84
- * So for the later case, adjust forward to compensate for what
85
- * will be done later by cpu_restore_state_from_tb.
86
- */
87
- if (helper_retaddr) {
88
+ switch (helper_retaddr) {
89
+ default:
90
+ /*
91
+ * Fault during host memory operation within a helper function.
92
+ * The helper's host return address, saved here, gives us a
93
+ * pointer into the generated code that will unwind to the
94
+ * correct guest pc.
95
+ */
96
pc = helper_retaddr;
97
- } else {
98
+ break;
99
+
100
+ case 0:
101
+ /*
102
+ * Fault during host memory operation within generated code.
103
+ * (Or, a unrelated bug within qemu, but we can't tell from here).
104
+ *
105
+ * We take the host pc from the signal frame. However, we cannot
106
+ * use that value directly. Within cpu_restore_state_from_tb, we
107
+ * assume PC comes from GETPC(), as used by the helper functions,
108
+ * so we adjust the address by -GETPC_ADJ to form an address that
109
+ * is within the call insn, so that the address does not accidentially
110
+ * match the beginning of the next guest insn. However, when the
111
+ * pc comes from the signal frame it points to the actual faulting
112
+ * host memory insn and not the return from a call insn.
113
+ *
114
+ * Therefore, adjust to compensate for what will be done later
115
+ * by cpu_restore_state_from_tb.
116
+ */
117
pc += GETPC_ADJ;
118
+ break;
119
+
120
+ case 1:
121
+ /*
122
+ * Fault during host read for translation, or loosely, "execution".
123
+ *
124
+ * The guest pc is already pointing to the start of the TB for which
125
+ * code is being generated. If the guest translator manages the
126
+ * page crossings correctly, this is exactly the correct address
127
+ * (and if the translator doesn't handle page boundaries correctly
128
+ * there's little we can do about that here). Therefore, do not
129
+ * trigger the unwinder.
130
+ *
131
+ * Like tb_gen_code, release the memory lock before cpu_loop_exit.
132
+ */
133
+ pc = 0;
134
+ access_type = MMU_INST_FETCH;
135
+ mmap_unlock();
136
+ break;
137
}
138
139
/* For synchronous signals we expect to be coming from the vCPU
140
@@ -XXX,XX +XXX,XX @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
141
clear_helper_retaddr();
142
143
cc = CPU_GET_CLASS(cpu);
144
- access_type = is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
145
cc->tlb_fill(cpu, address, 0, access_type, MMU_USER_IDX, false, pc);
146
g_assert_not_reached();
147
}
148
--
148
--
149
2.17.1
149
2.34.1
150
150
151
151
diff view generated by jsdifflib
1
This code block is already surrounded by #ifndef CODE_ACCESS.
1
The not pattern is always available via generic expansion.
2
See debug block in tcg_can_emit_vecop_list.
2
3
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Fixes: 11978f6f58 ("tcg: Fix expansion of INDEX_op_not_vec")
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
---
7
---
6
include/exec/cpu_ldst_useronly_template.h | 2 --
8
tcg/tcg-op-vec.c | 7 +++----
7
1 file changed, 2 deletions(-)
9
1 file changed, 3 insertions(+), 4 deletions(-)
8
10
9
diff --git a/include/exec/cpu_ldst_useronly_template.h b/include/exec/cpu_ldst_useronly_template.h
11
diff --git a/tcg/tcg-op-vec.c b/tcg/tcg-op-vec.c
10
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
11
--- a/include/exec/cpu_ldst_useronly_template.h
13
--- a/tcg/tcg-op-vec.c
12
+++ b/include/exec/cpu_ldst_useronly_template.h
14
+++ b/tcg/tcg-op-vec.c
13
@@ -XXX,XX +XXX,XX @@ static inline void
15
@@ -XXX,XX +XXX,XX @@ static bool do_op2(unsigned vece, TCGv_vec r, TCGv_vec a, TCGOpcode opc)
14
glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr,
16
15
RES_TYPE v)
17
void tcg_gen_not_vec(unsigned vece, TCGv_vec r, TCGv_vec a)
16
{
18
{
17
-#if !defined(CODE_ACCESS)
19
- const TCGOpcode *hold_list = tcg_swap_vecop_list(NULL);
18
trace_guest_mem_before_exec(
20
-
19
env_cpu(env), ptr,
21
- if (!TCG_TARGET_HAS_not_vec || !do_op2(vece, r, a, INDEX_op_not_vec)) {
20
trace_mem_build_info(SHIFT, false, MO_TE, true));
22
+ if (TCG_TARGET_HAS_not_vec) {
21
-#endif
23
+ vec_gen_op2(INDEX_op_not_vec, 0, r, a);
22
glue(glue(st, SUFFIX), _p)(g2h(ptr), v);
24
+ } else {
25
tcg_gen_xor_vec(0, r, a, tcg_constant_vec_matching(r, 0, -1));
26
}
27
- tcg_swap_vecop_list(hold_list);
23
}
28
}
24
29
30
void tcg_gen_neg_vec(unsigned vece, TCGv_vec r, TCGv_vec a)
25
--
31
--
26
2.17.1
32
2.34.1
27
33
28
34
diff view generated by jsdifflib
1
These functions are not used, and are not usable in the
1
Since a59a29312660 ("tcg/sparc64: Remove sparc32plus constraints")
2
context of code generation, because we never have a helper
2
we no longer distinguish registers with 32 vs 64 bits.
3
return address to pass in to them.
3
Therefore we can remove support for the backend-specific
4
type change opcodes.
4
5
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
---
7
---
8
include/exec/cpu_ldst_useronly_template.h | 6 +++++-
8
tcg/sparc64/tcg-target.h | 2 +-
9
1 file changed, 5 insertions(+), 1 deletion(-)
9
tcg/sparc64/tcg-target.c.inc | 11 -----------
10
2 files changed, 1 insertion(+), 12 deletions(-)
10
11
11
diff --git a/include/exec/cpu_ldst_useronly_template.h b/include/exec/cpu_ldst_useronly_template.h
12
diff --git a/tcg/sparc64/tcg-target.h b/tcg/sparc64/tcg-target.h
12
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
13
--- a/include/exec/cpu_ldst_useronly_template.h
14
--- a/tcg/sparc64/tcg-target.h
14
+++ b/include/exec/cpu_ldst_useronly_template.h
15
+++ b/tcg/sparc64/tcg-target.h
15
@@ -XXX,XX +XXX,XX @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr)
16
@@ -XXX,XX +XXX,XX @@ extern bool use_vis3_instructions;
16
return glue(glue(ld, USUFFIX), _p)(g2h(ptr));
17
#define TCG_TARGET_HAS_mulsh_i32 0
18
#define TCG_TARGET_HAS_qemu_st8_i32 0
19
20
-#define TCG_TARGET_HAS_extr_i64_i32 1
21
+#define TCG_TARGET_HAS_extr_i64_i32 0
22
#define TCG_TARGET_HAS_div_i64 1
23
#define TCG_TARGET_HAS_rem_i64 0
24
#define TCG_TARGET_HAS_rot_i64 0
25
diff --git a/tcg/sparc64/tcg-target.c.inc b/tcg/sparc64/tcg-target.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/tcg/sparc64/tcg-target.c.inc
28
+++ b/tcg/sparc64/tcg-target.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void tcg_out_extu_i32_i64(TCGContext *s, TCGReg rd, TCGReg rs)
30
tcg_out_ext32u(s, rd, rs);
17
}
31
}
18
32
19
+#ifndef CODE_ACCESS
33
-static void tcg_out_extrl_i64_i32(TCGContext *s, TCGReg rd, TCGReg rs)
20
static inline RES_TYPE
34
-{
21
glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
35
- tcg_out_mov(s, TCG_TYPE_I32, rd, rs);
22
abi_ptr ptr,
36
-}
23
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
37
-
24
clear_helper_retaddr();
38
static bool tcg_out_xchg(TCGContext *s, TCGType type, TCGReg r1, TCGReg r2)
25
return ret;
39
{
26
}
40
return false;
27
+#endif
41
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
28
42
case INDEX_op_divu_i64:
29
#if DATA_SIZE <= 2
43
c = ARITH_UDIVX;
30
static inline int
44
goto gen_arith;
31
@@ -XXX,XX +XXX,XX @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr)
45
- case INDEX_op_extrh_i64_i32:
32
return glue(glue(lds, SUFFIX), _p)(g2h(ptr));
46
- tcg_out_arithi(s, a0, a1, 32, SHIFT_SRLX);
33
}
47
- break;
34
48
35
+#ifndef CODE_ACCESS
49
case INDEX_op_brcond_i64:
36
static inline int
50
tcg_out_brcond_i64(s, a2, a0, a1, const_args[1], arg_label(args[3]));
37
glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
51
@@ -XXX,XX +XXX,XX @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
38
abi_ptr ptr,
52
case INDEX_op_ext32u_i64:
39
@@ -XXX,XX +XXX,XX @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
53
case INDEX_op_ext_i32_i64:
40
clear_helper_retaddr();
54
case INDEX_op_extu_i32_i64:
41
return ret;
55
- case INDEX_op_extrl_i64_i32:
42
}
56
default:
43
-#endif
57
g_assert_not_reached();
44
+#endif /* CODE_ACCESS */
58
}
45
+#endif /* DATA_SIZE <= 2 */
59
@@ -XXX,XX +XXX,XX @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
46
60
case INDEX_op_ext32u_i64:
47
#ifndef CODE_ACCESS
61
case INDEX_op_ext_i32_i64:
48
static inline void
62
case INDEX_op_extu_i32_i64:
63
- case INDEX_op_extrl_i64_i32:
64
- case INDEX_op_extrh_i64_i32:
65
case INDEX_op_qemu_ld_a32_i32:
66
case INDEX_op_qemu_ld_a64_i32:
67
case INDEX_op_qemu_ld_a32_i64:
49
--
68
--
50
2.17.1
69
2.34.1
51
52
diff view generated by jsdifflib