@@ -182,6 +182,7 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu)
182182 * TCG is not considered a security-sensitive part of QEMU so this does not
183183 * affect the impact of CFI in environment with high security requirements
184184 */
185+ #ifdef CONFIG_LATX
185186static inline TranslationBlock * QEMU_DISABLE_CFI
186187cpu_tb_exec (CPUState * cpu , TranslationBlock * itb , int * tb_exit )
187188{
@@ -263,7 +264,6 @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
263264#ifdef CONFIG_LATX_DEBUG
264265 latx_before_exec_trace_tb (env , itb );
265266#endif
266- #ifdef CONFIG_LATX
267267
268268 env -> fpu_clobber = false;
269269 ret = tcg_qemu_tb_exec (env , tb_ptr );
@@ -304,9 +304,6 @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
304304 link_indirect_jmp (env );
305305 }
306306
307- #else
308- ret = tcg_qemu_tb_exec (env , tb_ptr );
309- #endif
310307#ifdef CONFIG_LATX_DEBUG
311308 latx_after_exec_trace_tb (env , itb );
312309#endif
@@ -366,6 +363,80 @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
366363
367364 return last_tb ;
368365}
366+ #else
367+ static inline TranslationBlock * QEMU_DISABLE_CFI
368+ cpu_tb_exec (CPUState * cpu , TranslationBlock * itb , int * tb_exit )
369+ {
370+ if (!itb ) {
371+ fprintf (stderr , "[LATX] ERROR!\n" );
372+ }
373+ CPUArchState * env = cpu -> env_ptr ;
374+ uintptr_t ret ;
375+ TranslationBlock * last_tb ;
376+ const void * tb_ptr = itb -> tc .ptr ;
377+ if (qemu_loglevel_mask (CPU_LOG_EXEC )) {
378+ qemu_log_mask_and_addr (CPU_LOG_EXEC , itb -> pc ,
379+ "pid(%d) - tid(%" PRIuPTR ") Trace cpu%d: %p [ "
380+ TARGET_FMT_lx "/%#x] %s\n" ,
381+ getpid (), (uintptr_t )pthread_self (), cpu -> cpu_index , itb -> tc .ptr ,
382+ itb -> pc , itb -> flags , lookup_symbol (itb -> pc ));
383+ }
384+
385+ #if defined(DEBUG_DISAS )
386+ if (qemu_loglevel_mask (CPU_LOG_TB_CPU )
387+ && qemu_log_in_addr_range (itb -> pc )) {
388+ FILE * logfile = qemu_log_lock ();
389+ int flags = 0 ;
390+ if (qemu_loglevel_mask (CPU_LOG_TB_FPU )) {
391+ flags |= CPU_DUMP_FPU ;
392+ }
393+ #if defined(TARGET_I386 )
394+ flags |= CPU_DUMP_CCOP ;
395+ #endif
396+ log_cpu_state (cpu , flags );
397+ qemu_log_unlock (logfile );
398+ }
399+ #endif /* DEBUG_DISAS */
400+
401+ qemu_thread_jit_execute ();
402+ ret = tcg_qemu_tb_exec (env , tb_ptr );
403+ cpu -> can_do_io = 1 ;
404+ /*
405+ * TODO: Delay swapping back to the read-write region of the TB
406+ * until we actually need to modify the TB. The read-only copy,
407+ * coming from the rx region, shares the same host TLB entry as
408+ * the code that executed the exit_tb opcode that arrived here.
409+ * If we insist on touching both the RX and the RW pages, we
410+ * double the host TLB pressure.
411+ */
412+ last_tb = tcg_splitwx_to_rw ((void * )(ret & ~TB_EXIT_MASK ));
413+ * tb_exit = ret & TB_EXIT_MASK ;
414+
415+ trace_exec_tb_exit (last_tb , * tb_exit );
416+
417+ if (* tb_exit > TB_EXIT_IDX1 ) {
418+ /* We didn't start executing this TB (eg because the instruction
419+ * counter hit zero); we must restore the guest PC to the address
420+ * of the start of the TB.
421+ */
422+ CPUClass * cc = CPU_GET_CLASS (cpu );
423+ qemu_log_mask_and_addr (CPU_LOG_EXEC , last_tb -> pc ,
424+ "Stopped execution of TB chain before %p ["
425+ TARGET_FMT_lx "] %s\n" ,
426+ last_tb -> tc .ptr , last_tb -> pc ,
427+ lookup_symbol (last_tb -> pc ));
428+ if (cc -> tcg_ops -> synchronize_from_tb ) {
429+ cc -> tcg_ops -> synchronize_from_tb (cpu , last_tb );
430+ } else {
431+ assert (cc -> set_pc );
432+ cc -> set_pc (cpu , last_tb -> pc );
433+ }
434+ }
435+
436+
437+ return last_tb ;
438+ }
439+ #endif
369440
370441
371442static void cpu_exec_enter (CPUState * cpu )
@@ -718,6 +789,7 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
718789#include "tu.h"
719790#endif
720791
792+ #ifdef CONFIG_LATX
721793static inline TranslationBlock * tb_find (CPUState * cpu ,
722794 TranslationBlock * last_tb ,
723795 int tb_exit , uint32_t cflags )
@@ -786,6 +858,49 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
786858 }
787859 return tb ;
788860}
861+ #else
862+ static inline TranslationBlock * tb_find (CPUState * cpu ,
863+ TranslationBlock * last_tb ,
864+ int tb_exit , uint32_t cflags )
865+ {
866+ CPUArchState * env = (CPUArchState * )cpu -> env_ptr ;
867+ TranslationBlock * tb ;
868+ target_ulong cs_base , pc ;
869+ uint32_t flags ;
870+
871+ cpu_get_tb_cpu_state (env , & pc , & cs_base , & flags );
872+
873+ tb = tb_lookup (cpu , pc , cs_base , flags , cflags );
874+ if (tb == NULL ) {
875+ mmap_lock ();
876+
877+ tb = tb_gen_code (cpu , pc , cs_base , flags , cflags );
878+
879+ if (!tb ) {
880+ mmap_unlock ();
881+ return NULL ;
882+ }
883+ /* We add the TB in the virtual pc hash table for the fast lookup */
884+ int hash_value = tb_jmp_cache_hash_func (pc );
885+ qatomic_set (& cpu -> tb_jmp_cache [hash_value ], tb );
886+ mmap_unlock ();
887+ }
888+ #ifndef CONFIG_USER_ONLY
889+ /* We don't take care of direct jumps when address mapping changes in
890+ * system emulation. So it's not safe to make a direct jump to a TB
891+ * spanning two pages because the mapping for the second page can change.
892+ */
893+ if (tb -> page_addr [1 ] != -1 ) {
894+ last_tb = NULL ;
895+ }
896+ #endif
897+ /* See if we can patch the calling TB. */
898+ if (last_tb ) {
899+ tb_add_jump (last_tb , tb_exit , tb );
900+ }
901+ return tb ;
902+ }
903+ #endif
789904
790905static inline bool cpu_handle_halt (CPUState * cpu )
791906{
0 commit comments