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, ¤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 | } | ||
467 | } | ||
468 | -- | 74 | -- |
469 | 2.14.3 | 75 | 2.20.1 |
470 | 76 | ||
471 | 77 | diff view generated by jsdifflib |