qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

tcg: take tb_ctx out of TCGContext

Groundwork for supporting multiple TCG contexts.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

authored by

Emilio G. Cota and committed by
Richard Henderson
44ded3d0 f19c6cc6

+34 -35
+1 -1
accel/tcg/cpu-exec.c
··· 327 327 phys_pc = get_page_addr_code(desc.env, pc); 328 328 desc.phys_page1 = phys_pc & TARGET_PAGE_MASK; 329 329 h = tb_hash_func(phys_pc, pc, flags, cf_mask, *cpu->trace_dstate); 330 - return qht_lookup(&tcg_ctx.tb_ctx.htable, tb_cmp, &desc, h); 330 + return qht_lookup(&tb_ctx.htable, tb_cmp, &desc, h); 331 331 } 332 332 333 333 void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr)
+28 -29
accel/tcg/translate-all.c
··· 154 154 155 155 /* code generation context */ 156 156 TCGContext tcg_ctx; 157 + TBContext tb_ctx; 157 158 bool parallel_cpus; 158 159 159 160 /* translation block context */ ··· 185 186 void tb_lock(void) 186 187 { 187 188 assert_tb_unlocked(); 188 - qemu_mutex_lock(&tcg_ctx.tb_ctx.tb_lock); 189 + qemu_mutex_lock(&tb_ctx.tb_lock); 189 190 have_tb_lock++; 190 191 } 191 192 ··· 193 194 { 194 195 assert_tb_locked(); 195 196 have_tb_lock--; 196 - qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock); 197 + qemu_mutex_unlock(&tb_ctx.tb_lock); 197 198 } 198 199 199 200 void tb_lock_reset(void) 200 201 { 201 202 if (have_tb_lock) { 202 - qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock); 203 + qemu_mutex_unlock(&tb_ctx.tb_lock); 203 204 have_tb_lock = 0; 204 205 } 205 206 } ··· 824 825 fprintf(stderr, "Could not allocate dynamic translator buffer\n"); 825 826 exit(1); 826 827 } 827 - tcg_ctx.tb_ctx.tb_tree = g_tree_new(tb_tc_cmp); 828 - qemu_mutex_init(&tcg_ctx.tb_ctx.tb_lock); 828 + tb_ctx.tb_tree = g_tree_new(tb_tc_cmp); 829 + qemu_mutex_init(&tb_ctx.tb_lock); 829 830 } 830 831 831 832 static void tb_htable_init(void) 832 833 { 833 834 unsigned int mode = QHT_MODE_AUTO_RESIZE; 834 835 835 - qht_init(&tcg_ctx.tb_ctx.htable, CODE_GEN_HTABLE_SIZE, mode); 836 + qht_init(&tb_ctx.htable, CODE_GEN_HTABLE_SIZE, mode); 836 837 } 837 838 838 839 /* Must be called before using the QEMU cpus. 'tb_size' is the size ··· 876 877 { 877 878 assert_tb_locked(); 878 879 879 - g_tree_remove(tcg_ctx.tb_ctx.tb_tree, &tb->tc); 880 + g_tree_remove(tb_ctx.tb_tree, &tb->tc); 880 881 } 881 882 882 883 static inline void invalidate_page_bitmap(PageDesc *p) ··· 938 939 /* If it is already been done on request of another CPU, 939 940 * just retry. 940 941 */ 941 - if (tcg_ctx.tb_ctx.tb_flush_count != tb_flush_count.host_int) { 942 + if (tb_ctx.tb_flush_count != tb_flush_count.host_int) { 942 943 goto done; 943 944 } 944 945 945 946 if (DEBUG_TB_FLUSH_GATE) { 946 - size_t nb_tbs = g_tree_nnodes(tcg_ctx.tb_ctx.tb_tree); 947 + size_t nb_tbs = g_tree_nnodes(tb_ctx.tb_tree); 947 948 size_t host_size = 0; 948 949 949 - g_tree_foreach(tcg_ctx.tb_ctx.tb_tree, tb_host_size_iter, &host_size); 950 + g_tree_foreach(tb_ctx.tb_tree, tb_host_size_iter, &host_size); 950 951 printf("qemu: flush code_size=%td nb_tbs=%zu avg_tb_size=%zu\n", 951 952 tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer, nb_tbs, 952 953 nb_tbs > 0 ? host_size / nb_tbs : 0); ··· 961 962 } 962 963 963 964 /* Increment the refcount first so that destroy acts as a reset */ 964 - g_tree_ref(tcg_ctx.tb_ctx.tb_tree); 965 - g_tree_destroy(tcg_ctx.tb_ctx.tb_tree); 965 + g_tree_ref(tb_ctx.tb_tree); 966 + g_tree_destroy(tb_ctx.tb_tree); 966 967 967 - qht_reset_size(&tcg_ctx.tb_ctx.htable, CODE_GEN_HTABLE_SIZE); 968 + qht_reset_size(&tb_ctx.htable, CODE_GEN_HTABLE_SIZE); 968 969 page_flush_tb(); 969 970 970 971 tcg_ctx.code_gen_ptr = tcg_ctx.code_gen_buffer; 971 972 /* XXX: flush processor icache at this point if cache flush is 972 973 expensive */ 973 - atomic_mb_set(&tcg_ctx.tb_ctx.tb_flush_count, 974 - tcg_ctx.tb_ctx.tb_flush_count + 1); 974 + atomic_mb_set(&tb_ctx.tb_flush_count, tb_ctx.tb_flush_count + 1); 975 975 976 976 done: 977 977 tb_unlock(); ··· 980 980 void tb_flush(CPUState *cpu) 981 981 { 982 982 if (tcg_enabled()) { 983 - unsigned tb_flush_count = atomic_mb_read(&tcg_ctx.tb_ctx.tb_flush_count); 983 + unsigned tb_flush_count = atomic_mb_read(&tb_ctx.tb_flush_count); 984 984 async_safe_run_on_cpu(cpu, do_tb_flush, 985 985 RUN_ON_CPU_HOST_INT(tb_flush_count)); 986 986 } ··· 1013 1013 static void tb_invalidate_check(target_ulong address) 1014 1014 { 1015 1015 address &= TARGET_PAGE_MASK; 1016 - qht_iter(&tcg_ctx.tb_ctx.htable, do_tb_invalidate_check, &address); 1016 + qht_iter(&tb_ctx.htable, do_tb_invalidate_check, &address); 1017 1017 } 1018 1018 1019 1019 static void ··· 1033 1033 /* verify that all the pages have correct rights for code */ 1034 1034 static void tb_page_check(void) 1035 1035 { 1036 - qht_iter(&tcg_ctx.tb_ctx.htable, do_tb_page_check, NULL); 1036 + qht_iter(&tb_ctx.htable, do_tb_page_check, NULL); 1037 1037 } 1038 1038 1039 1039 #endif /* CONFIG_USER_ONLY */ ··· 1133 1133 phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK); 1134 1134 h = tb_hash_func(phys_pc, tb->pc, tb->flags, tb->cflags & CF_HASH_MASK, 1135 1135 tb->trace_vcpu_dstate); 1136 - qht_remove(&tcg_ctx.tb_ctx.htable, tb, h); 1136 + qht_remove(&tb_ctx.htable, tb, h); 1137 1137 1138 1138 /* remove the TB from the page list */ 1139 1139 if (tb->page_addr[0] != page_addr) { ··· 1162 1162 /* suppress any remaining jumps to this TB */ 1163 1163 tb_jmp_unlink(tb); 1164 1164 1165 - tcg_ctx.tb_ctx.tb_phys_invalidate_count++; 1165 + tb_ctx.tb_phys_invalidate_count++; 1166 1166 } 1167 1167 1168 1168 #ifdef CONFIG_SOFTMMU ··· 1278 1278 /* add in the hash table */ 1279 1279 h = tb_hash_func(phys_pc, tb->pc, tb->flags, tb->cflags & CF_HASH_MASK, 1280 1280 tb->trace_vcpu_dstate); 1281 - qht_insert(&tcg_ctx.tb_ctx.htable, tb, h); 1281 + qht_insert(&tb_ctx.htable, tb, h); 1282 1282 1283 1283 #ifdef CONFIG_USER_ONLY 1284 1284 if (DEBUG_TB_CHECK_GATE) { ··· 1441 1441 * through the physical hash table and physical page list. 1442 1442 */ 1443 1443 tb_link_page(tb, phys_pc, phys_page2); 1444 - g_tree_insert(tcg_ctx.tb_ctx.tb_tree, &tb->tc, tb); 1444 + g_tree_insert(tb_ctx.tb_tree, &tb->tc, tb); 1445 1445 return tb; 1446 1446 } 1447 1447 ··· 1713 1713 { 1714 1714 struct tb_tc s = { .ptr = (void *)tc_ptr }; 1715 1715 1716 - return g_tree_lookup(tcg_ctx.tb_ctx.tb_tree, &s); 1716 + return g_tree_lookup(tb_ctx.tb_tree, &s); 1717 1717 } 1718 1718 1719 1719 #if !defined(CONFIG_USER_ONLY) ··· 1930 1930 1931 1931 tb_lock(); 1932 1932 1933 - nb_tbs = g_tree_nnodes(tcg_ctx.tb_ctx.tb_tree); 1934 - g_tree_foreach(tcg_ctx.tb_ctx.tb_tree, tb_tree_stats_iter, &tst); 1933 + nb_tbs = g_tree_nnodes(tb_ctx.tb_tree); 1934 + g_tree_foreach(tb_ctx.tb_tree, tb_tree_stats_iter, &tst); 1935 1935 /* XXX: avoid using doubles ? */ 1936 1936 cpu_fprintf(f, "Translation buffer state:\n"); 1937 1937 /* ··· 1957 1957 tst.direct_jmp2_count, 1958 1958 nb_tbs ? (tst.direct_jmp2_count * 100) / nb_tbs : 0); 1959 1959 1960 - qht_statistics_init(&tcg_ctx.tb_ctx.htable, &hst); 1960 + qht_statistics_init(&tb_ctx.htable, &hst); 1961 1961 print_qht_statistics(f, cpu_fprintf, hst); 1962 1962 qht_statistics_destroy(&hst); 1963 1963 1964 1964 cpu_fprintf(f, "\nStatistics:\n"); 1965 1965 cpu_fprintf(f, "TB flush count %u\n", 1966 - atomic_read(&tcg_ctx.tb_ctx.tb_flush_count)); 1967 - cpu_fprintf(f, "TB invalidate count %d\n", 1968 - tcg_ctx.tb_ctx.tb_phys_invalidate_count); 1966 + atomic_read(&tb_ctx.tb_flush_count)); 1967 + cpu_fprintf(f, "TB invalidate count %d\n", tb_ctx.tb_phys_invalidate_count); 1969 1968 cpu_fprintf(f, "TLB flush count %zu\n", tlb_flush_count()); 1970 1969 tcg_dump_info(f, cpu_fprintf); 1971 1970
+2
include/exec/tb-context.h
··· 41 41 int tb_phys_invalidate_count; 42 42 }; 43 43 44 + extern TBContext tb_ctx; 45 + 44 46 #endif
+3 -3
linux-user/main.c
··· 129 129 void fork_start(void) 130 130 { 131 131 cpu_list_lock(); 132 - qemu_mutex_lock(&tcg_ctx.tb_ctx.tb_lock); 132 + qemu_mutex_lock(&tb_ctx.tb_lock); 133 133 mmap_fork_start(); 134 134 } 135 135 ··· 145 145 QTAILQ_REMOVE(&cpus, cpu, node); 146 146 } 147 147 } 148 - qemu_mutex_init(&tcg_ctx.tb_ctx.tb_lock); 148 + qemu_mutex_init(&tb_ctx.tb_lock); 149 149 qemu_init_cpu_list(); 150 150 gdbserver_fork(thread_cpu); 151 151 } else { 152 - qemu_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock); 152 + qemu_mutex_unlock(&tb_ctx.tb_lock); 153 153 cpu_list_unlock(); 154 154 } 155 155 }
-2
tcg/tcg.h
··· 663 663 /* Threshold to flush the translated code buffer. */ 664 664 void *code_gen_highwater; 665 665 666 - TBContext tb_ctx; 667 - 668 666 /* Track which vCPU triggers events */ 669 667 CPUState *cpu; /* *_trans */ 670 668 TCGv_env tcg_env; /* *_exec */