diff --git a/accel/tcg/vcpu-state.h b/accel/tcg/vcpu-state.h
index cb06f0412b..d1f989c625 100644
--- a/accel/tcg/vcpu-state.h
+++ b/accel/tcg/vcpu-state.h
@@ -10,12 +10,15 @@
 
 /**
  * AccelCPUState:
+ * @mem_io_pc: Host Program Counter at which the memory was accessed.
  */
 struct AccelCPUState {
     sigjmp_buf jmp_env;
 
 #ifdef CONFIG_USER_ONLY
     TaskState *ts;
+#else
+    uintptr_t mem_io_pc;
 #endif
 };
 
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 6d3716f619..4df9bfeba9 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -423,7 +423,6 @@ struct qemu_work_item;
  * @gdb_num_g_regs: Number of registers in GDB 'g' packets.
  * @node: QTAILQ of CPUs sharing TB cache.
  * @opaque: User data.
- * @mem_io_pc: Host Program Counter at which the memory was accessed.
  * @accel: Pointer to accelerator specific state.
  * @kvm_fd: vCPU file descriptor for KVM.
  * @work_mutex: Lock to prevent multiple access to @work_list.
@@ -502,7 +501,6 @@ struct CPUState {
     /* In order to avoid passing too many arguments to the MMIO helpers,
      * we store some rarely used information in the CPU context.
      */
-    uintptr_t mem_io_pc;
 
     /* Only used in KVM */
     int kvm_fd;
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index cdb3e12dfb..e9d6faf78f 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1383,7 +1383,7 @@ io_prepare(hwaddr *out_offset, CPUState *cpu, hwaddr xlat,
 
     section = iotlb_to_section(cpu, xlat, attrs);
     mr_offset = (xlat & TARGET_PAGE_MASK) + addr;
-    cpu->mem_io_pc = retaddr;
+    cpu->accel->mem_io_pc = retaddr;
     if (!cpu->neg.can_do_io) {
         cpu_io_recompile(cpu, retaddr);
     }
diff --git a/accel/tcg/tcg-accel-ops.c b/accel/tcg/tcg-accel-ops.c
index 56bbad9fcd..dfa0357558 100644
--- a/accel/tcg/tcg-accel-ops.c
+++ b/accel/tcg/tcg-accel-ops.c
@@ -89,6 +89,7 @@ static void tcg_cpu_reset_hold(CPUState *cpu)
 
     qatomic_set(&cpu->neg.icount_decr.u32, 0);
     cpu->neg.can_do_io = true;
+    cpu->accel->mem_io_pc = 0;
 }
 
 /* mask must never be zero, except for A20 change call */
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
index 3e00ea94be..21151f5634 100644
--- a/hw/core/cpu-common.c
+++ b/hw/core/cpu-common.c
@@ -117,7 +117,6 @@ static void cpu_common_reset_hold(Object *obj, ResetType type)
 
     cpu->interrupt_request = 0;
     cpu->halted = cpu->start_powered_off;
-    cpu->mem_io_pc = 0;
     cpu->icount_extra = 0;
     cpu->exception_index = -1;
     cpu->crash_occurred = false;
diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c
index f8acfb3ee2..aa11548e71 100644
--- a/hw/misc/mips_itu.c
+++ b/hw/misc/mips_itu.c
@@ -26,6 +26,7 @@
 #include "hw/misc/mips_itu.h"
 #include "hw/qdev-properties.h"
 #include "target/mips/cpu.h"
+#include "accel/tcg/vcpu-state.h"
 
 #define ITC_TAG_ADDRSPACE_SZ (ITC_ADDRESSMAP_NUM * 8)
 /* Initialize as 4kB area to fit all 32 cells with default 128B grain.
@@ -185,7 +186,7 @@ void block_thread_and_exit(ITCStorageCell *c)
     c->blocked_threads |= 1ULL << current_cpu->cpu_index;
     current_cpu->halted = 1;
     current_cpu->exception_index = EXCP_HLT;
-    cpu_loop_exit_restore(current_cpu, current_cpu->mem_io_pc);
+    cpu_loop_exit_restore(current_cpu, current_cpu->accel->mem_io_pc);
 }
 
 /* ITC Bypass View */
diff --git a/target/i386/helper.c b/target/i386/helper.c
index 48d1513a35..6c188ea94c 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -30,6 +30,7 @@
 #include "qemu/log.h"
 #ifdef CONFIG_TCG
 #include "tcg/insn-start-words.h"
+#include "accel/tcg/vcpu-state.h" // ???
 #endif
 
 void cpu_sync_avx_hflag(CPUX86State *env)
@@ -518,7 +519,7 @@ static inline target_ulong get_memio_eip(CPUX86State *env)
     uint64_t data[TARGET_INSN_START_WORDS];
     CPUState *cs = env_cpu(env);
 
-    if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) {
+    if (!cpu_unwind_state_data(cs, cs->accel->mem_io_pc, data)) {
         return env->eip;
     }
 
