1 | The following changes since commit 26d6a7c87b05017ffabffb5e16837a0fccf67e90: | 1 | Pretty small still, but there are two patches that ought |
---|---|---|---|
2 | to get backported to stable, so no point in delaying. | ||
2 | 3 | ||
3 | Merge remote-tracking branch 'remotes/ericb/tags/pull-qapi-2018-04-10' into staging (2018-04-10 22:16:19 +0100) | 4 | r~ |
5 | |||
6 | The following changes since commit a5ba0a7e4e150d1350a041f0d0ef9ca6c8d7c307: | ||
7 | |||
8 | Merge tag 'pull-aspeed-20241211' of https://github.com/legoater/qemu into staging (2024-12-11 15:16:47 +0000) | ||
4 | 9 | ||
5 | are available in the Git repository at: | 10 | are available in the Git repository at: |
6 | 11 | ||
7 | git://github.com/rth7680/qemu.git tags/pull-tcg-20180411 | 12 | https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20241212 |
8 | 13 | ||
9 | for you to fetch changes up to afd46fcad2dceffda35c0586f5723c127b6e09d8: | 14 | for you to fetch changes up to 7ac87b14a92234b6a89b701b4043ad6cf8bdcccf: |
10 | 15 | ||
11 | icount: fix cpu_restore_state_from_tb for non-tb-exit cases (2018-04-11 09:05:22 +1000) | 16 | target/sparc: Use memcpy() and remove memcpy32() (2024-12-12 14:28:38 -0600) |
12 | 17 | ||
13 | ---------------------------------------------------------------- | 18 | ---------------------------------------------------------------- |
14 | Handle read-modify-write i/o with icount | 19 | tcg: Reset free_temps before tcg_optimize |
20 | tcg/riscv: Fix StoreStore barrier generation | ||
21 | include/exec: Introduce fpst alias in helper-head.h.inc | ||
22 | target/sparc: Use memcpy() and remove memcpy32() | ||
15 | 23 | ||
16 | ---------------------------------------------------------------- | 24 | ---------------------------------------------------------------- |
17 | Pavel Dovgalyuk (1): | 25 | Philippe Mathieu-Daudé (1): |
18 | icount: fix cpu_restore_state_from_tb for non-tb-exit cases | 26 | target/sparc: Use memcpy() and remove memcpy32() |
19 | 27 | ||
20 | include/exec/exec-all.h | 5 ++++- | 28 | Richard Henderson (2): |
21 | accel/tcg/cpu-exec-common.c | 10 +++++----- | 29 | tcg: Reset free_temps before tcg_optimize |
22 | accel/tcg/cpu-exec.c | 1 - | 30 | include/exec: Introduce fpst alias in helper-head.h.inc |
23 | accel/tcg/translate-all.c | 27 ++++++++++++++------------- | ||
24 | accel/tcg/user-exec.c | 2 +- | ||
25 | hw/misc/mips_itu.c | 3 +-- | ||
26 | target/alpha/helper.c | 2 +- | ||
27 | target/alpha/mem_helper.c | 6 ++---- | ||
28 | target/arm/op_helper.c | 6 +++--- | ||
29 | target/cris/op_helper.c | 4 ++-- | ||
30 | target/i386/helper.c | 2 +- | ||
31 | target/i386/svm_helper.c | 2 +- | ||
32 | target/m68k/op_helper.c | 4 ++-- | ||
33 | target/moxie/helper.c | 2 +- | ||
34 | target/openrisc/sys_helper.c | 8 ++++---- | ||
35 | target/tricore/op_helper.c | 2 +- | ||
36 | target/xtensa/op_helper.c | 4 ++-- | ||
37 | 17 files changed, 45 insertions(+), 45 deletions(-) | ||
38 | 31 | ||
32 | Roman Artemev (1): | ||
33 | tcg/riscv: Fix StoreStore barrier generation | ||
34 | |||
35 | include/tcg/tcg-temp-internal.h | 6 ++++++ | ||
36 | accel/tcg/plugin-gen.c | 2 +- | ||
37 | target/sparc/win_helper.c | 26 ++++++++------------------ | ||
38 | tcg/tcg.c | 5 ++++- | ||
39 | include/exec/helper-head.h.inc | 3 +++ | ||
40 | tcg/riscv/tcg-target.c.inc | 2 +- | ||
41 | 6 files changed, 23 insertions(+), 21 deletions(-) | ||
42 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | When allocating new temps during tcg_optmize, do not re-use | ||
2 | any EBB temps that were used within the TB. We do not have | ||
3 | any idea what span of the TB in which the temp was live. | ||
1 | 4 | ||
5 | Introduce tcg_temp_ebb_reset_freed and use before tcg_optimize, | ||
6 | as well as replacing the equivalent in plugin_gen_inject and | ||
7 | tcg_func_start. | ||
8 | |||
9 | Cc: qemu-stable@nongnu.org | ||
10 | Fixes: fb04ab7ddd8 ("tcg/optimize: Lower TCG_COND_TST{EQ,NE} if unsupported") | ||
11 | Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2711 | ||
12 | Reported-by: wannacu <wannacu2049@gmail.com> | ||
13 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
14 | Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> | ||
15 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
16 | --- | ||
17 | include/tcg/tcg-temp-internal.h | 6 ++++++ | ||
18 | accel/tcg/plugin-gen.c | 2 +- | ||
19 | tcg/tcg.c | 5 ++++- | ||
20 | 3 files changed, 11 insertions(+), 2 deletions(-) | ||
21 | |||
22 | diff --git a/include/tcg/tcg-temp-internal.h b/include/tcg/tcg-temp-internal.h | ||
23 | index XXXXXXX..XXXXXXX 100644 | ||
24 | --- a/include/tcg/tcg-temp-internal.h | ||
25 | +++ b/include/tcg/tcg-temp-internal.h | ||
26 | @@ -XXX,XX +XXX,XX @@ TCGv_i64 tcg_temp_ebb_new_i64(void); | ||
27 | TCGv_ptr tcg_temp_ebb_new_ptr(void); | ||
28 | TCGv_i128 tcg_temp_ebb_new_i128(void); | ||
29 | |||
30 | +/* Forget all freed EBB temps, so that new allocations produce new temps. */ | ||
31 | +static inline void tcg_temp_ebb_reset_freed(TCGContext *s) | ||
32 | +{ | ||
33 | + memset(s->free_temps, 0, sizeof(s->free_temps)); | ||
34 | +} | ||
35 | + | ||
36 | #endif /* TCG_TEMP_FREE_H */ | ||
37 | diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/accel/tcg/plugin-gen.c | ||
40 | +++ b/accel/tcg/plugin-gen.c | ||
41 | @@ -XXX,XX +XXX,XX @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb) | ||
42 | * that might be live within the existing opcode stream. | ||
43 | * The simplest solution is to release them all and create new. | ||
44 | */ | ||
45 | - memset(tcg_ctx->free_temps, 0, sizeof(tcg_ctx->free_temps)); | ||
46 | + tcg_temp_ebb_reset_freed(tcg_ctx); | ||
47 | |||
48 | QTAILQ_FOREACH_SAFE(op, &tcg_ctx->ops, link, next) { | ||
49 | switch (op->opc) { | ||
50 | diff --git a/tcg/tcg.c b/tcg/tcg.c | ||
51 | index XXXXXXX..XXXXXXX 100644 | ||
52 | --- a/tcg/tcg.c | ||
53 | +++ b/tcg/tcg.c | ||
54 | @@ -XXX,XX +XXX,XX @@ void tcg_func_start(TCGContext *s) | ||
55 | s->nb_temps = s->nb_globals; | ||
56 | |||
57 | /* No temps have been previously allocated for size or locality. */ | ||
58 | - memset(s->free_temps, 0, sizeof(s->free_temps)); | ||
59 | + tcg_temp_ebb_reset_freed(s); | ||
60 | |||
61 | /* No constant temps have been previously allocated. */ | ||
62 | for (int i = 0; i < TCG_TYPE_COUNT; ++i) { | ||
63 | @@ -XXX,XX +XXX,XX @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start) | ||
64 | } | ||
65 | #endif | ||
66 | |||
67 | + /* Do not reuse any EBB that may be allocated within the TB. */ | ||
68 | + tcg_temp_ebb_reset_freed(s); | ||
69 | + | ||
70 | tcg_optimize(s); | ||
71 | |||
72 | reachable_code_pass(s); | ||
73 | -- | ||
74 | 2.43.0 | ||
75 | |||
76 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Roman Artemev <roman.artemev@syntacore.com> | ||
1 | 2 | ||
3 | On RISC-V to StoreStore barrier corresponds | ||
4 | `fence w, w` not `fence r, r` | ||
5 | |||
6 | Cc: qemu-stable@nongnu.org | ||
7 | Fixes: efbea94c76b ("tcg/riscv: Add slowpath load and store instructions") | ||
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Signed-off-by: Denis Tomashev <denis.tomashev@syntacore.com> | ||
10 | Signed-off-by: Roman Artemev <roman.artemev@syntacore.com> | ||
11 | Message-ID: <e2f2131e294a49e79959d4fa9ec02cf4@syntacore.com> | ||
12 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
13 | --- | ||
14 | tcg/riscv/tcg-target.c.inc | 2 +- | ||
15 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
16 | |||
17 | diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/tcg/riscv/tcg-target.c.inc | ||
20 | +++ b/tcg/riscv/tcg-target.c.inc | ||
21 | @@ -XXX,XX +XXX,XX @@ static void tcg_out_mb(TCGContext *s, TCGArg a0) | ||
22 | insn |= 0x02100000; | ||
23 | } | ||
24 | if (a0 & TCG_MO_ST_ST) { | ||
25 | - insn |= 0x02200000; | ||
26 | + insn |= 0x01100000; | ||
27 | } | ||
28 | tcg_out32(s, insn); | ||
29 | } | ||
30 | -- | ||
31 | 2.43.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | This allows targets to declare that the helper requires a | ||
2 | float_status pointer and instead of a generic void pointer. | ||
1 | 3 | ||
4 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
5 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | ||
6 | --- | ||
7 | include/exec/helper-head.h.inc | 3 +++ | ||
8 | 1 file changed, 3 insertions(+) | ||
9 | |||
10 | diff --git a/include/exec/helper-head.h.inc b/include/exec/helper-head.h.inc | ||
11 | index XXXXXXX..XXXXXXX 100644 | ||
12 | --- a/include/exec/helper-head.h.inc | ||
13 | +++ b/include/exec/helper-head.h.inc | ||
14 | @@ -XXX,XX +XXX,XX @@ | ||
15 | #define dh_alias_ptr ptr | ||
16 | #define dh_alias_cptr ptr | ||
17 | #define dh_alias_env ptr | ||
18 | +#define dh_alias_fpst ptr | ||
19 | #define dh_alias_void void | ||
20 | #define dh_alias_noreturn noreturn | ||
21 | #define dh_alias(t) glue(dh_alias_, t) | ||
22 | @@ -XXX,XX +XXX,XX @@ | ||
23 | #define dh_ctype_ptr void * | ||
24 | #define dh_ctype_cptr const void * | ||
25 | #define dh_ctype_env CPUArchState * | ||
26 | +#define dh_ctype_fpst float_status * | ||
27 | #define dh_ctype_void void | ||
28 | #define dh_ctype_noreturn G_NORETURN void | ||
29 | #define dh_ctype(t) dh_ctype_##t | ||
30 | @@ -XXX,XX +XXX,XX @@ | ||
31 | #define dh_typecode_f64 dh_typecode_i64 | ||
32 | #define dh_typecode_cptr dh_typecode_ptr | ||
33 | #define dh_typecode_env dh_typecode_ptr | ||
34 | +#define dh_typecode_fpst dh_typecode_ptr | ||
35 | #define dh_typecode(t) dh_typecode_##t | ||
36 | |||
37 | #define dh_callflag_i32 0 | ||
38 | -- | ||
39 | 2.43.0 | ||
40 | |||
41 | diff view generated by jsdifflib |
1 | From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | In icount mode, instructions that access io memory spaces in the middle | 3 | Rather than manually copying each register, use |
4 | of the translation block invoke TB recompilation. After recompilation, | 4 | the libc memcpy(), which is well optimized nowadays. |
5 | such instructions become last in the TB and are allowed to access io | ||
6 | memory spaces. | ||
7 | 5 | ||
8 | When the code includes instruction like i386 'xchg eax, 0xffffd080' | 6 | Suggested-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> |
9 | which accesses APIC, QEMU goes into an infinite loop of the recompilation. | 7 | Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> |
10 | 8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | |
11 | This instruction includes two memory accesses - one read and one write. | 9 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
12 | After the first access, APIC calls cpu_report_tpr_access, which restores | 10 | Message-ID: <20241205205418.67613-1-philmd@linaro.org> |
13 | the CPU state to get the current eip. But cpu_restore_state_from_tb | ||
14 | resets the cpu->can_do_io flag which makes the second memory access invalid. | ||
15 | Therefore the second memory access causes a recompilation of the block. | ||
16 | Then these operations repeat again and again. | ||
17 | |||
18 | This patch moves resetting cpu->can_do_io flag from | ||
19 | cpu_restore_state_from_tb to cpu_loop_exit* functions. | ||
20 | |||
21 | It also adds a parameter for cpu_restore_state which controls restoring | ||
22 | icount. There is no need to restore icount when we only query CPU state | ||
23 | without breaking the TB. Restoring it in such cases leads to the | ||
24 | incorrect flow of the virtual time. | ||
25 | |||
26 | In most cases new parameter is true (icount should be recalculated). | ||
27 | But there are two cases in i386 and openrisc when the CPU state is only | ||
28 | queried without the need to break the TB. This patch fixes both of | ||
29 | these cases. | ||
30 | |||
31 | Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> | ||
32 | Message-Id: <20180409091320.12504.35329.stgit@pasha-VirtualBox> | ||
33 | [rth: Make can_do_io setting unconditional; move from cpu_exec; | ||
34 | make cpu_loop_exit_{noexc,restore} call cpu_loop_exit.] | ||
35 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> | 11 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
36 | --- | 12 | --- |
37 | include/exec/exec-all.h | 5 ++++- | 13 | target/sparc/win_helper.c | 26 ++++++++------------------ |
38 | accel/tcg/cpu-exec-common.c | 10 +++++----- | 14 | 1 file changed, 8 insertions(+), 18 deletions(-) |
39 | accel/tcg/cpu-exec.c | 1 - | ||
40 | accel/tcg/translate-all.c | 27 ++++++++++++++------------- | ||
41 | accel/tcg/user-exec.c | 2 +- | ||
42 | hw/misc/mips_itu.c | 3 +-- | ||
43 | target/alpha/helper.c | 2 +- | ||
44 | target/alpha/mem_helper.c | 6 ++---- | ||
45 | target/arm/op_helper.c | 6 +++--- | ||
46 | target/cris/op_helper.c | 4 ++-- | ||
47 | target/i386/helper.c | 2 +- | ||
48 | target/i386/svm_helper.c | 2 +- | ||
49 | target/m68k/op_helper.c | 4 ++-- | ||
50 | target/moxie/helper.c | 2 +- | ||
51 | target/openrisc/sys_helper.c | 8 ++++---- | ||
52 | target/tricore/op_helper.c | 2 +- | ||
53 | target/xtensa/op_helper.c | 4 ++-- | ||
54 | 17 files changed, 45 insertions(+), 45 deletions(-) | ||
55 | 15 | ||
56 | diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h | 16 | diff --git a/target/sparc/win_helper.c b/target/sparc/win_helper.c |
57 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
58 | --- a/include/exec/exec-all.h | 18 | --- a/target/sparc/win_helper.c |
59 | +++ b/include/exec/exec-all.h | 19 | +++ b/target/sparc/win_helper.c |
60 | @@ -XXX,XX +XXX,XX @@ void cpu_gen_init(void); | 20 | @@ -XXX,XX +XXX,XX @@ |
61 | * cpu_restore_state: | 21 | #include "exec/helper-proto.h" |
62 | * @cpu: the vCPU state is to be restore to | 22 | #include "trace.h" |
63 | * @searched_pc: the host PC the fault occurred at | 23 | |
64 | + * @will_exit: true if the TB executed will be interrupted after some | 24 | -static inline void memcpy32(target_ulong *dst, const target_ulong *src) |
65 | + cpu adjustments. Required for maintaining the correct | 25 | -{ |
66 | + icount valus | 26 | - dst[0] = src[0]; |
67 | * @return: true if state was restored, false otherwise | 27 | - dst[1] = src[1]; |
68 | * | 28 | - dst[2] = src[2]; |
69 | * Attempt to restore the state for a fault occurring in translated | 29 | - dst[3] = src[3]; |
70 | * code. If the searched_pc is not in translated code no state is | 30 | - dst[4] = src[4]; |
71 | * restored and the function returns false. | 31 | - dst[5] = src[5]; |
72 | */ | 32 | - dst[6] = src[6]; |
73 | -bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc); | 33 | - dst[7] = src[7]; |
74 | +bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc, bool will_exit); | 34 | -} |
75 | 35 | - | |
76 | void QEMU_NORETURN cpu_loop_exit_noexc(CPUState *cpu); | 36 | void cpu_set_cwp(CPUSPARCState *env, int new_cwp) |
77 | void QEMU_NORETURN cpu_io_recompile(CPUState *cpu, uintptr_t retaddr); | ||
78 | diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c | ||
79 | index XXXXXXX..XXXXXXX 100644 | ||
80 | --- a/accel/tcg/cpu-exec-common.c | ||
81 | +++ b/accel/tcg/cpu-exec-common.c | ||
82 | @@ -XXX,XX +XXX,XX @@ bool tcg_allowed; | ||
83 | /* exit the current TB, but without causing any exception to be raised */ | ||
84 | void cpu_loop_exit_noexc(CPUState *cpu) | ||
85 | { | 37 | { |
86 | - /* XXX: restore cpu registers saved in host registers */ | 38 | /* put the modified wrap registers at their proper location */ |
87 | - | 39 | if (env->cwp == env->nwindows - 1) { |
88 | cpu->exception_index = -1; | 40 | - memcpy32(env->regbase, env->regbase + env->nwindows * 16); |
89 | - siglongjmp(cpu->jmp_env, 1); | 41 | + memcpy(env->regbase, env->regbase + env->nwindows * 16, |
90 | + cpu_loop_exit(cpu); | 42 | + sizeof(env->gregs)); |
43 | } | ||
44 | env->cwp = new_cwp; | ||
45 | |||
46 | /* put the wrap registers at their temporary location */ | ||
47 | if (new_cwp == env->nwindows - 1) { | ||
48 | - memcpy32(env->regbase + env->nwindows * 16, env->regbase); | ||
49 | + memcpy(env->regbase + env->nwindows * 16, env->regbase, | ||
50 | + sizeof(env->gregs)); | ||
51 | } | ||
52 | env->regwptr = env->regbase + (new_cwp * 16); | ||
91 | } | 53 | } |
92 | 54 | @@ -XXX,XX +XXX,XX @@ void cpu_gl_switch_gregs(CPUSPARCState *env, uint32_t new_gl) | |
93 | #if defined(CONFIG_SOFTMMU) | 55 | dst = get_gl_gregset(env, env->gl); |
94 | @@ -XXX,XX +XXX,XX @@ void cpu_reloading_memory_map(void) | 56 | |
95 | 57 | if (src != dst) { | |
96 | void cpu_loop_exit(CPUState *cpu) | 58 | - memcpy32(dst, env->gregs); |
97 | { | 59 | - memcpy32(env->gregs, src); |
98 | + /* Undo the setting in cpu_tb_exec. */ | 60 | + memcpy(dst, env->gregs, sizeof(env->gregs)); |
99 | + cpu->can_do_io = 1; | 61 | + memcpy(env->gregs, src, sizeof(env->gregs)); |
100 | siglongjmp(cpu->jmp_env, 1); | ||
101 | } | ||
102 | |||
103 | void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc) | ||
104 | { | ||
105 | if (pc) { | ||
106 | - cpu_restore_state(cpu, pc); | ||
107 | + cpu_restore_state(cpu, pc, true); | ||
108 | } | ||
109 | - siglongjmp(cpu->jmp_env, 1); | ||
110 | + cpu_loop_exit(cpu); | ||
111 | } | ||
112 | |||
113 | void cpu_loop_exit_atomic(CPUState *cpu, uintptr_t pc) | ||
114 | diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c | ||
115 | index XXXXXXX..XXXXXXX 100644 | ||
116 | --- a/accel/tcg/cpu-exec.c | ||
117 | +++ b/accel/tcg/cpu-exec.c | ||
118 | @@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu) | ||
119 | g_assert(cpu == current_cpu); | ||
120 | g_assert(cc == CPU_GET_CLASS(cpu)); | ||
121 | #endif /* buggy compiler */ | ||
122 | - cpu->can_do_io = 1; | ||
123 | tb_lock_reset(); | ||
124 | if (qemu_mutex_iothread_locked()) { | ||
125 | qemu_mutex_unlock_iothread(); | ||
126 | diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c | ||
127 | index XXXXXXX..XXXXXXX 100644 | ||
128 | --- a/accel/tcg/translate-all.c | ||
129 | +++ b/accel/tcg/translate-all.c | ||
130 | @@ -XXX,XX +XXX,XX @@ static int encode_search(TranslationBlock *tb, uint8_t *block) | ||
131 | |||
132 | /* The cpu state corresponding to 'searched_pc' is restored. | ||
133 | * Called with tb_lock held. | ||
134 | + * When reset_icount is true, current TB will be interrupted and | ||
135 | + * icount should be recalculated. | ||
136 | */ | ||
137 | static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, | ||
138 | - uintptr_t searched_pc) | ||
139 | + uintptr_t searched_pc, bool reset_icount) | ||
140 | { | ||
141 | target_ulong data[TARGET_INSN_START_WORDS] = { tb->pc }; | ||
142 | uintptr_t host_pc = (uintptr_t)tb->tc.ptr; | ||
143 | @@ -XXX,XX +XXX,XX @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, | ||
144 | return -1; | ||
145 | |||
146 | found: | ||
147 | - if (tb->cflags & CF_USE_ICOUNT) { | ||
148 | + if (reset_icount && (tb->cflags & CF_USE_ICOUNT)) { | ||
149 | assert(use_icount); | ||
150 | - /* Reset the cycle counter to the start of the block. */ | ||
151 | - cpu->icount_decr.u16.low += num_insns; | ||
152 | - /* Clear the IO flag. */ | ||
153 | - cpu->can_do_io = 0; | ||
154 | + /* Reset the cycle counter to the start of the block | ||
155 | + and shift if to the number of actually executed instructions */ | ||
156 | + cpu->icount_decr.u16.low += num_insns - i; | ||
157 | } | ||
158 | - cpu->icount_decr.u16.low -= i; | ||
159 | restore_state_to_opc(env, tb, data); | ||
160 | |||
161 | #ifdef CONFIG_PROFILER | ||
162 | @@ -XXX,XX +XXX,XX @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | -bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc) | ||
167 | +bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit) | ||
168 | { | ||
169 | TranslationBlock *tb; | ||
170 | bool r = false; | ||
171 | @@ -XXX,XX +XXX,XX @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc) | ||
172 | tb_lock(); | ||
173 | tb = tb_find_pc(host_pc); | ||
174 | if (tb) { | ||
175 | - cpu_restore_state_from_tb(cpu, tb, host_pc); | ||
176 | + cpu_restore_state_from_tb(cpu, tb, host_pc, will_exit); | ||
177 | if (tb->cflags & CF_NOCACHE) { | ||
178 | /* one-shot translation, invalidate it immediately */ | ||
179 | tb_phys_invalidate(tb, -1); | ||
180 | @@ -XXX,XX +XXX,XX @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, | ||
181 | restore the CPU state */ | ||
182 | |||
183 | current_tb_modified = 1; | ||
184 | - cpu_restore_state_from_tb(cpu, current_tb, cpu->mem_io_pc); | ||
185 | + cpu_restore_state_from_tb(cpu, current_tb, | ||
186 | + cpu->mem_io_pc, true); | ||
187 | cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, | ||
188 | ¤t_flags); | ||
189 | } | ||
190 | @@ -XXX,XX +XXX,XX @@ static bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc) | ||
191 | restore the CPU state */ | ||
192 | |||
193 | current_tb_modified = 1; | ||
194 | - cpu_restore_state_from_tb(cpu, current_tb, pc); | ||
195 | + cpu_restore_state_from_tb(cpu, current_tb, pc, true); | ||
196 | cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, | ||
197 | ¤t_flags); | ||
198 | } | ||
199 | @@ -XXX,XX +XXX,XX @@ void tb_check_watchpoint(CPUState *cpu) | ||
200 | tb = tb_find_pc(cpu->mem_io_pc); | ||
201 | if (tb) { | ||
202 | /* We can use retranslation to find the PC. */ | ||
203 | - cpu_restore_state_from_tb(cpu, tb, cpu->mem_io_pc); | ||
204 | + cpu_restore_state_from_tb(cpu, tb, cpu->mem_io_pc, true); | ||
205 | tb_phys_invalidate(tb, -1); | ||
206 | } else { | ||
207 | /* The exception probably happened in a helper. The CPU state should | ||
208 | @@ -XXX,XX +XXX,XX @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr) | ||
209 | cpu_abort(cpu, "cpu_io_recompile: could not find TB for pc=%p", | ||
210 | (void *)retaddr); | ||
211 | } | ||
212 | - cpu_restore_state_from_tb(cpu, tb, retaddr); | ||
213 | + cpu_restore_state_from_tb(cpu, tb, retaddr, true); | ||
214 | |||
215 | /* On MIPS and SH, delay slot instructions can only be restarted if | ||
216 | they were already the first instruction in the TB. If this is not | ||
217 | diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c | ||
218 | index XXXXXXX..XXXXXXX 100644 | ||
219 | --- a/accel/tcg/user-exec.c | ||
220 | +++ b/accel/tcg/user-exec.c | ||
221 | @@ -XXX,XX +XXX,XX @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info, | ||
222 | } | ||
223 | |||
224 | /* Now we have a real cpu fault. */ | ||
225 | - cpu_restore_state(cpu, pc); | ||
226 | + cpu_restore_state(cpu, pc, true); | ||
227 | |||
228 | sigprocmask(SIG_SETMASK, old_set, NULL); | ||
229 | cpu_loop_exit(cpu); | ||
230 | diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c | ||
231 | index XXXXXXX..XXXXXXX 100644 | ||
232 | --- a/hw/misc/mips_itu.c | ||
233 | +++ b/hw/misc/mips_itu.c | ||
234 | @@ -XXX,XX +XXX,XX @@ static void wake_blocked_threads(ITCStorageCell *c) | ||
235 | static void QEMU_NORETURN block_thread_and_exit(ITCStorageCell *c) | ||
236 | { | ||
237 | c->blocked_threads |= 1ULL << current_cpu->cpu_index; | ||
238 | - cpu_restore_state(current_cpu, current_cpu->mem_io_pc); | ||
239 | current_cpu->halted = 1; | ||
240 | current_cpu->exception_index = EXCP_HLT; | ||
241 | - cpu_loop_exit(current_cpu); | ||
242 | + cpu_loop_exit_restore(current_cpu, current_cpu->mem_io_pc); | ||
243 | } | ||
244 | |||
245 | /* ITC Bypass View */ | ||
246 | diff --git a/target/alpha/helper.c b/target/alpha/helper.c | ||
247 | index XXXXXXX..XXXXXXX 100644 | ||
248 | --- a/target/alpha/helper.c | ||
249 | +++ b/target/alpha/helper.c | ||
250 | @@ -XXX,XX +XXX,XX @@ void QEMU_NORETURN dynamic_excp(CPUAlphaState *env, uintptr_t retaddr, | ||
251 | cs->exception_index = excp; | ||
252 | env->error_code = error; | ||
253 | if (retaddr) { | ||
254 | - cpu_restore_state(cs, retaddr); | ||
255 | + cpu_restore_state(cs, retaddr, true); | ||
256 | /* Floating-point exceptions (our only users) point to the next PC. */ | ||
257 | env->pc += 4; | ||
258 | } | ||
259 | diff --git a/target/alpha/mem_helper.c b/target/alpha/mem_helper.c | ||
260 | index XXXXXXX..XXXXXXX 100644 | ||
261 | --- a/target/alpha/mem_helper.c | ||
262 | +++ b/target/alpha/mem_helper.c | ||
263 | @@ -XXX,XX +XXX,XX @@ void alpha_cpu_do_unaligned_access(CPUState *cs, vaddr addr, | ||
264 | uint64_t pc; | ||
265 | uint32_t insn; | ||
266 | |||
267 | - cpu_restore_state(cs, retaddr); | ||
268 | + cpu_restore_state(cs, retaddr, true); | ||
269 | |||
270 | pc = env->pc; | ||
271 | insn = cpu_ldl_code(env, pc); | ||
272 | @@ -XXX,XX +XXX,XX @@ void alpha_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, | ||
273 | AlphaCPU *cpu = ALPHA_CPU(cs); | ||
274 | CPUAlphaState *env = &cpu->env; | ||
275 | |||
276 | - cpu_restore_state(cs, retaddr); | ||
277 | - | ||
278 | env->trap_arg0 = addr; | ||
279 | env->trap_arg1 = access_type == MMU_DATA_STORE ? 1 : 0; | ||
280 | cs->exception_index = EXCP_MCHK; | ||
281 | env->error_code = 0; | ||
282 | - cpu_loop_exit(cs); | ||
283 | + cpu_loop_exit_restore(cs, retaddr); | ||
284 | } | ||
285 | |||
286 | /* try to fill the TLB and return an exception if error. If retaddr is | ||
287 | diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c | ||
288 | index XXXXXXX..XXXXXXX 100644 | ||
289 | --- a/target/arm/op_helper.c | ||
290 | +++ b/target/arm/op_helper.c | ||
291 | @@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong addr, int size, | ||
292 | ARMCPU *cpu = ARM_CPU(cs); | ||
293 | |||
294 | /* now we have a real cpu fault */ | ||
295 | - cpu_restore_state(cs, retaddr); | ||
296 | + cpu_restore_state(cs, retaddr, true); | ||
297 | |||
298 | deliver_fault(cpu, addr, access_type, mmu_idx, &fi); | ||
299 | } | ||
300 | @@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, | ||
301 | ARMMMUFaultInfo fi = {}; | ||
302 | |||
303 | /* now we have a real cpu fault */ | ||
304 | - cpu_restore_state(cs, retaddr); | ||
305 | + cpu_restore_state(cs, retaddr, true); | ||
306 | |||
307 | fi.type = ARMFault_Alignment; | ||
308 | deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi); | ||
309 | @@ -XXX,XX +XXX,XX @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, | ||
310 | ARMMMUFaultInfo fi = {}; | ||
311 | |||
312 | /* now we have a real cpu fault */ | ||
313 | - cpu_restore_state(cs, retaddr); | ||
314 | + cpu_restore_state(cs, retaddr, true); | ||
315 | |||
316 | fi.ea = arm_extabort_type(response); | ||
317 | fi.type = ARMFault_SyncExternal; | ||
318 | diff --git a/target/cris/op_helper.c b/target/cris/op_helper.c | ||
319 | index XXXXXXX..XXXXXXX 100644 | ||
320 | --- a/target/cris/op_helper.c | ||
321 | +++ b/target/cris/op_helper.c | ||
322 | @@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong addr, int size, | ||
323 | if (unlikely(ret)) { | ||
324 | if (retaddr) { | ||
325 | /* now we have a real cpu fault */ | ||
326 | - if (cpu_restore_state(cs, retaddr)) { | ||
327 | - /* Evaluate flags after retranslation. */ | ||
328 | + if (cpu_restore_state(cs, retaddr, true)) { | ||
329 | + /* Evaluate flags after retranslation. */ | ||
330 | helper_top_evaluate_flags(env); | ||
331 | } | ||
332 | } | ||
333 | diff --git a/target/i386/helper.c b/target/i386/helper.c | ||
334 | index XXXXXXX..XXXXXXX 100644 | ||
335 | --- a/target/i386/helper.c | ||
336 | +++ b/target/i386/helper.c | ||
337 | @@ -XXX,XX +XXX,XX @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) | ||
338 | |||
339 | cpu_interrupt(cs, CPU_INTERRUPT_TPR); | ||
340 | } else if (tcg_enabled()) { | ||
341 | - cpu_restore_state(cs, cs->mem_io_pc); | ||
342 | + cpu_restore_state(cs, cs->mem_io_pc, false); | ||
343 | |||
344 | apic_handle_tpr_access_report(cpu->apic_state, env->eip, access); | ||
345 | } | ||
346 | diff --git a/target/i386/svm_helper.c b/target/i386/svm_helper.c | ||
347 | index XXXXXXX..XXXXXXX 100644 | ||
348 | --- a/target/i386/svm_helper.c | ||
349 | +++ b/target/i386/svm_helper.c | ||
350 | @@ -XXX,XX +XXX,XX @@ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1, | ||
351 | { | ||
352 | CPUState *cs = CPU(x86_env_get_cpu(env)); | ||
353 | |||
354 | - cpu_restore_state(cs, retaddr); | ||
355 | + cpu_restore_state(cs, retaddr, true); | ||
356 | |||
357 | qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016" | ||
358 | PRIx64 ", " TARGET_FMT_lx ")!\n", | ||
359 | diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c | ||
360 | index XXXXXXX..XXXXXXX 100644 | ||
361 | --- a/target/m68k/op_helper.c | ||
362 | +++ b/target/m68k/op_helper.c | ||
363 | @@ -XXX,XX +XXX,XX @@ void HELPER(chk)(CPUM68KState *env, int32_t val, int32_t ub) | ||
364 | CPUState *cs = CPU(m68k_env_get_cpu(env)); | ||
365 | |||
366 | /* Recover PC and CC_OP for the beginning of the insn. */ | ||
367 | - cpu_restore_state(cs, GETPC()); | ||
368 | + cpu_restore_state(cs, GETPC(), true); | ||
369 | |||
370 | /* flags have been modified by gen_flush_flags() */ | ||
371 | env->cc_op = CC_OP_FLAGS; | ||
372 | @@ -XXX,XX +XXX,XX @@ void HELPER(chk2)(CPUM68KState *env, int32_t val, int32_t lb, int32_t ub) | ||
373 | CPUState *cs = CPU(m68k_env_get_cpu(env)); | ||
374 | |||
375 | /* Recover PC and CC_OP for the beginning of the insn. */ | ||
376 | - cpu_restore_state(cs, GETPC()); | ||
377 | + cpu_restore_state(cs, GETPC(), true); | ||
378 | |||
379 | /* flags have been modified by gen_flush_flags() */ | ||
380 | env->cc_op = CC_OP_FLAGS; | ||
381 | diff --git a/target/moxie/helper.c b/target/moxie/helper.c | ||
382 | index XXXXXXX..XXXXXXX 100644 | ||
383 | --- a/target/moxie/helper.c | ||
384 | +++ b/target/moxie/helper.c | ||
385 | @@ -XXX,XX +XXX,XX @@ void helper_raise_exception(CPUMoxieState *env, int ex) | ||
386 | /* Stash the exception type. */ | ||
387 | env->sregs[2] = ex; | ||
388 | /* Stash the address where the exception occurred. */ | ||
389 | - cpu_restore_state(cs, GETPC()); | ||
390 | + cpu_restore_state(cs, GETPC(), true); | ||
391 | env->sregs[5] = env->pc; | ||
392 | /* Jump to the exception handline routine. */ | ||
393 | env->pc = env->sregs[1]; | ||
394 | diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c | ||
395 | index XXXXXXX..XXXXXXX 100644 | ||
396 | --- a/target/openrisc/sys_helper.c | ||
397 | +++ b/target/openrisc/sys_helper.c | ||
398 | @@ -XXX,XX +XXX,XX @@ void HELPER(mtspr)(CPUOpenRISCState *env, | ||
399 | break; | ||
400 | |||
401 | case TO_SPR(0, 16): /* NPC */ | ||
402 | - cpu_restore_state(cs, GETPC()); | ||
403 | + cpu_restore_state(cs, GETPC(), true); | ||
404 | /* ??? Mirror or1ksim in not trashing delayed branch state | ||
405 | when "jumping" to the current instruction. */ | ||
406 | if (env->pc != rb) { | ||
407 | @@ -XXX,XX +XXX,XX @@ void HELPER(mtspr)(CPUOpenRISCState *env, | ||
408 | case TO_SPR(8, 0): /* PMR */ | ||
409 | env->pmr = rb; | ||
410 | if (env->pmr & PMR_DME || env->pmr & PMR_SME) { | ||
411 | - cpu_restore_state(cs, GETPC()); | ||
412 | + cpu_restore_state(cs, GETPC(), true); | ||
413 | env->pc += 4; | ||
414 | cs->halted = 1; | ||
415 | raise_exception(cpu, EXCP_HALTED); | ||
416 | @@ -XXX,XX +XXX,XX @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, | ||
417 | return env->evbar; | ||
418 | |||
419 | case TO_SPR(0, 16): /* NPC (equals PC) */ | ||
420 | - cpu_restore_state(cs, GETPC()); | ||
421 | + cpu_restore_state(cs, GETPC(), false); | ||
422 | return env->pc; | ||
423 | |||
424 | case TO_SPR(0, 17): /* SR */ | ||
425 | return cpu_get_sr(env); | ||
426 | |||
427 | case TO_SPR(0, 18): /* PPC */ | ||
428 | - cpu_restore_state(cs, GETPC()); | ||
429 | + cpu_restore_state(cs, GETPC(), false); | ||
430 | return env->ppc; | ||
431 | |||
432 | case TO_SPR(0, 32): /* EPCR */ | ||
433 | diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c | ||
434 | index XXXXXXX..XXXXXXX 100644 | ||
435 | --- a/target/tricore/op_helper.c | ||
436 | +++ b/target/tricore/op_helper.c | ||
437 | @@ -XXX,XX +XXX,XX @@ raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin, | ||
438 | { | ||
439 | CPUState *cs = CPU(tricore_env_get_cpu(env)); | ||
440 | /* in case we come from a helper-call we need to restore the PC */ | ||
441 | - cpu_restore_state(cs, pc); | ||
442 | + cpu_restore_state(cs, pc, true); | ||
443 | |||
444 | /* Tin is loaded into d[15] */ | ||
445 | env->gpr_d[15] = tin; | ||
446 | diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c | ||
447 | index XXXXXXX..XXXXXXX 100644 | ||
448 | --- a/target/xtensa/op_helper.c | ||
449 | +++ b/target/xtensa/op_helper.c | ||
450 | @@ -XXX,XX +XXX,XX @@ void xtensa_cpu_do_unaligned_access(CPUState *cs, | ||
451 | |||
452 | if (xtensa_option_enabled(env->config, XTENSA_OPTION_UNALIGNED_EXCEPTION) && | ||
453 | !xtensa_option_enabled(env->config, XTENSA_OPTION_HW_ALIGNMENT)) { | ||
454 | - cpu_restore_state(CPU(cpu), retaddr); | ||
455 | + cpu_restore_state(CPU(cpu), retaddr, true); | ||
456 | HELPER(exception_cause_vaddr)(env, | ||
457 | env->pc, LOAD_STORE_ALIGNMENT_CAUSE, addr); | ||
458 | } | ||
459 | @@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong vaddr, int size, | ||
460 | paddr & TARGET_PAGE_MASK, | ||
461 | access, mmu_idx, page_size); | ||
462 | } else { | ||
463 | - cpu_restore_state(cs, retaddr); | ||
464 | + cpu_restore_state(cs, retaddr, true); | ||
465 | HELPER(exception_cause_vaddr)(env, env->pc, ret, vaddr); | ||
466 | } | 62 | } |
467 | } | 63 | } |
64 | |||
65 | @@ -XXX,XX +XXX,XX @@ void cpu_change_pstate(CPUSPARCState *env, uint32_t new_pstate) | ||
66 | /* Switch global register bank */ | ||
67 | src = get_gregset(env, new_pstate_regs); | ||
68 | dst = get_gregset(env, pstate_regs); | ||
69 | - memcpy32(dst, env->gregs); | ||
70 | - memcpy32(env->gregs, src); | ||
71 | + memcpy(dst, env->gregs, sizeof(env->gregs)); | ||
72 | + memcpy(env->gregs, src, sizeof(env->gregs)); | ||
73 | } else { | ||
74 | trace_win_helper_no_switch_pstate(new_pstate_regs); | ||
75 | } | ||
468 | -- | 76 | -- |
469 | 2.14.3 | 77 | 2.43.0 |
470 | 78 | ||
471 | 79 | diff view generated by jsdifflib |