accel/tcg: Move can_do_io to CPUNegativeOffsetState
authorRichard Henderson <richard.henderson@linaro.org>
Fri, 15 Sep 2023 22:41:39 +0000 (15:41 -0700)
committerRichard Henderson <richard.henderson@linaro.org>
Tue, 3 Oct 2023 15:01:02 +0000 (08:01 -0700)
Minimize the displacement to can_do_io, since it may
be touched at the start of each TranslationBlock.
It fits into other padding within the substructure.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14 files changed:
accel/dummy-cpus.c
accel/hvf/hvf-accel-ops.c
accel/kvm/kvm-accel-ops.c
accel/tcg/cpu-exec-common.c
accel/tcg/cpu-exec.c
accel/tcg/cputlb.c
accel/tcg/tcg-accel-ops-icount.c
accel/tcg/tcg-accel-ops-mttcg.c
accel/tcg/tcg-accel-ops-rr.c
accel/tcg/translator.c
hw/core/cpu-common.c
include/hw/core/cpu.h
softmmu/icount.c
softmmu/watchpoint.c

index d6a1b8d0a277a6f789d3bca16546633b448d08aa..b75c919ac358677919598506ce55bacad35601f4 100644 (file)
@@ -27,7 +27,7 @@ static void *dummy_cpu_thread_fn(void *arg)
     qemu_mutex_lock_iothread();
     qemu_thread_get_self(cpu->thread);
     cpu->thread_id = qemu_get_thread_id();
-    cpu->can_do_io = 1;
+    cpu->neg.can_do_io = true;
     current_cpu = cpu;
 
 #ifndef _WIN32
index 3c94c79747d1879c66265b47c52c23d72ffd6082..abe7adf7ee87c89532fdbb78d08748e1140340ae 100644 (file)
@@ -428,7 +428,7 @@ static void *hvf_cpu_thread_fn(void *arg)
     qemu_thread_get_self(cpu->thread);
 
     cpu->thread_id = qemu_get_thread_id();
-    cpu->can_do_io = 1;
+    cpu->neg.can_do_io = true;
     current_cpu = cpu;
 
     hvf_init_vcpu(cpu);
index 457eafa38020550f33279b0ead314dc9273b5e2d..6195150a0b4d2f310614d4efa18d409dd0c28044 100644 (file)
@@ -36,7 +36,7 @@ static void *kvm_vcpu_thread_fn(void *arg)
     qemu_mutex_lock_iothread();
     qemu_thread_get_self(cpu->thread);
     cpu->thread_id = qemu_get_thread_id();
-    cpu->can_do_io = 1;
+    cpu->neg.can_do_io = true;
     current_cpu = cpu;
 
     r = kvm_init_vcpu(cpu, &error_fatal);
index 7e35d7f4b58ee94f884b5a8cb87f450de6b4a44c..82ae837e39ff3d149616bf3484cae3d763757793 100644 (file)
@@ -36,7 +36,7 @@ void cpu_loop_exit_noexc(CPUState *cpu)
 void cpu_loop_exit(CPUState *cpu)
 {
     /* Undo the setting in cpu_tb_exec.  */
-    cpu->can_do_io = 1;
+    cpu->neg.can_do_io = true;
     /* Undo any setting in generated code.  */
     qemu_plugin_disable_mem_helpers(cpu);
     siglongjmp(cpu->jmp_env, 1);
index 60f1986b85034239c6c9fb2958c8c1f1063cb342..de60fdb612f873156475c4999fdb8a4aff205c69 100644 (file)
@@ -455,7 +455,7 @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
 
     qemu_thread_jit_execute();
     ret = tcg_qemu_tb_exec(env, tb_ptr);
-    cpu->can_do_io = 1;
+    cpu->neg.can_do_io = true;
     qemu_plugin_disable_mem_helpers(cpu);
     /*
      * TODO: Delay swapping back to the read-write region of the TB
index 3270f65c20e0dd5c037cd2dee79d64d24060a562..d69e046b80cd22a91c71f5664626f276dba5d321 100644 (file)
@@ -1361,7 +1361,7 @@ io_prepare(hwaddr *out_offset, CPUArchState *env, hwaddr xlat,
     section = iotlb_to_section(cpu, xlat, attrs);
     mr_offset = (xlat & TARGET_PAGE_MASK) + addr;
     cpu->mem_io_pc = retaddr;
-    if (!cpu->can_do_io) {
+    if (!cpu->neg.can_do_io) {
         cpu_io_recompile(cpu, retaddr);
     }
 
index 3d2cfbbc97786368825a71958c7df090f256f146..0af643b2171c2fd39fc0ea656cc2b4da0259fe23 100644 (file)
@@ -153,7 +153,7 @@ void icount_handle_interrupt(CPUState *cpu, int mask)
 
     tcg_handle_interrupt(cpu, mask);
     if (qemu_cpu_is_self(cpu) &&
-        !cpu->can_do_io
+        !cpu->neg.can_do_io
         && (mask & ~old_mask) != 0) {
         cpu_abort(cpu, "Raised interrupt while not in I/O function");
     }
index 4b0dfb4be732c614770235e3187b66060d32525d..ae95ba419ee09ad710bad1b9ba6a0c2380b59193 100644 (file)
@@ -80,7 +80,7 @@ static void *mttcg_cpu_thread_fn(void *arg)
     qemu_thread_get_self(cpu->thread);
 
     cpu->thread_id = qemu_get_thread_id();
-    cpu->can_do_io = 1;
+    cpu->neg.can_do_io = true;
     current_cpu = cpu;
     cpu_thread_signal_created(cpu);
     qemu_guest_random_seed_thread_part2(cpu->random_seed);
index 2d523289a8db807d06428982ccf9208ab7244c6a..671a3c4ca0ae0a24f243e075958fd69d45e48984 100644 (file)
@@ -192,7 +192,7 @@ static void *rr_cpu_thread_fn(void *arg)
     qemu_thread_get_self(cpu->thread);
 
     cpu->thread_id = qemu_get_thread_id();
-    cpu->can_do_io = 1;
+    cpu->neg.can_do_io = true;
     cpu_thread_signal_created(cpu);
     qemu_guest_random_seed_thread_part2(cpu->random_seed);
 
@@ -334,7 +334,7 @@ void rr_start_vcpu_thread(CPUState *cpu)
         cpu->thread = single_tcg_cpu_thread;
         cpu->halt_cond = single_tcg_halt_cond;
         cpu->thread_id = first_cpu->thread_id;
-        cpu->can_do_io = 1;
+        cpu->neg.can_do_io = 1;
         cpu->created = true;
     }
 }
index b3e12d61e998784f0fcaf76cdfd424d373b71168..460bfc4c7489ffead4bd9ae869be80523614cd9b 100644 (file)
@@ -20,9 +20,11 @@ static void set_can_do_io(DisasContextBase *db, bool val)
 {
     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));
+
+        QEMU_BUILD_BUG_ON(sizeof_field(CPUState, neg.can_do_io) != 1);
+        tcg_gen_st8_i32(tcg_constant_i32(val), cpu_env,
+                        offsetof(ArchCPU, parent_obj.neg.can_do_io) -
+                        offsetof(ArchCPU, env));
     }
 }
 
@@ -83,7 +85,7 @@ static TCGOp *gen_tb_start(DisasContextBase *db, uint32_t cflags)
     }
 
     /*
-     * cpu->can_do_io is set automatically here at the beginning of
+     * cpu->neg.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.
      */
index 08d5bbc873a73115f1018d6f298b0147df59355b..4d406995ab599079c47ab109406b6c2312d4ef42 100644 (file)
@@ -131,7 +131,7 @@ static void cpu_common_reset_hold(Object *obj)
     cpu->mem_io_pc = 0;
     cpu->icount_extra = 0;
     qatomic_set(&cpu->neg.icount_decr.u32, 0);
-    cpu->can_do_io = 1;
+    cpu->neg.can_do_io = true;
     cpu->exception_index = -1;
     cpu->crash_occurred = false;
     cpu->cflags_next_tb = -1;
index 973ff9d106a5242f5c9c40105dfd09729df7f85f..293cedd9b5c8e6a172612ac4df37f50aa73b1917 100644 (file)
@@ -351,6 +351,7 @@ typedef union IcountDecr {
 typedef struct CPUNegativeOffsetState {
     CPUTLB tlb;
     IcountDecr icount_decr;
+    bool can_do_io;
 } CPUNegativeOffsetState;
 
 typedef struct CPUBreakpoint {
@@ -420,9 +421,7 @@ struct qemu_work_item;
  * @crash_occurred: Indicates the OS reported a crash (panic) for this CPU
  * @singlestep_enabled: Flags for single-stepping.
  * @icount_extra: Instructions until next timer event.
- * @can_do_io: Nonzero if memory-mapped IO is safe. Deterministic execution
- * requires that IO only be performed on the last instruction of a TB
- * so that interrupts take effect immediately.
+ * @neg.can_do_io: True if memory-mapped IO is allowed.
  * @cpu_ases: Pointer to array of CPUAddressSpaces (which define the
  *            AddressSpaces this CPU has)
  * @num_ases: number of CPUAddressSpaces in @cpu_ases
@@ -547,7 +546,6 @@ struct CPUState {
     int cluster_index;
     uint32_t tcg_cflags;
     uint32_t halted;
-    uint32_t can_do_io;
     int32_t exception_index;
 
     AccelCPUState *accel;
index 144e24829cd5ea27980eb241d859aa2be79f9172..956d15e343f83ed3978304d85d8e656b1d9d3b6d 100644 (file)
@@ -111,7 +111,7 @@ static int64_t icount_get_raw_locked(void)
     CPUState *cpu = current_cpu;
 
     if (cpu && cpu->running) {
-        if (!cpu->can_do_io) {
+        if (!cpu->neg.can_do_io) {
             error_report("Bad icount read");
             exit(1);
         }
index 5350163385834a75fbf876cca174d3b7e9bbfb43..45d1f12faf1b404158f24dfa0bd1a9942acaa014 100644 (file)
@@ -177,7 +177,7 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
                  * Force recompile to succeed, because icount may
                  * be read only at the end of the block.
                  */
-                if (!cpu->can_do_io) {
+                if (!cpu->neg.can_do_io) {
                     /* Force execution of one insn next time.  */
                     cpu->cflags_next_tb = 1 | CF_LAST_IO | CF_NOIRQ
                                           | curr_cflags(cpu);