Hi, all I want to add a binary tranlation optimization, called IBTC (Indirect Branch Translation Cache) to QEMU. IBTC is a data structure used to cache the mapping between guest IB (indirect branch) and its corresponding translated code cache address. If IBTC get a hit, then there is no need to jump back to QEMU, next translated code cache can be excuted directly. An example below.
=------------------- target-i386/translation.c -------------------= static target_ulong disas_insn(CPUState *env, DisasContext *s, target_ulong pc_start) { // Place IBTC lookup in the following cases case 2: /* call Ev */ case 4: /* jmp Ev */ case 0xc2: /* ret im */ /* * generate IBTC lookup TCG IR in the code cache while * encounting indirect branch (ret im) */ if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); TCGv_ptr ibtc_host_eip = tcg_temp_new_ptr(); gen_helper_lookup_ibtc(ibtc_host_eip, cpu_T[0]); *gen_opc_ptr++ = INDEX_op_jmp; *gen_opparam_ptr++ = GET_TCGV_PTR(ibtc_host_eip); tcg_temp_free_ptr(ibtc_host_eip); gen_eob(s); break; case 0xc3: /* ret */ } =------------------- target-i386/translation.c -------------------= IBTC works fine in the process (user) mode, but not in the system mode. In process mode, since the IBTC allocated is big enough, I don't need to invalidate an IBTC entry or flush the entire IBTC. I suspect this is why IBTC doesn't work in the system mode. I spot a few place to might be needed to call flush_ibtc() to flush the entire IBTC, but I am not sure if there are the right place. Or I might miss some place. The places I insert flush_ibtc are below, ----- 1. cpu-exec.c int cpu_exec(CPUState *env1) { if (tb_invalidated_flag) { next_tb = 0; flush_ibtc(); // flush IBTC tb_invalidated_flag = 0; } } 2. exec.c TranslationBlock *tb_gen_code(CPUState *env, target_ulong pc, target_ulong cs_base, int flags, int cflags) { if (!tb) { /* flush must be done */ tb_flush(env); flush_ibtc(); // flush IBTC /* cannot fail at this point */ tb = tb_alloc(pc); /* Don't forget to invalidate previous TB info. */ tb_invalidated_flag = 1; } } 3. exec.c void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr) { tb_invalidated_flag = 1; /* remove the TB from the hash list */ h = tb_jmp_cache_hash_func(tb->pc); for(env = first_cpu; env != NULL; env = env->next_cpu) { if (env->tb_jmp_cache[h] == tb) env->tb_jmp_cache[h] = NULL; } flush_ibtc(); // flush IBTC } ----- Have I already considered all kind of situations? Or something else I need to do to make IBTC work in system mode? Thanks! Regards, chenwj -- Wei-Ren Chen (陳韋任) Computer Systems Lab, Institute of Information Science, Academia Sinica, Taiwan (R.O.C.) Tel:886-2-2788-3799 #1667