1
The following changes since commit 26d6a7c87b05017ffabffb5e16837a0fccf67e90:
1
The following changes since commit e18e5501d8ac692d32657a3e1ef545b14e72b730:
2
2
3
Merge remote-tracking branch 'remotes/ericb/tags/pull-qapi-2018-04-10' into staging (2018-04-10 22:16:19 +0100)
3
Merge remote-tracking branch 'remotes/dgilbert-gitlab/tags/pull-virtiofs-20200210' into staging (2020-02-10 18:09:14 +0000)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git://github.com/rth7680/qemu.git tags/pull-tcg-20180411
7
https://github.com/rth7680/qemu.git tags/pull-tcg-20200212
8
8
9
for you to fetch changes up to afd46fcad2dceffda35c0586f5723c127b6e09d8:
9
for you to fetch changes up to 2445971604c1cfd3ec484457159f4ac300fb04d2:
10
10
11
icount: fix cpu_restore_state_from_tb for non-tb-exit cases (2018-04-11 09:05:22 +1000)
11
tcg: Add tcg_gen_gvec_5_ptr (2020-02-12 14:58:36 -0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Handle read-modify-write i/o with icount
14
Fix breakpoint invalidation.
15
Add support for tcg helpers with 7 arguments.
16
Add support for gvec helpers with 5 arguments.
15
17
16
----------------------------------------------------------------
18
----------------------------------------------------------------
17
Pavel Dovgalyuk (1):
19
Max Filippov (1):
18
icount: fix cpu_restore_state_from_tb for non-tb-exit cases
20
exec: flush CPU TB cache in breakpoint_invalidate
19
21
20
include/exec/exec-all.h | 5 ++++-
22
Richard Henderson (1):
21
accel/tcg/cpu-exec-common.c | 10 +++++-----
23
tcg: Add tcg_gen_gvec_5_ptr
22
accel/tcg/cpu-exec.c | 1 -
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
24
25
Taylor Simpson (1):
26
tcg: Add support for a helper with 7 arguments
27
28
include/exec/helper-gen.h | 13 +++++++++++++
29
include/exec/helper-head.h | 2 ++
30
include/exec/helper-proto.h | 6 ++++++
31
include/exec/helper-tcg.h | 7 +++++++
32
include/tcg/tcg-op-gvec.h | 7 +++++++
33
exec.c | 15 +++++++--------
34
tcg/tcg-op-gvec.c | 32 ++++++++++++++++++++++++++++++++
35
7 files changed, 74 insertions(+), 8 deletions(-)
36
diff view generated by jsdifflib
New patch
1
From: Max Filippov <jcmvbkbc@gmail.com>
1
2
3
When a breakpoint is inserted at location for which there's currently no
4
virtual to physical translation no action is taken on CPU TB cache. If a
5
TB for that virtual address already exists but is not visible ATM the
6
breakpoint won't be hit next time an instruction at that address will be
7
executed.
8
9
Flush entire CPU TB cache in breakpoint_invalidate to force
10
re-translation of all TBs for the breakpoint address.
11
12
This change fixes the following scenario:
13
- linux user application is running
14
- a breakpoint is inserted from QEMU gdbstub for a user address that is
15
not currently present in the target CPU TLB
16
- an instruction at that address is executed, but the external debugger
17
doesn't get control.
18
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
21
Message-Id: <20191127220602.10827-2-jcmvbkbc@gmail.com>
22
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
23
---
24
exec.c | 15 +++++++--------
25
1 file changed, 7 insertions(+), 8 deletions(-)
26
27
diff --git a/exec.c b/exec.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/exec.c
30
+++ b/exec.c
31
@@ -XXX,XX +XXX,XX @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
32
33
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
34
{
35
- MemTxAttrs attrs;
36
- hwaddr phys = cpu_get_phys_page_attrs_debug(cpu, pc, &attrs);
37
- int asidx = cpu_asidx_from_attrs(cpu, attrs);
38
- if (phys != -1) {
39
- /* Locks grabbed by tb_invalidate_phys_addr */
40
- tb_invalidate_phys_addr(cpu->cpu_ases[asidx].as,
41
- phys | (pc & ~TARGET_PAGE_MASK), attrs);
42
- }
43
+ /*
44
+ * There may not be a virtual to physical translation for the pc
45
+ * right now, but there may exist cached TB for this pc.
46
+ * Flush the whole TB cache to force re-translation of such TBs.
47
+ * This is heavyweight, but we're debugging anyway.
48
+ */
49
+ tb_flush(cpu);
50
}
51
#endif
52
53
--
54
2.20.1
55
56
diff view generated by jsdifflib
New patch
1
From: Taylor Simpson <tsimpson@quicinc.com>
1
2
3
Currently, helpers can only take up to 6 arguments. This patch adds the
4
capability for up to 7 arguments. I have tested it with the Hexagon port
5
that I am preparing for submission.
6
7
Signed-off-by: Taylor Simpson <tsimpson@quicinc.com>
8
Message-Id: <1580942510-2820-1-git-send-email-tsimpson@quicinc.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
---
11
include/exec/helper-gen.h | 13 +++++++++++++
12
include/exec/helper-head.h | 2 ++
13
include/exec/helper-proto.h | 6 ++++++
14
include/exec/helper-tcg.h | 7 +++++++
15
4 files changed, 28 insertions(+)
16
17
diff --git a/include/exec/helper-gen.h b/include/exec/helper-gen.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/helper-gen.h
20
+++ b/include/exec/helper-gen.h
21
@@ -XXX,XX +XXX,XX @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
22
tcg_gen_callN(HELPER(name), dh_retvar(ret), 6, args); \
23
}
24
25
+#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7)\
26
+static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
27
+ dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
28
+ dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6), \
29
+ dh_arg_decl(t7, 7)) \
30
+{ \
31
+ TCGTemp *args[7] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
32
+ dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6), \
33
+ dh_arg(t7, 7) }; \
34
+ tcg_gen_callN(HELPER(name), dh_retvar(ret), 7, args); \
35
+}
36
+
37
#include "helper.h"
38
#include "trace/generated-helpers.h"
39
#include "trace/generated-helpers-wrappers.h"
40
@@ -XXX,XX +XXX,XX @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
41
#undef DEF_HELPER_FLAGS_4
42
#undef DEF_HELPER_FLAGS_5
43
#undef DEF_HELPER_FLAGS_6
44
+#undef DEF_HELPER_FLAGS_7
45
#undef GEN_HELPER
46
47
#endif /* HELPER_GEN_H */
48
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/include/exec/helper-head.h
51
+++ b/include/exec/helper-head.h
52
@@ -XXX,XX +XXX,XX @@
53
DEF_HELPER_FLAGS_5(name, 0, ret, t1, t2, t3, t4, t5)
54
#define DEF_HELPER_6(name, ret, t1, t2, t3, t4, t5, t6) \
55
DEF_HELPER_FLAGS_6(name, 0, ret, t1, t2, t3, t4, t5, t6)
56
+#define DEF_HELPER_7(name, ret, t1, t2, t3, t4, t5, t6, t7) \
57
+ DEF_HELPER_FLAGS_7(name, 0, ret, t1, t2, t3, t4, t5, t6, t7)
58
59
/* MAX_OPC_PARAM_IARGS must be set to n if last entry is DEF_HELPER_FLAGS_n. */
60
61
diff --git a/include/exec/helper-proto.h b/include/exec/helper-proto.h
62
index XXXXXXX..XXXXXXX 100644
63
--- a/include/exec/helper-proto.h
64
+++ b/include/exec/helper-proto.h
65
@@ -XXX,XX +XXX,XX @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
66
dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
67
dh_ctype(t4), dh_ctype(t5), dh_ctype(t6));
68
69
+#define DEF_HELPER_FLAGS_7(name, flags, ret, t1, t2, t3, t4, t5, t6, t7) \
70
+dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
71
+ dh_ctype(t4), dh_ctype(t5), dh_ctype(t6), \
72
+ dh_ctype(t7));
73
+
74
#include "helper.h"
75
#include "trace/generated-helpers.h"
76
#include "tcg-runtime.h"
77
@@ -XXX,XX +XXX,XX @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), \
78
#undef DEF_HELPER_FLAGS_4
79
#undef DEF_HELPER_FLAGS_5
80
#undef DEF_HELPER_FLAGS_6
81
+#undef DEF_HELPER_FLAGS_7
82
83
#endif /* HELPER_PROTO_H */
84
diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h
85
index XXXXXXX..XXXXXXX 100644
86
--- a/include/exec/helper-tcg.h
87
+++ b/include/exec/helper-tcg.h
88
@@ -XXX,XX +XXX,XX @@
89
| dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
90
| dh_sizemask(t5, 5) | dh_sizemask(t6, 6) },
91
92
+#define DEF_HELPER_FLAGS_7(NAME, FLAGS, ret, t1, t2, t3, t4, t5, t6, t7) \
93
+ { .func = HELPER(NAME), .name = str(NAME), .flags = FLAGS, \
94
+ .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
95
+ | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
96
+ | dh_sizemask(t5, 5) | dh_sizemask(t6, 6) | dh_sizemask(t7, 7) },
97
+
98
#include "helper.h"
99
#include "trace/generated-helpers.h"
100
#include "tcg-runtime.h"
101
@@ -XXX,XX +XXX,XX @@
102
#undef DEF_HELPER_FLAGS_4
103
#undef DEF_HELPER_FLAGS_5
104
#undef DEF_HELPER_FLAGS_6
105
+#undef DEF_HELPER_FLAGS_7
106
107
#endif /* HELPER_TCG_H */
108
--
109
2.20.1
110
111
diff view generated by jsdifflib
1
From: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
1
Extend the vector generator infrastructure to handle
2
5 vector arguments.
2
3
3
In icount mode, instructions that access io memory spaces in the middle
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
of the translation block invoke TB recompilation. After recompilation,
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
such instructions become last in the TB and are allowed to access io
6
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
6
memory spaces.
7
8
When the code includes instruction like i386 'xchg eax, 0xffffd080'
9
which accesses APIC, QEMU goes into an infinite loop of the recompilation.
10
11
This instruction includes two memory accesses - one read and one write.
12
After the first access, APIC calls cpu_report_tpr_access, which restores
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>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
36
---
8
---
37
include/exec/exec-all.h | 5 ++++-
9
include/tcg/tcg-op-gvec.h | 7 +++++++
38
accel/tcg/cpu-exec-common.c | 10 +++++-----
10
tcg/tcg-op-gvec.c | 32 ++++++++++++++++++++++++++++++++
39
accel/tcg/cpu-exec.c | 1 -
11
2 files changed, 39 insertions(+)
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
12
56
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
13
diff --git a/include/tcg/tcg-op-gvec.h b/include/tcg/tcg-op-gvec.h
57
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
58
--- a/include/exec/exec-all.h
15
--- a/include/tcg/tcg-op-gvec.h
59
+++ b/include/exec/exec-all.h
16
+++ b/include/tcg/tcg-op-gvec.h
60
@@ -XXX,XX +XXX,XX @@ void cpu_gen_init(void);
17
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_4_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
61
* cpu_restore_state:
18
uint32_t maxsz, int32_t data,
62
* @cpu: the vCPU state is to be restore to
19
gen_helper_gvec_4_ptr *fn);
63
* @searched_pc: the host PC the fault occurred at
20
64
+ * @will_exit: true if the TB executed will be interrupted after some
21
+typedef void gen_helper_gvec_5_ptr(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr,
65
+ cpu adjustments. Required for maintaining the correct
22
+ TCGv_ptr, TCGv_ptr, TCGv_i32);
66
+ icount valus
23
+void tcg_gen_gvec_5_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
67
* @return: true if state was restored, false otherwise
24
+ uint32_t cofs, uint32_t eofs, TCGv_ptr ptr,
68
*
25
+ uint32_t oprsz, uint32_t maxsz, int32_t data,
69
* Attempt to restore the state for a fault occurring in translated
26
+ gen_helper_gvec_5_ptr *fn);
70
* code. If the searched_pc is not in translated code no state is
27
+
71
* restored and the function returns false.
28
/* Expand a gvec operation. Either inline or out-of-line depending on
72
*/
29
the actual vector size and the operations supported by the host. */
73
-bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc);
30
typedef struct {
74
+bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc, bool will_exit);
31
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
75
76
void QEMU_NORETURN cpu_loop_exit_noexc(CPUState *cpu);
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
32
index XXXXXXX..XXXXXXX 100644
80
--- a/accel/tcg/cpu-exec-common.c
33
--- a/tcg/tcg-op-gvec.c
81
+++ b/accel/tcg/cpu-exec-common.c
34
+++ b/tcg/tcg-op-gvec.c
82
@@ -XXX,XX +XXX,XX @@ bool tcg_allowed;
35
@@ -XXX,XX +XXX,XX @@ void tcg_gen_gvec_4_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
83
/* exit the current TB, but without causing any exception to be raised */
36
tcg_temp_free_i32(desc);
84
void cpu_loop_exit_noexc(CPUState *cpu)
85
{
86
- /* XXX: restore cpu registers saved in host registers */
87
-
88
cpu->exception_index = -1;
89
- siglongjmp(cpu->jmp_env, 1);
90
+ cpu_loop_exit(cpu);
91
}
37
}
92
38
93
#if defined(CONFIG_SOFTMMU)
39
+/* Generate a call to a gvec-style helper with five vector operands
94
@@ -XXX,XX +XXX,XX @@ void cpu_reloading_memory_map(void)
40
+ and an extra pointer operand. */
95
41
+void tcg_gen_gvec_5_ptr(uint32_t dofs, uint32_t aofs, uint32_t bofs,
96
void cpu_loop_exit(CPUState *cpu)
42
+ uint32_t cofs, uint32_t eofs, TCGv_ptr ptr,
97
{
43
+ uint32_t oprsz, uint32_t maxsz, int32_t data,
98
+ /* Undo the setting in cpu_tb_exec. */
44
+ gen_helper_gvec_5_ptr *fn)
99
+ cpu->can_do_io = 1;
45
+{
100
siglongjmp(cpu->jmp_env, 1);
46
+ TCGv_ptr a0, a1, a2, a3, a4;
101
}
47
+ TCGv_i32 desc = tcg_const_i32(simd_desc(oprsz, maxsz, data));
102
48
+
103
void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc)
49
+ a0 = tcg_temp_new_ptr();
104
{
50
+ a1 = tcg_temp_new_ptr();
105
if (pc) {
51
+ a2 = tcg_temp_new_ptr();
106
- cpu_restore_state(cpu, pc);
52
+ a3 = tcg_temp_new_ptr();
107
+ cpu_restore_state(cpu, pc, true);
53
+ a4 = tcg_temp_new_ptr();
108
}
54
+
109
- siglongjmp(cpu->jmp_env, 1);
55
+ tcg_gen_addi_ptr(a0, cpu_env, dofs);
110
+ cpu_loop_exit(cpu);
56
+ tcg_gen_addi_ptr(a1, cpu_env, aofs);
111
}
57
+ tcg_gen_addi_ptr(a2, cpu_env, bofs);
112
58
+ tcg_gen_addi_ptr(a3, cpu_env, cofs);
113
void cpu_loop_exit_atomic(CPUState *cpu, uintptr_t pc)
59
+ tcg_gen_addi_ptr(a4, cpu_env, eofs);
114
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
60
+
115
index XXXXXXX..XXXXXXX 100644
61
+ fn(a0, a1, a2, a3, a4, ptr, desc);
116
--- a/accel/tcg/cpu-exec.c
62
+
117
+++ b/accel/tcg/cpu-exec.c
63
+ tcg_temp_free_ptr(a0);
118
@@ -XXX,XX +XXX,XX @@ int cpu_exec(CPUState *cpu)
64
+ tcg_temp_free_ptr(a1);
119
g_assert(cpu == current_cpu);
65
+ tcg_temp_free_ptr(a2);
120
g_assert(cc == CPU_GET_CLASS(cpu));
66
+ tcg_temp_free_ptr(a3);
121
#endif /* buggy compiler */
67
+ tcg_temp_free_ptr(a4);
122
- cpu->can_do_io = 1;
68
+ tcg_temp_free_i32(desc);
123
tb_lock_reset();
69
+}
124
if (qemu_mutex_iothread_locked()) {
70
+
125
qemu_mutex_unlock_iothread();
71
/* Return true if we want to implement something of OPRSZ bytes
126
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
72
in units of LNSZ. This limits the expansion of inline code. */
127
index XXXXXXX..XXXXXXX 100644
73
static inline bool check_size_impl(uint32_t oprsz, uint32_t lnsz)
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, &current_pc, &current_cs_base,
188
&current_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, &current_pc, &current_cs_base,
197
&current_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
}
467
}
468
--
74
--
469
2.14.3
75
2.20.1
470
76
471
77
diff view generated by jsdifflib