Skip to content

Commit cf9b579

Browse files
committed
accel/tcg: Remove CF_LAST_IO
In cpu_exec_step_atomic, we did not set CF_LAST_IO, which lead to a loop with cpu_io_recompile. But since 18a536f ("Always require can_do_io") we no longer need a flag to indicate when the last insn should have can_do_io set, so remove the flag entirely. Reported-by: Clément Chigot <chigot@adacore.com> Tested-by: Clément Chigot <chigot@adacore.com> Reviewed-by: Claudio Fontana <cfontana@suse.de> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1961 Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
1 parent 6d44474 commit cf9b579

File tree

7 files changed

+22
-37
lines changed

7 files changed

+22
-37
lines changed

accel/tcg/cpu-exec.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
721721
&& cpu->neg.icount_decr.u16.low + cpu->icount_extra == 0) {
722722
/* Execute just one insn to trigger exception pending in the log */
723723
cpu->cflags_next_tb = (curr_cflags(cpu) & ~CF_USE_ICOUNT)
724-
| CF_LAST_IO | CF_NOIRQ | 1;
724+
| CF_NOIRQ | 1;
725725
}
726726
#endif
727727
return false;

accel/tcg/tb-maint.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -1083,8 +1083,7 @@ bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc)
10831083
if (current_tb_modified) {
10841084
/* Force execution of one insn next time. */
10851085
CPUState *cpu = current_cpu;
1086-
cpu->cflags_next_tb =
1087-
1 | CF_LAST_IO | CF_NOIRQ | curr_cflags(current_cpu);
1086+
cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(current_cpu);
10881087
return true;
10891088
}
10901089
return false;
@@ -1154,8 +1153,7 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
11541153
if (current_tb_modified) {
11551154
page_collection_unlock(pages);
11561155
/* Force execution of one insn next time. */
1157-
current_cpu->cflags_next_tb =
1158-
1 | CF_LAST_IO | CF_NOIRQ | curr_cflags(current_cpu);
1156+
current_cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(current_cpu);
11591157
mmap_unlock();
11601158
cpu_loop_exit_noexc(current_cpu);
11611159
}

accel/tcg/translate-all.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
304304

305305
if (phys_pc == -1) {
306306
/* Generate a one-shot TB with 1 insn in it */
307-
cflags = (cflags & ~CF_COUNT_MASK) | CF_LAST_IO | 1;
307+
cflags = (cflags & ~CF_COUNT_MASK) | 1;
308308
}
309309

310310
max_insns = cflags & CF_COUNT_MASK;
@@ -632,7 +632,7 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr)
632632
* operations only (which execute after completion) so we don't
633633
* double instrument the instruction.
634634
*/
635-
cpu->cflags_next_tb = curr_cflags(cpu) | CF_MEMI_ONLY | CF_LAST_IO | n;
635+
cpu->cflags_next_tb = curr_cflags(cpu) | CF_MEMI_ONLY | n;
636636

637637
if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
638638
vaddr pc = log_pc(cpu, tb);

accel/tcg/translator.c

+9-13
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ static TCGOp *gen_tb_start(DisasContextBase *db, uint32_t cflags)
8989
* each translation block. The cost is minimal, plus it would be
9090
* very easy to forget doing it in the translator.
9191
*/
92-
set_can_do_io(db, db->max_insns == 1 && (cflags & CF_LAST_IO));
92+
set_can_do_io(db, db->max_insns == 1);
9393

9494
return icount_start_insn;
9595
}
@@ -151,13 +151,7 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
151151
ops->tb_start(db, cpu);
152152
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
153153

154-
if (cflags & CF_MEMI_ONLY) {
155-
/* We should only see CF_MEMI_ONLY for io_recompile. */
156-
assert(cflags & CF_LAST_IO);
157-
plugin_enabled = plugin_gen_tb_start(cpu, db, true);
158-
} else {
159-
plugin_enabled = plugin_gen_tb_start(cpu, db, false);
160-
}
154+
plugin_enabled = plugin_gen_tb_start(cpu, db, cflags & CF_MEMI_ONLY);
161155
db->plugin_enabled = plugin_enabled;
162156

163157
while (true) {
@@ -169,11 +163,13 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
169163
plugin_gen_insn_start(cpu, db);
170164
}
171165

172-
/* Disassemble one instruction. The translate_insn hook should
173-
update db->pc_next and db->is_jmp to indicate what should be
174-
done next -- either exiting this loop or locate the start of
175-
the next instruction. */
176-
if (db->num_insns == db->max_insns && (cflags & CF_LAST_IO)) {
166+
/*
167+
* Disassemble one instruction. The translate_insn hook should
168+
* update db->pc_next and db->is_jmp to indicate what should be
169+
* done next -- either exiting this loop or locate the start of
170+
* the next instruction.
171+
*/
172+
if (db->num_insns == db->max_insns) {
177173
/* Accept I/O on the last instruction. */
178174
set_can_do_io(db, true);
179175
}

docs/devel/tcg-icount.rst

-6
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,6 @@ To deal with this case, when an I/O access is made we:
6262
- re-compile a single [1]_ instruction block for the current PC
6363
- exit the cpu loop and execute the re-compiled block
6464

65-
The new block is created with the CF_LAST_IO compile flag which
66-
ensures the final instruction translation starts with a call to
67-
gen_io_start() so we don't enter a perpetual loop constantly
68-
recompiling a single instruction block. For translators using the
69-
common translator_loop this is done automatically.
70-
7165
.. [1] sometimes two instructions if dealing with delay slots
7266
7367
Other I/O operations

include/exec/translation-block.h

+6-7
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,12 @@ struct TranslationBlock {
7171
#define CF_NO_GOTO_TB 0x00000200 /* Do not chain with goto_tb */
7272
#define CF_NO_GOTO_PTR 0x00000400 /* Do not chain with goto_ptr */
7373
#define CF_SINGLE_STEP 0x00000800 /* gdbstub single-step in effect */
74-
#define CF_LAST_IO 0x00008000 /* Last insn may be an IO access. */
75-
#define CF_MEMI_ONLY 0x00010000 /* Only instrument memory ops */
76-
#define CF_USE_ICOUNT 0x00020000
77-
#define CF_INVALID 0x00040000 /* TB is stale. Set with @jmp_lock held */
78-
#define CF_PARALLEL 0x00080000 /* Generate code for a parallel context */
79-
#define CF_NOIRQ 0x00100000 /* Generate an uninterruptible TB */
80-
#define CF_PCREL 0x00200000 /* Opcodes in TB are PC-relative */
74+
#define CF_MEMI_ONLY 0x00001000 /* Only instrument memory ops */
75+
#define CF_USE_ICOUNT 0x00002000
76+
#define CF_INVALID 0x00004000 /* TB is stale. Set with @jmp_lock held */
77+
#define CF_PARALLEL 0x00008000 /* Generate code for a parallel context */
78+
#define CF_NOIRQ 0x00010000 /* Generate an uninterruptible TB */
79+
#define CF_PCREL 0x00020000 /* Opcodes in TB are PC-relative */
8180
#define CF_CLUSTER_MASK 0xff000000 /* Top 8 bits are cluster ID */
8281
#define CF_CLUSTER_SHIFT 24
8382

system/watchpoint.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,7 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
179179
*/
180180
if (!cpu->neg.can_do_io) {
181181
/* Force execution of one insn next time. */
182-
cpu->cflags_next_tb = 1 | CF_LAST_IO | CF_NOIRQ
183-
| curr_cflags(cpu);
182+
cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu);
184183
cpu_loop_exit_restore(cpu, ra);
185184
}
186185
/*
@@ -212,8 +211,7 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
212211
cpu_loop_exit(cpu);
213212
} else {
214213
/* Force execution of one insn next time. */
215-
cpu->cflags_next_tb = 1 | CF_LAST_IO | CF_NOIRQ
216-
| curr_cflags(cpu);
214+
cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu);
217215
mmap_unlock();
218216
cpu_loop_exit_noexc(cpu);
219217
}

0 commit comments

Comments
 (0)