mirror of https://github.com/xemu-project/xemu.git
accel/tcg: Always require can_do_io, for #1866
-----BEGIN PGP SIGNATURE----- iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmUV1sgdHHJpY2hhcmQu aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/8UAgAjFSrUvW5cGTiaow7 cTvvoFnQzVCM7gFbC2T9W29Hrv0s3tqJHSdUFftzzMXB1atylwb85XN5wegC98zk 7+OzrUvTN2fRHVTnWdUg2Tgj+pR/Sw+9HVy851c3B/e3oFegqAIQaNK5w9N3ZpWd gpGN8Lau6dEdte8ckMTzG0Sw4LryZyvcgz9+vDv+YX03JaiSMqziHoJGwHfjqr9Q FOI1f4gQw+Y2ct6Xop1vVILH2I26US40Y2DvEMEDuZpTkTN0L2V8ipz+tWgGuCMa 7HRySJAw5HiDdtAV9/H5dfGJVgjsgwuWoYm+viJtJKJ+X350a5YI77hkbglPxQu+ Q+dCVA== =lQYd -----END PGP SIGNATURE----- Merge tag 'pull-tcg-20230928' of https://gitlab.com/rth7680/qemu into staging accel/tcg: Always require can_do_io, for #1866 # -----BEGIN PGP SIGNATURE----- # # iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmUV1sgdHHJpY2hhcmQu # aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/8UAgAjFSrUvW5cGTiaow7 # cTvvoFnQzVCM7gFbC2T9W29Hrv0s3tqJHSdUFftzzMXB1atylwb85XN5wegC98zk # 7+OzrUvTN2fRHVTnWdUg2Tgj+pR/Sw+9HVy851c3B/e3oFegqAIQaNK5w9N3ZpWd # gpGN8Lau6dEdte8ckMTzG0Sw4LryZyvcgz9+vDv+YX03JaiSMqziHoJGwHfjqr9Q # FOI1f4gQw+Y2ct6Xop1vVILH2I26US40Y2DvEMEDuZpTkTN0L2V8ipz+tWgGuCMa # 7HRySJAw5HiDdtAV9/H5dfGJVgjsgwuWoYm+viJtJKJ+X350a5YI77hkbglPxQu+ # Q+dCVA== # =lQYd # -----END PGP SIGNATURE----- # gpg: Signature made Thu 28 Sep 2023 15:40:56 EDT # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full] # Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F * tag 'pull-tcg-20230928' of https://gitlab.com/rth7680/qemu: accel/tcg: Always require can_do_io accel/tcg: Always set CF_LAST_IO with CF_NOIRQ accel/tcg: Improve setting of can_do_io at start of TB accel/tcg: Track current value of can_do_io in the TB accel/tcg: Hoist CF_MEMI_ONLY check outside translation loop accel/tcg: Avoid load of icount_decr if unused Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
5b0d1a8395
|
@ -720,7 +720,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
|
|||
&& cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra == 0) {
|
||||
/* Execute just one insn to trigger exception pending in the log */
|
||||
cpu->cflags_next_tb = (curr_cflags(cpu) & ~CF_USE_ICOUNT)
|
||||
| CF_NOIRQ | 1;
|
||||
| CF_LAST_IO | CF_NOIRQ | 1;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
|
|
|
@ -1083,7 +1083,8 @@ bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc)
|
|||
if (current_tb_modified) {
|
||||
/* Force execution of one insn next time. */
|
||||
CPUState *cpu = current_cpu;
|
||||
cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(current_cpu);
|
||||
cpu->cflags_next_tb =
|
||||
1 | CF_LAST_IO | CF_NOIRQ | curr_cflags(current_cpu);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1153,7 +1154,8 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
|
|||
if (current_tb_modified) {
|
||||
page_collection_unlock(pages);
|
||||
/* Force execution of one insn next time. */
|
||||
current_cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(current_cpu);
|
||||
current_cpu->cflags_next_tb =
|
||||
1 | CF_LAST_IO | CF_NOIRQ | curr_cflags(current_cpu);
|
||||
mmap_unlock();
|
||||
cpu_loop_exit_noexc(current_cpu);
|
||||
}
|
||||
|
|
|
@ -16,26 +16,19 @@
|
|||
#include "tcg/tcg-op-common.h"
|
||||
#include "internal.h"
|
||||
|
||||
static void gen_io_start(void)
|
||||
static void set_can_do_io(DisasContextBase *db, bool val)
|
||||
{
|
||||
tcg_gen_st_i32(tcg_constant_i32(1), cpu_env,
|
||||
offsetof(ArchCPU, parent_obj.can_do_io) -
|
||||
offsetof(ArchCPU, env));
|
||||
if (db->saved_can_do_io != val) {
|
||||
db->saved_can_do_io = val;
|
||||
tcg_gen_st_i32(tcg_constant_i32(val), cpu_env,
|
||||
offsetof(ArchCPU, parent_obj.can_do_io) -
|
||||
offsetof(ArchCPU, env));
|
||||
}
|
||||
}
|
||||
|
||||
bool translator_io_start(DisasContextBase *db)
|
||||
{
|
||||
uint32_t cflags = tb_cflags(db->tb);
|
||||
|
||||
if (!(cflags & CF_USE_ICOUNT)) {
|
||||
return false;
|
||||
}
|
||||
if (db->num_insns == db->max_insns && (cflags & CF_LAST_IO)) {
|
||||
/* Already started in translator_loop. */
|
||||
return true;
|
||||
}
|
||||
|
||||
gen_io_start();
|
||||
set_can_do_io(db, true);
|
||||
|
||||
/*
|
||||
* Ensure that this instruction will be the last in the TB.
|
||||
|
@ -47,14 +40,17 @@ bool translator_io_start(DisasContextBase *db)
|
|||
return true;
|
||||
}
|
||||
|
||||
static TCGOp *gen_tb_start(uint32_t cflags)
|
||||
static TCGOp *gen_tb_start(DisasContextBase *db, uint32_t cflags)
|
||||
{
|
||||
TCGv_i32 count = tcg_temp_new_i32();
|
||||
TCGv_i32 count = NULL;
|
||||
TCGOp *icount_start_insn = NULL;
|
||||
|
||||
tcg_gen_ld_i32(count, cpu_env,
|
||||
offsetof(ArchCPU, neg.icount_decr.u32) -
|
||||
offsetof(ArchCPU, env));
|
||||
if ((cflags & CF_USE_ICOUNT) || !(cflags & CF_NOIRQ)) {
|
||||
count = tcg_temp_new_i32();
|
||||
tcg_gen_ld_i32(count, cpu_env,
|
||||
offsetof(ArchCPU, neg.icount_decr.u32) -
|
||||
offsetof(ArchCPU, env));
|
||||
}
|
||||
|
||||
if (cflags & CF_USE_ICOUNT) {
|
||||
/*
|
||||
|
@ -84,18 +80,15 @@ static TCGOp *gen_tb_start(uint32_t cflags)
|
|||
tcg_gen_st16_i32(count, cpu_env,
|
||||
offsetof(ArchCPU, neg.icount_decr.u16.low) -
|
||||
offsetof(ArchCPU, env));
|
||||
/*
|
||||
* cpu->can_do_io is cleared automatically here at the beginning of
|
||||
* each translation block. The cost is minimal and only paid for
|
||||
* -icount, plus it would be very easy to forget doing it in the
|
||||
* translator. Doing it here means we don't need a gen_io_end() to
|
||||
* go with gen_io_start().
|
||||
*/
|
||||
tcg_gen_st_i32(tcg_constant_i32(0), cpu_env,
|
||||
offsetof(ArchCPU, parent_obj.can_do_io) -
|
||||
offsetof(ArchCPU, env));
|
||||
}
|
||||
|
||||
/*
|
||||
* cpu->can_do_io is set automatically here at the beginning of
|
||||
* each translation block. The cost is minimal, plus it would be
|
||||
* very easy to forget doing it in the translator.
|
||||
*/
|
||||
set_can_do_io(db, db->max_insns == 1 && (cflags & CF_LAST_IO));
|
||||
|
||||
return icount_start_insn;
|
||||
}
|
||||
|
||||
|
@ -144,6 +137,7 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
|
|||
db->num_insns = 0;
|
||||
db->max_insns = *max_insns;
|
||||
db->singlestep_enabled = cflags & CF_SINGLE_STEP;
|
||||
db->saved_can_do_io = -1;
|
||||
db->host_addr[0] = host_pc;
|
||||
db->host_addr[1] = NULL;
|
||||
|
||||
|
@ -151,11 +145,17 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
|
|||
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
|
||||
|
||||
/* Start translating. */
|
||||
icount_start_insn = gen_tb_start(cflags);
|
||||
icount_start_insn = gen_tb_start(db, cflags);
|
||||
ops->tb_start(db, cpu);
|
||||
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
|
||||
|
||||
plugin_enabled = plugin_gen_tb_start(cpu, db, cflags & CF_MEMI_ONLY);
|
||||
if (cflags & CF_MEMI_ONLY) {
|
||||
/* We should only see CF_MEMI_ONLY for io_recompile. */
|
||||
assert(cflags & CF_LAST_IO);
|
||||
plugin_enabled = plugin_gen_tb_start(cpu, db, true);
|
||||
} else {
|
||||
plugin_enabled = plugin_gen_tb_start(cpu, db, false);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
*max_insns = ++db->num_insns;
|
||||
|
@ -172,13 +172,9 @@ void translator_loop(CPUState *cpu, TranslationBlock *tb, int *max_insns,
|
|||
the next instruction. */
|
||||
if (db->num_insns == db->max_insns && (cflags & CF_LAST_IO)) {
|
||||
/* Accept I/O on the last instruction. */
|
||||
gen_io_start();
|
||||
ops->translate_insn(db, cpu);
|
||||
} else {
|
||||
/* we should only see CF_MEMI_ONLY for io_recompile */
|
||||
tcg_debug_assert(!(cflags & CF_MEMI_ONLY));
|
||||
ops->translate_insn(db, cpu);
|
||||
set_can_do_io(db, true);
|
||||
}
|
||||
ops->translate_insn(db, cpu);
|
||||
|
||||
/*
|
||||
* We can't instrument after instructions that change control
|
||||
|
|
|
@ -72,6 +72,7 @@ typedef enum DisasJumpType {
|
|||
* @num_insns: Number of translated instructions (including current).
|
||||
* @max_insns: Maximum number of instructions to be translated in this TB.
|
||||
* @singlestep_enabled: "Hardware" single stepping enabled.
|
||||
* @saved_can_do_io: Known value of cpu->neg.can_do_io, or -1 for unknown.
|
||||
*
|
||||
* Architecture-agnostic disassembly context.
|
||||
*/
|
||||
|
@ -83,6 +84,7 @@ typedef struct DisasContextBase {
|
|||
int num_insns;
|
||||
int max_insns;
|
||||
bool singlestep_enabled;
|
||||
int8_t saved_can_do_io;
|
||||
void *host_addr[2];
|
||||
} DisasContextBase;
|
||||
|
||||
|
|
|
@ -11212,7 +11212,6 @@ static void gen_branch(DisasContext *ctx, int insn_bytes)
|
|||
/* Branches completion */
|
||||
clear_branch_hflags(ctx);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
/* FIXME: Need to clear can_do_io. */
|
||||
switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
|
||||
case MIPS_HFLAG_FBNSLOT:
|
||||
gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
|
||||
|
|
Loading…
Reference in New Issue