All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops
@ 2013-06-16 15:57 Andreas Färber
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
                   ` (29 more replies)
  0 siblings, 30 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stefano Stabellini, Markus Armbruster,
	Alexander Graf, Blue Swirl, Anthony Liguori, Scott Wood,
	Paolo Bonzini, Andreas Färber, Aurélien Jarno

Hello,

This series changes cpu_single_env, first_cpu, next_cpu and thread_env to CPUState.

qemu_init_vcpu() is converted to CPUState and moved away from targets.

cpu_unassigned_access(), cpu_dump_state() and cpu_dump_statistics() are turned
into CPUClass methods. exec/hwaddr.h is modified to allow its use in qom/cpu.h.

v2 takes the approach of leaving open-coded CPU loops in place and just changing
them over to CPUState in one big patch. It goes on to remove qemu_for_each_cpu()
and demonstrates the benefits of this invasive series by making a few devices
target-independent.

Available for testing at:
git://github.com/afaerber/qemu-cpu.git qom-cpu-10.v2
https://github.com/afaerber/qemu-cpu/commits/qom-cpu-10.v2

Regards,
Andreas

v1 -> v2:
* Fixed typo spotted by Li Guang.
* Dropped qemu_for_each_cpu() conversion patches.
* Applied most qemu_get_cpu() patches already.
* Fixed Xen breakage due to NULL cpu_single_env (reported by Stefano).
* Appended patch to drop qemu_for_each_cpu() (suggested by Markus).
* Appended patches to build arm_gic, arm_mptimer, openpic and sh_intc only once.
* Avoided some un-typed uses of CPUState::env_ptr.

Cc: Anthony Liguori <anthony@codemonkey.ws>
Cc: Blue Swirl <blauwirbel@gmail.com>
Cc: Aurélien Jarno <aurelien@aurel32.net>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com> (cpu_unassigned_access)
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com> (dummy CPU thread changes)
Cc: Peter Maydell <peter.maydell@linaro.org> (hwaddr, arm devs)
Cc: Alexander Graf <agraf@suse.de> (openpic)
Cc: Scott Wood <scottwood@freescale.com> (openpic)

Andreas Färber (29):
  kvm: Change kvm_cpu_synchronize_state() argument to CPUState
  kvm: Change cpu_synchronize_state() argument to CPUState
  gdbstub: Simplify find_cpu()
  cpu: Change cpu_exit() argument to CPUState
  cpus: Change cpu_thread_is_idle() argument to CPUState
  cpus: Change qemu_kvm_wait_io_event() argument to CPUState
  kvm: Change kvm_set_signal_mask() argument to CPUState
  cpus: Change qemu_kvm_init_cpu_signals() argument to CPUState
  cpu: Turn cpu_dump_{state,statistics}() into CPUState hooks
  kvm: Change kvm_handle_internal_error() argument to CPUState
  kvm: Change kvm_cpu_exec() argument to CPUState
  gdbstub: Set gdb_set_stop_cpu() argument to CPUState
  cpus: Change cpu_handle_guest_debug() argument to CPUState
  cpus: Change qemu_kvm_start_vcpu() argument to CPUState
  cpus: Change qemu_dummy_start_vcpu() argument to CPUState
  cpu: Change qemu_init_vcpu() argument to CPUState
  hwaddr: Make hwaddr type usable beyond softmmu
  cpu: Turn cpu_unassigned_access() into a CPUState hook
  cpu: Replace cpu_single_env with CPUState cpu_single_cpu
  kvm: Change kvm_remove_all_breakpoints() argument to CPUState
  cpu: Make first_cpu and next_cpu CPUState
  linux-user: Change thread_env to CPUState
  bsd-user: Change thread_env to CPUState
  cpu: Drop qemu_for_each_cpu()
  cpu: Move CPU_INTERRUPT_* to qom/cpu.h
  intc/sh_intc: Build sh_intc only once
  intc/arm_gic: Build arm_gic only once
  intc/openpic: Build openpic only once
  timer/arm_mptimer: Build arm_mptimer only once

 bsd-user/elfload.c            |   6 +-
 bsd-user/main.c               |   9 +-
 bsd-user/qemu.h               |   2 +-
 cpu-exec.c                    |  13 +--
 cpus.c                        | 227 ++++++++++++++++++++----------------------
 cputlb.c                      |  19 ++--
 dump.c                        |  16 ++-
 exec.c                        |  67 +++++--------
 gdbstub.c                     |  61 +++++++-----
 hw/acpi/piix4.c               |  20 ++--
 hw/alpha/typhoon.c            |  12 +--
 hw/arm/boot.c                 |  10 +-
 hw/arm/exynos4_boards.c       |   4 +-
 hw/arm/highbank.c             |   2 +-
 hw/arm/pxa2xx.c               |   3 +-
 hw/arm/realview.c             |   2 +-
 hw/arm/vexpress.c             |   2 +-
 hw/arm/xilinx_zynq.c          |   2 +-
 hw/i386/kvm/apic.c            |   2 +-
 hw/i386/kvm/clock.c           |  12 ++-
 hw/i386/kvmvapic.c            |  21 ++--
 hw/i386/pc.c                  |  28 +++---
 hw/i386/pc_piix.c             |   3 +-
 hw/intc/Makefile.objs         |   6 +-
 hw/intc/arm_gic.c             |   4 +-
 hw/intc/armv7m_nvic.c         |  11 +-
 hw/intc/openpic.c             |   7 +-
 hw/intc/sh_intc.c             |   6 +-
 hw/isa/lpc_ich9.c             |   2 +-
 hw/mips/mips_fulong2e.c       |   6 +-
 hw/mips/mips_jazz.c           |   6 +-
 hw/mips/mips_malta.c          |   9 +-
 hw/misc/vmport.c              |  26 +++--
 hw/ppc/mpc8544_guts.c         |   3 +-
 hw/ppc/ppc.c                  |  12 +--
 hw/ppc/ppce500_spin.c         |   2 +-
 hw/ppc/prep.c                 |  12 ++-
 hw/ppc/spapr.c                |  27 +++--
 hw/ppc/spapr_rtas.c           |   2 +-
 hw/sparc/sun4m.c              |   5 +-
 hw/timer/Makefile.objs        |   2 +-
 hw/timer/arm_mptimer.c        |   3 +-
 include/exec/cpu-all.h        |  66 ------------
 include/exec/cpu-common.h     |   2 +
 include/exec/cpu-defs.h       |   3 +-
 include/exec/gdbstub.h        |   2 +-
 include/exec/hwaddr.h         |   4 -
 include/exec/memory.h         |   2 +
 include/exec/poison.h         |  13 ---
 include/hw/ppc/ppc.h          |   2 -
 include/hw/ppc/ppc_e500.h     |   6 ++
 include/hw/sh4/sh.h           |   2 +
 include/qemu-common.h         |   8 --
 include/qemu/log.h            |   2 +-
 include/qom/cpu.h             | 165 ++++++++++++++++++++++++++++--
 include/sysemu/kvm.h          |  12 +--
 kvm-all.c                     |  45 ++++-----
 kvm-stub.c                    |  10 +-
 linux-user/elfload.c          |  21 ++--
 linux-user/linuxload.c        |   3 +-
 linux-user/main.c             |  56 ++++++-----
 linux-user/qemu.h             |   2 +-
 linux-user/signal.c           |  12 ++-
 linux-user/syscall.c          |  15 +--
 memory.c                      |  12 +--
 memory_mapping.c              |  16 +--
 monitor.c                     |  23 ++---
 qom/cpu.c                     |  60 +++++++----
 stubs/cpus.c                  |   5 +
 target-alpha/cpu-qom.h        |   2 +
 target-alpha/cpu.c            |   5 +-
 target-alpha/cpu.h            |   6 +-
 target-alpha/helper.c         |   6 +-
 target-alpha/mem_helper.c     |  10 +-
 target-arm/arm-semi.c         |   3 +-
 target-arm/cpu-qom.h          |   3 +
 target-arm/cpu.c              |   2 +-
 target-arm/translate.c        |   6 +-
 target-cris/cpu-qom.h         |   3 +
 target-cris/cpu.c             |   2 +-
 target-cris/helper.c          |   4 +-
 target-cris/translate.c       |   6 +-
 target-i386/arch_dump.c       |   7 +-
 target-i386/cpu-qom.h         |   3 +
 target-i386/cpu.c             |   2 +-
 target-i386/helper.c          |  26 +++--
 target-i386/kvm.c             |  20 ++--
 target-i386/misc_helper.c     |   2 +-
 target-lm32/cpu-qom.h         |   2 +
 target-lm32/cpu.c             |   3 +-
 target-lm32/translate.c       |   6 +-
 target-m68k/cpu-qom.h         |   2 +
 target-m68k/cpu.c             |   2 +-
 target-m68k/translate.c       |   6 +-
 target-microblaze/cpu-qom.h   |   2 +
 target-microblaze/cpu.c       |   4 +-
 target-microblaze/cpu.h       |   5 +-
 target-microblaze/helper.c    |   4 +-
 target-microblaze/op_helper.c |  17 +++-
 target-microblaze/translate.c |   6 +-
 target-mips/cpu-qom.h         |   2 +
 target-mips/cpu.c             |   3 +-
 target-mips/cpu.h             |   5 +-
 target-mips/op_helper.c       |  38 +++----
 target-mips/translate.c       |   6 +-
 target-moxie/cpu.c            |   8 +-
 target-moxie/cpu.h            |   2 +
 target-moxie/helper.c         |   4 +-
 target-moxie/translate.c      |   6 +-
 target-openrisc/cpu.c         |   2 +-
 target-openrisc/cpu.h         |   2 +
 target-openrisc/translate.c   |  12 ++-
 target-ppc/cpu-qom.h          |   4 +
 target-ppc/excp_helper.c      |   9 +-
 target-ppc/kvm.c              |   2 +-
 target-ppc/mmu-hash64.c       |   2 +-
 target-ppc/translate.c        |  15 +--
 target-ppc/translate_init.c   |   4 +-
 target-s390x/cpu-qom.h        |   2 +
 target-s390x/cpu.c            |   2 +-
 target-s390x/kvm.c            |   9 +-
 target-s390x/translate.c      |   6 +-
 target-sh4/cpu-qom.h          |   2 +
 target-sh4/cpu.c              |   2 +-
 target-sh4/translate.c        |   7 +-
 target-sparc/cpu-qom.h        |   2 +
 target-sparc/cpu.c            |  11 +-
 target-sparc/cpu.h            |   5 +-
 target-sparc/ldst_helper.c    |  27 +++--
 target-unicore32/cpu-qom.h    |   2 +
 target-unicore32/cpu.c        |   4 +-
 target-unicore32/translate.c  |   6 +-
 target-xtensa/cpu-qom.h       |   2 +
 target-xtensa/cpu.c           |   4 +-
 target-xtensa/op_helper.c     |   4 +-
 target-xtensa/translate.c     |   6 +-
 translate-all.c               |  32 +++---
 user-exec.c                   |   9 +-
 138 files changed, 964 insertions(+), 746 deletions(-)
 create mode 100644 include/hw/ppc/ppc_e500.h

-- 
1.8.1.4

^ permalink raw reply	[flat|nested] 98+ messages in thread

* [PATCH qom-cpu v2 01/29] kvm: Change kvm_cpu_synchronize_state() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
@ 2013-06-16 15:57   ` Andreas Färber
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
                     ` (28 subsequent siblings)
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: open list:Overall, Gleb Natapov, Marcelo Tosatti, Alexander Graf,
	open list:sPAPR, Andreas Färber, David Gibson

It no longer relies on CPUArchState since 20d695a.

Reviewed-by: liguang <lig.fnst@cn.fujitsu.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/ppc/spapr_rtas.c  |  2 +-
 include/sysemu/kvm.h |  4 ++--
 kvm-all.c            |  4 +---
 kvm-stub.c           |  2 +-
 target-i386/kvm.c    | 10 +++++-----
 5 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index f4bd3c9..42ed7dc 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -184,7 +184,7 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
         /* This will make sure qemu state is up to date with kvm, and
          * mark it dirty so our changes get flushed back before the
          * new cpu enters */
-        kvm_cpu_synchronize_state(env);
+        kvm_cpu_synchronize_state(cs);
 
         env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
         env->nip = start;
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 8b19322..3e1db28 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -259,14 +259,14 @@ int kvm_check_extension(KVMState *s, unsigned int extension);
 
 uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
                                       uint32_t index, int reg);
-void kvm_cpu_synchronize_state(CPUArchState *env);
+void kvm_cpu_synchronize_state(CPUState *cpu);
 
 /* generic hooks - to be moved/refactored once there are more users */
 
 static inline void cpu_synchronize_state(CPUArchState *env)
 {
     if (kvm_enabled()) {
-        kvm_cpu_synchronize_state(env);
+        kvm_cpu_synchronize_state(ENV_GET_CPU(env));
     }
 }
 
diff --git a/kvm-all.c b/kvm-all.c
index 405480e..e7202ff 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1585,10 +1585,8 @@ static void do_kvm_cpu_synchronize_state(void *arg)
     }
 }
 
-void kvm_cpu_synchronize_state(CPUArchState *env)
+void kvm_cpu_synchronize_state(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
-
     if (!cpu->kvm_vcpu_dirty) {
         run_on_cpu(cpu, do_kvm_cpu_synchronize_state, cpu);
     }
diff --git a/kvm-stub.c b/kvm-stub.c
index 22eaff0..128faf7 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -42,7 +42,7 @@ void kvm_flush_coalesced_mmio_buffer(void)
 {
 }
 
-void kvm_cpu_synchronize_state(CPUArchState *env)
+void kvm_cpu_synchronize_state(CPUState *cpu)
 {
 }
 
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 9ffb6ca..0b0adfd 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1857,7 +1857,7 @@ int kvm_arch_process_async_events(CPUState *cs)
 
         cs->interrupt_request &= ~CPU_INTERRUPT_MCE;
 
-        kvm_cpu_synchronize_state(env);
+        kvm_cpu_synchronize_state(cs);
 
         if (env->exception_injected == EXCP08_DBLE) {
             /* this means triple fault */
@@ -1888,16 +1888,16 @@ int kvm_arch_process_async_events(CPUState *cs)
         cs->halted = 0;
     }
     if (cs->interrupt_request & CPU_INTERRUPT_INIT) {
-        kvm_cpu_synchronize_state(env);
+        kvm_cpu_synchronize_state(cs);
         do_cpu_init(cpu);
     }
     if (cs->interrupt_request & CPU_INTERRUPT_SIPI) {
-        kvm_cpu_synchronize_state(env);
+        kvm_cpu_synchronize_state(cs);
         do_cpu_sipi(cpu);
     }
     if (cs->interrupt_request & CPU_INTERRUPT_TPR) {
         cs->interrupt_request &= ~CPU_INTERRUPT_TPR;
-        kvm_cpu_synchronize_state(env);
+        kvm_cpu_synchronize_state(cs);
         apic_handle_tpr_access_report(env->apic_state, env->eip,
                                       env->tpr_access_type);
     }
@@ -2184,7 +2184,7 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
 
-    kvm_cpu_synchronize_state(env);
+    kvm_cpu_synchronize_state(cs);
     return !(env->cr[0] & CR0_PE_MASK) ||
            ((env->segs[R_CS].selector  & 3) != 3);
 }
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 01/29] kvm: Change kvm_cpu_synchronize_state() argument to CPUState
@ 2013-06-16 15:57   ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: open list:Overall, Gleb Natapov, Marcelo Tosatti, Alexander Graf,
	open list:sPAPR, Andreas Färber, David Gibson

It no longer relies on CPUArchState since 20d695a.

Reviewed-by: liguang <lig.fnst@cn.fujitsu.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/ppc/spapr_rtas.c  |  2 +-
 include/sysemu/kvm.h |  4 ++--
 kvm-all.c            |  4 +---
 kvm-stub.c           |  2 +-
 target-i386/kvm.c    | 10 +++++-----
 5 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index f4bd3c9..42ed7dc 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -184,7 +184,7 @@ static void rtas_start_cpu(sPAPREnvironment *spapr,
         /* This will make sure qemu state is up to date with kvm, and
          * mark it dirty so our changes get flushed back before the
          * new cpu enters */
-        kvm_cpu_synchronize_state(env);
+        kvm_cpu_synchronize_state(cs);
 
         env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
         env->nip = start;
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 8b19322..3e1db28 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -259,14 +259,14 @@ int kvm_check_extension(KVMState *s, unsigned int extension);
 
 uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
                                       uint32_t index, int reg);
-void kvm_cpu_synchronize_state(CPUArchState *env);
+void kvm_cpu_synchronize_state(CPUState *cpu);
 
 /* generic hooks - to be moved/refactored once there are more users */
 
 static inline void cpu_synchronize_state(CPUArchState *env)
 {
     if (kvm_enabled()) {
-        kvm_cpu_synchronize_state(env);
+        kvm_cpu_synchronize_state(ENV_GET_CPU(env));
     }
 }
 
diff --git a/kvm-all.c b/kvm-all.c
index 405480e..e7202ff 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1585,10 +1585,8 @@ static void do_kvm_cpu_synchronize_state(void *arg)
     }
 }
 
-void kvm_cpu_synchronize_state(CPUArchState *env)
+void kvm_cpu_synchronize_state(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
-
     if (!cpu->kvm_vcpu_dirty) {
         run_on_cpu(cpu, do_kvm_cpu_synchronize_state, cpu);
     }
diff --git a/kvm-stub.c b/kvm-stub.c
index 22eaff0..128faf7 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -42,7 +42,7 @@ void kvm_flush_coalesced_mmio_buffer(void)
 {
 }
 
-void kvm_cpu_synchronize_state(CPUArchState *env)
+void kvm_cpu_synchronize_state(CPUState *cpu)
 {
 }
 
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 9ffb6ca..0b0adfd 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1857,7 +1857,7 @@ int kvm_arch_process_async_events(CPUState *cs)
 
         cs->interrupt_request &= ~CPU_INTERRUPT_MCE;
 
-        kvm_cpu_synchronize_state(env);
+        kvm_cpu_synchronize_state(cs);
 
         if (env->exception_injected == EXCP08_DBLE) {
             /* this means triple fault */
@@ -1888,16 +1888,16 @@ int kvm_arch_process_async_events(CPUState *cs)
         cs->halted = 0;
     }
     if (cs->interrupt_request & CPU_INTERRUPT_INIT) {
-        kvm_cpu_synchronize_state(env);
+        kvm_cpu_synchronize_state(cs);
         do_cpu_init(cpu);
     }
     if (cs->interrupt_request & CPU_INTERRUPT_SIPI) {
-        kvm_cpu_synchronize_state(env);
+        kvm_cpu_synchronize_state(cs);
         do_cpu_sipi(cpu);
     }
     if (cs->interrupt_request & CPU_INTERRUPT_TPR) {
         cs->interrupt_request &= ~CPU_INTERRUPT_TPR;
-        kvm_cpu_synchronize_state(env);
+        kvm_cpu_synchronize_state(cs);
         apic_handle_tpr_access_report(env->apic_state, env->eip,
                                       env->tpr_access_type);
     }
@@ -2184,7 +2184,7 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
 
-    kvm_cpu_synchronize_state(env);
+    kvm_cpu_synchronize_state(cs);
     return !(env->cr[0] & CR0_PE_MASK) ||
            ((env->segs[R_CS].selector  & 3) != 3);
 }
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH qom-cpu v2 02/29] kvm: Change cpu_synchronize_state() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
@ 2013-06-16 15:57   ` Andreas Färber
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
                     ` (28 subsequent siblings)
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Andreas Färber, Alexander Graf, Luiz Capitulino,
	Gleb Natapov, Marcelo Tosatti, Richard Henderson,
	open list:PowerPC, open list:X86

Change Monitor::mon_cpu to CPUState as well.
In cpu_synchronize_all_states() use qemu_for_each_cpu() now.

Reviewed-by: liguang <lig.fnst@cn.fujitsu.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c                  | 8 ++++----
 gdbstub.c               | 8 ++++----
 hw/i386/kvm/apic.c      | 2 +-
 hw/i386/kvmvapic.c      | 4 ++--
 hw/misc/vmport.c        | 2 +-
 hw/ppc/ppce500_spin.c   | 2 +-
 include/sysemu/kvm.h    | 4 ++--
 monitor.c               | 6 +++---
 target-i386/helper.c    | 4 ++--
 target-i386/kvm.c       | 2 +-
 target-ppc/mmu-hash64.c | 2 +-
 target-ppc/translate.c  | 2 +-
 target-s390x/kvm.c      | 9 +++++----
 13 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/cpus.c b/cpus.c
index c232265..3260f09 100644
--- a/cpus.c
+++ b/cpus.c
@@ -407,10 +407,10 @@ void hw_error(const char *fmt, ...)
 
 void cpu_synchronize_all_states(void)
 {
-    CPUArchState *cpu;
+    CPUArchState *env;
 
-    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
-        cpu_synchronize_state(cpu);
+    for (env = first_cpu; env; env = env->next_cpu) {
+        cpu_synchronize_state(ENV_GET_CPU(env));
     }
 }
 
@@ -1219,7 +1219,7 @@ CpuInfoList *qmp_query_cpus(Error **errp)
         CPUState *cpu = ENV_GET_CPU(env);
         CpuInfoList *info;
 
-        cpu_synchronize_state(env);
+        cpu_synchronize_state(cpu);
 
         info = g_malloc0(sizeof(*info));
         info->value = g_malloc0(sizeof(*info->value));
diff --git a/gdbstub.c b/gdbstub.c
index 94c78ce..bbae06d 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2033,7 +2033,7 @@ static void gdb_breakpoint_remove_all(void)
 
 static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
 {
-    cpu_synchronize_state(s->c_cpu);
+    cpu_synchronize_state(ENV_GET_CPU(s->c_cpu));
 #if defined(TARGET_I386)
     s->c_cpu->eip = pc;
 #elif defined (TARGET_PPC)
@@ -2232,7 +2232,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         }
         break;
     case 'g':
-        cpu_synchronize_state(s->g_cpu);
+        cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
         env = s->g_cpu;
         len = 0;
         for (addr = 0; addr < num_g_regs; addr++) {
@@ -2243,7 +2243,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         put_packet(s, buf);
         break;
     case 'G':
-        cpu_synchronize_state(s->g_cpu);
+        cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
         env = s->g_cpu;
         registers = mem_buf;
         len = strlen(p) / 2;
@@ -2411,7 +2411,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             env = find_cpu(thread);
             if (env != NULL) {
                 CPUState *cpu = ENV_GET_CPU(env);
-                cpu_synchronize_state(env);
+                cpu_synchronize_state(cpu);
                 len = snprintf((char *)mem_buf, sizeof(mem_buf),
                                "CPU#%d [%s]", cpu->cpu_index,
                                cpu->halted ? "halted " : "running");
diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
index 8f80425..bd0bdd8 100644
--- a/hw/i386/kvm/apic.c
+++ b/hw/i386/kvm/apic.c
@@ -129,7 +129,7 @@ static void do_inject_external_nmi(void *data)
     uint32_t lvt;
     int ret;
 
-    cpu_synchronize_state(&s->cpu->env);
+    cpu_synchronize_state(cpu);
 
     lvt = s->lvt[APIC_LVT_LINT1];
     if (!(lvt & APIC_LVT_MASKED) && ((lvt >> 8) & 7) == APIC_DM_NMI) {
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 655483b..f93629f 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -456,7 +456,7 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(cs);
 
     if (evaluate_tpr_instruction(s, env, &ip, access) < 0) {
         if (s->state == VAPIC_ACTIVE) {
@@ -627,7 +627,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
     hwaddr rom_paddr;
     VAPICROMState *s = opaque;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
 
     /*
      * The VAPIC supports two PIO-based hypercalls, both via port 0x7E.
diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c
index 57b71f5..8363dfd 100644
--- a/hw/misc/vmport.c
+++ b/hw/misc/vmport.c
@@ -66,7 +66,7 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
     unsigned char command;
     uint32_t eax;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
 
     eax = env->regs[R_EAX];
     if (eax != VMPORT_MAGIC)
diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c
index 1290d37..ea65414 100644
--- a/hw/ppc/ppce500_spin.c
+++ b/hw/ppc/ppce500_spin.c
@@ -98,7 +98,7 @@ static void spin_kick(void *data)
     hwaddr map_size = 64 * 1024 * 1024;
     hwaddr map_start;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(cpu);
     stl_p(&curspin->pir, env->spr[SPR_PIR]);
     env->nip = ldq_p(&curspin->addr) & (map_size - 1);
     env->gpr[3] = ldq_p(&curspin->r3);
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 3e1db28..06da2b3 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -263,10 +263,10 @@ void kvm_cpu_synchronize_state(CPUState *cpu);
 
 /* generic hooks - to be moved/refactored once there are more users */
 
-static inline void cpu_synchronize_state(CPUArchState *env)
+static inline void cpu_synchronize_state(CPUState *cpu)
 {
     if (kvm_enabled()) {
-        kvm_cpu_synchronize_state(ENV_GET_CPU(env));
+        kvm_cpu_synchronize_state(cpu);
     }
 }
 
diff --git a/monitor.c b/monitor.c
index 70ae8f5..19c297d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -191,7 +191,7 @@ struct Monitor {
     QString *outbuf;
     ReadLineState *rs;
     MonitorControl *mc;
-    CPUArchState *mon_cpu;
+    CPUState *mon_cpu;
     BlockDriverCompletionFunc *password_completion_cb;
     void *password_opaque;
     QError *error;
@@ -900,7 +900,7 @@ int monitor_set_cpu(int cpu_index)
     if (cpu == NULL) {
         return -1;
     }
-    cur_mon->mon_cpu = cpu->env_ptr;
+    cur_mon->mon_cpu = cpu;
     return 0;
 }
 
@@ -910,7 +910,7 @@ static CPUArchState *mon_get_cpu(void)
         monitor_set_cpu(0);
     }
     cpu_synchronize_state(cur_mon->mon_cpu);
-    return cur_mon->mon_cpu;
+    return cur_mon->mon_cpu->env_ptr;
 }
 
 int monitor_get_cpu_index(void)
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 158710a..803945d 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -187,7 +187,7 @@ void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
     char cc_op_name[32];
     static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(cs);
 
     eflags = cpu_compute_eflags(env);
 #ifdef TARGET_X86_64
@@ -1116,7 +1116,7 @@ static void do_inject_x86_mce(void *data)
     CPUState *cpu = CPU(params->cpu);
     uint64_t *banks = cenv->mce_banks + 4 * params->bank;
 
-    cpu_synchronize_state(cenv);
+    cpu_synchronize_state(cpu);
 
     /*
      * If there is an MCE exception being processed, ignore this SRAO MCE
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 0b0adfd..39f4fbb 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -2079,7 +2079,7 @@ static int kvm_handle_debug(X86CPU *cpu,
         ret = EXCP_DEBUG;
     }
     if (ret == 0) {
-        cpu_synchronize_state(env);
+        cpu_synchronize_state(CPU(cpu));
         assert(env->exception_injected == -1);
 
         /* pass to guest */
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 43ccf45..5c67ec3 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -78,7 +78,7 @@ void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
     int i;
     uint64_t slbe, slbv;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
 
     cpu_fprintf(f, "SLB\tESID\t\t\tVSID\n");
     for (i = 0; i < env->slb_nr; i++) {
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 4590c6f..076cdac 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9534,7 +9534,7 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
 
     int i;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
 
     cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
                 TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 4d9ac4a..e7b3049 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -450,7 +450,7 @@ static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
     uint64_t code;
     int r = 0;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(CPU(cpu));
     sccb = env->regs[ipbh0 & 0xf];
     code = env->regs[(ipbh0 & 0xf0) >> 4];
 
@@ -656,16 +656,17 @@ static int s390_store_status(CPUS390XState *env, uint32_t parameter)
 
 static int s390_cpu_initial_reset(S390CPU *cpu)
 {
+    CPUState *cs = CPU(cpu);
     CPUS390XState *env = &cpu->env;
     int i;
 
     s390_del_running_cpu(cpu);
-    if (kvm_vcpu_ioctl(CPU(cpu), KVM_S390_INITIAL_RESET, NULL) < 0) {
+    if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL) < 0) {
         perror("cannot init reset vcpu");
     }
 
     /* Manually zero out all registers */
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(cs);
     for (i = 0; i < 16; i++) {
         env->regs[i] = 0;
     }
@@ -685,7 +686,7 @@ static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
     S390CPU *target_cpu;
     CPUS390XState *target_env;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(CPU(cpu));
 
     /* get order code */
     order_code = run->s390_sieic.ipb >> 28;
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 02/29] kvm: Change cpu_synchronize_state() argument to CPUState
@ 2013-06-16 15:57   ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: open list:X86, Gleb Natapov, Marcelo Tosatti, Alexander Graf,
	Luiz Capitulino, open list:PowerPC, Andreas Färber,
	Richard Henderson

Change Monitor::mon_cpu to CPUState as well.
In cpu_synchronize_all_states() use qemu_for_each_cpu() now.

Reviewed-by: liguang <lig.fnst@cn.fujitsu.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c                  | 8 ++++----
 gdbstub.c               | 8 ++++----
 hw/i386/kvm/apic.c      | 2 +-
 hw/i386/kvmvapic.c      | 4 ++--
 hw/misc/vmport.c        | 2 +-
 hw/ppc/ppce500_spin.c   | 2 +-
 include/sysemu/kvm.h    | 4 ++--
 monitor.c               | 6 +++---
 target-i386/helper.c    | 4 ++--
 target-i386/kvm.c       | 2 +-
 target-ppc/mmu-hash64.c | 2 +-
 target-ppc/translate.c  | 2 +-
 target-s390x/kvm.c      | 9 +++++----
 13 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/cpus.c b/cpus.c
index c232265..3260f09 100644
--- a/cpus.c
+++ b/cpus.c
@@ -407,10 +407,10 @@ void hw_error(const char *fmt, ...)
 
 void cpu_synchronize_all_states(void)
 {
-    CPUArchState *cpu;
+    CPUArchState *env;
 
-    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
-        cpu_synchronize_state(cpu);
+    for (env = first_cpu; env; env = env->next_cpu) {
+        cpu_synchronize_state(ENV_GET_CPU(env));
     }
 }
 
@@ -1219,7 +1219,7 @@ CpuInfoList *qmp_query_cpus(Error **errp)
         CPUState *cpu = ENV_GET_CPU(env);
         CpuInfoList *info;
 
-        cpu_synchronize_state(env);
+        cpu_synchronize_state(cpu);
 
         info = g_malloc0(sizeof(*info));
         info->value = g_malloc0(sizeof(*info->value));
diff --git a/gdbstub.c b/gdbstub.c
index 94c78ce..bbae06d 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2033,7 +2033,7 @@ static void gdb_breakpoint_remove_all(void)
 
 static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
 {
-    cpu_synchronize_state(s->c_cpu);
+    cpu_synchronize_state(ENV_GET_CPU(s->c_cpu));
 #if defined(TARGET_I386)
     s->c_cpu->eip = pc;
 #elif defined (TARGET_PPC)
@@ -2232,7 +2232,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         }
         break;
     case 'g':
-        cpu_synchronize_state(s->g_cpu);
+        cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
         env = s->g_cpu;
         len = 0;
         for (addr = 0; addr < num_g_regs; addr++) {
@@ -2243,7 +2243,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         put_packet(s, buf);
         break;
     case 'G':
-        cpu_synchronize_state(s->g_cpu);
+        cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
         env = s->g_cpu;
         registers = mem_buf;
         len = strlen(p) / 2;
@@ -2411,7 +2411,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             env = find_cpu(thread);
             if (env != NULL) {
                 CPUState *cpu = ENV_GET_CPU(env);
-                cpu_synchronize_state(env);
+                cpu_synchronize_state(cpu);
                 len = snprintf((char *)mem_buf, sizeof(mem_buf),
                                "CPU#%d [%s]", cpu->cpu_index,
                                cpu->halted ? "halted " : "running");
diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
index 8f80425..bd0bdd8 100644
--- a/hw/i386/kvm/apic.c
+++ b/hw/i386/kvm/apic.c
@@ -129,7 +129,7 @@ static void do_inject_external_nmi(void *data)
     uint32_t lvt;
     int ret;
 
-    cpu_synchronize_state(&s->cpu->env);
+    cpu_synchronize_state(cpu);
 
     lvt = s->lvt[APIC_LVT_LINT1];
     if (!(lvt & APIC_LVT_MASKED) && ((lvt >> 8) & 7) == APIC_DM_NMI) {
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 655483b..f93629f 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -456,7 +456,7 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
     X86CPU *cpu = X86_CPU(cs);
     CPUX86State *env = &cpu->env;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(cs);
 
     if (evaluate_tpr_instruction(s, env, &ip, access) < 0) {
         if (s->state == VAPIC_ACTIVE) {
@@ -627,7 +627,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
     hwaddr rom_paddr;
     VAPICROMState *s = opaque;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
 
     /*
      * The VAPIC supports two PIO-based hypercalls, both via port 0x7E.
diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c
index 57b71f5..8363dfd 100644
--- a/hw/misc/vmport.c
+++ b/hw/misc/vmport.c
@@ -66,7 +66,7 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
     unsigned char command;
     uint32_t eax;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
 
     eax = env->regs[R_EAX];
     if (eax != VMPORT_MAGIC)
diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c
index 1290d37..ea65414 100644
--- a/hw/ppc/ppce500_spin.c
+++ b/hw/ppc/ppce500_spin.c
@@ -98,7 +98,7 @@ static void spin_kick(void *data)
     hwaddr map_size = 64 * 1024 * 1024;
     hwaddr map_start;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(cpu);
     stl_p(&curspin->pir, env->spr[SPR_PIR]);
     env->nip = ldq_p(&curspin->addr) & (map_size - 1);
     env->gpr[3] = ldq_p(&curspin->r3);
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 3e1db28..06da2b3 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -263,10 +263,10 @@ void kvm_cpu_synchronize_state(CPUState *cpu);
 
 /* generic hooks - to be moved/refactored once there are more users */
 
-static inline void cpu_synchronize_state(CPUArchState *env)
+static inline void cpu_synchronize_state(CPUState *cpu)
 {
     if (kvm_enabled()) {
-        kvm_cpu_synchronize_state(ENV_GET_CPU(env));
+        kvm_cpu_synchronize_state(cpu);
     }
 }
 
diff --git a/monitor.c b/monitor.c
index 70ae8f5..19c297d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -191,7 +191,7 @@ struct Monitor {
     QString *outbuf;
     ReadLineState *rs;
     MonitorControl *mc;
-    CPUArchState *mon_cpu;
+    CPUState *mon_cpu;
     BlockDriverCompletionFunc *password_completion_cb;
     void *password_opaque;
     QError *error;
@@ -900,7 +900,7 @@ int monitor_set_cpu(int cpu_index)
     if (cpu == NULL) {
         return -1;
     }
-    cur_mon->mon_cpu = cpu->env_ptr;
+    cur_mon->mon_cpu = cpu;
     return 0;
 }
 
@@ -910,7 +910,7 @@ static CPUArchState *mon_get_cpu(void)
         monitor_set_cpu(0);
     }
     cpu_synchronize_state(cur_mon->mon_cpu);
-    return cur_mon->mon_cpu;
+    return cur_mon->mon_cpu->env_ptr;
 }
 
 int monitor_get_cpu_index(void)
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 158710a..803945d 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -187,7 +187,7 @@ void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
     char cc_op_name[32];
     static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(cs);
 
     eflags = cpu_compute_eflags(env);
 #ifdef TARGET_X86_64
@@ -1116,7 +1116,7 @@ static void do_inject_x86_mce(void *data)
     CPUState *cpu = CPU(params->cpu);
     uint64_t *banks = cenv->mce_banks + 4 * params->bank;
 
-    cpu_synchronize_state(cenv);
+    cpu_synchronize_state(cpu);
 
     /*
      * If there is an MCE exception being processed, ignore this SRAO MCE
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 0b0adfd..39f4fbb 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -2079,7 +2079,7 @@ static int kvm_handle_debug(X86CPU *cpu,
         ret = EXCP_DEBUG;
     }
     if (ret == 0) {
-        cpu_synchronize_state(env);
+        cpu_synchronize_state(CPU(cpu));
         assert(env->exception_injected == -1);
 
         /* pass to guest */
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 43ccf45..5c67ec3 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -78,7 +78,7 @@ void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
     int i;
     uint64_t slbe, slbv;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
 
     cpu_fprintf(f, "SLB\tESID\t\t\tVSID\n");
     for (i = 0; i < env->slb_nr; i++) {
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 4590c6f..076cdac 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9534,7 +9534,7 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
 
     int i;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
 
     cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
                 TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 4d9ac4a..e7b3049 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -450,7 +450,7 @@ static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
     uint64_t code;
     int r = 0;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(CPU(cpu));
     sccb = env->regs[ipbh0 & 0xf];
     code = env->regs[(ipbh0 & 0xf0) >> 4];
 
@@ -656,16 +656,17 @@ static int s390_store_status(CPUS390XState *env, uint32_t parameter)
 
 static int s390_cpu_initial_reset(S390CPU *cpu)
 {
+    CPUState *cs = CPU(cpu);
     CPUS390XState *env = &cpu->env;
     int i;
 
     s390_del_running_cpu(cpu);
-    if (kvm_vcpu_ioctl(CPU(cpu), KVM_S390_INITIAL_RESET, NULL) < 0) {
+    if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL) < 0) {
         perror("cannot init reset vcpu");
     }
 
     /* Manually zero out all registers */
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(cs);
     for (i = 0; i < 16; i++) {
         env->regs[i] = 0;
     }
@@ -685,7 +686,7 @@ static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
     S390CPU *target_cpu;
     CPUS390XState *target_env;
 
-    cpu_synchronize_state(env);
+    cpu_synchronize_state(CPU(cpu));
 
     /* get order code */
     order_code = run->s390_sieic.ipb >> 28;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 03/29] gdbstub: Simplify find_cpu()
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-17 19:54   ` Richard Henderson
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 04/29] cpu: Change cpu_exit() argument to CPUState Andreas Färber
                   ` (26 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Use qemu_get_cpu() and CPUState::env_ptr.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index bbae06d..663549c 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2071,17 +2071,13 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
 
 static CPUArchState *find_cpu(uint32_t thread_id)
 {
-    CPUArchState *env;
     CPUState *cpu;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = ENV_GET_CPU(env);
-        if (cpu_index(cpu) == thread_id) {
-            return env;
-        }
+    cpu = qemu_get_cpu(thread_id);
+    if (cpu == NULL) {
+        return NULL;
     }
-
-    return NULL;
+    return cpu->env_ptr;
 }
 
 static int gdb_handle_packet(GDBState *s, const char *line_buf)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 04/29] cpu: Change cpu_exit() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (2 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 03/29] gdbstub: Simplify find_cpu() Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-17 19:59   ` Richard Henderson
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 05/29] cpus: Change cpu_thread_is_idle() " Andreas Färber
                   ` (25 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Anthony Liguori, Riku Voipio, Alexander Graf,
	Andreas Färber, Hervé Poussineau, open list:PReP,
	Andreas Färber, Aurelien Jarno

It no longer depends on CPUArchState, so move it to qom/cpu.c.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c                  | 4 ++--
 exec.c                  | 8 --------
 gdbstub.c               | 2 +-
 hw/i386/pc.c            | 2 +-
 hw/mips/mips_fulong2e.c | 2 +-
 hw/mips/mips_jazz.c     | 2 +-
 hw/mips/mips_malta.c    | 2 +-
 hw/ppc/prep.c           | 2 +-
 include/exec/cpu-all.h  | 2 --
 include/qom/cpu.h       | 8 ++++++++
 linux-user/main.c       | 2 +-
 linux-user/signal.c     | 2 +-
 qom/cpu.c               | 6 ++++++
 13 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/cpus.c b/cpus.c
index 3260f09..ab0eb4f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -473,7 +473,7 @@ static void cpu_handle_guest_debug(CPUArchState *env)
 static void cpu_signal(int sig)
 {
     if (cpu_single_env) {
-        cpu_exit(cpu_single_env);
+        cpu_exit(ENV_GET_CPU(cpu_single_env));
     }
     exit_request = 1;
 }
@@ -1088,7 +1088,7 @@ void cpu_stop_current(void)
         CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
         cpu_single_cpu->stop = false;
         cpu_single_cpu->stopped = true;
-        cpu_exit(cpu_single_env);
+        cpu_exit(cpu_single_cpu);
         qemu_cond_signal(&qemu_pause_cond);
     }
 }
diff --git a/exec.c b/exec.c
index 5b8b40d..c0fa5a3 100644
--- a/exec.c
+++ b/exec.c
@@ -515,14 +515,6 @@ void cpu_single_step(CPUArchState *env, int enabled)
 #endif
 }
 
-void cpu_exit(CPUArchState *env)
-{
-    CPUState *cpu = ENV_GET_CPU(env);
-
-    cpu->exit_request = 1;
-    cpu->tcg_exit_req = 1;
-}
-
 void cpu_abort(CPUArchState *env, const char *fmt, ...)
 {
     va_list ap;
diff --git a/gdbstub.c b/gdbstub.c
index 663549c..0f15c7c 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2655,7 +2655,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
        is still in the running state, which can cause packets to be dropped
        and state transition 'T' packets to be sent while the syscall is still
        being processed.  */
-    cpu_exit(s->c_cpu);
+    cpu_exit(ENV_GET_CPU(s->c_cpu));
 #endif
 }
 
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e0fbb86..d7e8507 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1110,7 +1110,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
     CPUX86State *env = cpu_single_env;
 
     if (env && level) {
-        cpu_exit(env);
+        cpu_exit(CPU(x86_env_get_cpu(env)));
     }
 }
 
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index 1aac93a..00c9071 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -253,7 +253,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
     CPUMIPSState *env = cpu_single_env;
 
     if (env && level) {
-        cpu_exit(env);
+        cpu_exit(CPU(mips_env_get_cpu(env)));
     }
 }
 
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 94d9570..2ad0c0b 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -102,7 +102,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
     CPUMIPSState *env = cpu_single_env;
 
     if (env && level) {
-        cpu_exit(env);
+        cpu_exit(CPU(mips_env_get_cpu(env)));
     }
 }
 
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 5033d51..8a4459d 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -773,7 +773,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
     CPUMIPSState *env = cpu_single_env;
 
     if (env && level) {
-        cpu_exit(env);
+        cpu_exit(CPU(mips_env_get_cpu(env)));
     }
 }
 
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 4fdc164..90828f2 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -420,7 +420,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
     CPUPPCState *env = cpu_single_env;
 
     if (env && level) {
-        cpu_exit(env);
+        cpu_exit(CPU(ppc_env_get_cpu(env)));
     }
 }
 
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index e9c3717..e1cc62e 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -421,8 +421,6 @@ DECLARE_TLS(CPUArchState *,cpu_single_env);
      | CPU_INTERRUPT_TGT_EXT_3   \
      | CPU_INTERRUPT_TGT_EXT_4)
 
-void cpu_exit(CPUArchState *s);
-
 /* Breakpoint/watchpoint flags */
 #define BP_MEM_READ           0x01
 #define BP_MEM_WRITE          0x02
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index a5bb515..f633686 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -350,6 +350,14 @@ void cpu_interrupt(CPUState *cpu, int mask);
 void cpu_reset_interrupt(CPUState *cpu, int mask);
 
 /**
+ * cpu_exit:
+ * @cpu: The CPU to exit.
+ *
+ * Requests the CPU @cpu to exit execution.
+ */
+void cpu_exit(CPUState *cpu);
+
+/**
  * cpu_resume:
  * @cpu: The CPU to resume.
  *
diff --git a/linux-user/main.c b/linux-user/main.c
index b97b8cf..30e7953 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -160,7 +160,7 @@ static inline void start_exclusive(void)
         other_cpu = ENV_GET_CPU(other);
         if (other_cpu->running) {
             pending_cpus++;
-            cpu_exit(other);
+            cpu_exit(other_cpu);
         }
     }
     if (pending_cpus > 1) {
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 5da8452..c4e20dc 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -524,7 +524,7 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
     host_to_target_siginfo_noswap(&tinfo, info);
     if (queue_signal(thread_env, sig, &tinfo) == 1) {
         /* interrupt the virtual CPU as soon as possible */
-        cpu_exit(thread_env);
+        cpu_exit(ENV_GET_CPU(thread_env));
     }
 }
 
diff --git a/qom/cpu.c b/qom/cpu.c
index dba4a11..8a122b0 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -91,6 +91,12 @@ void cpu_reset_interrupt(CPUState *cpu, int mask)
     cpu->interrupt_request &= ~mask;
 }
 
+void cpu_exit(CPUState *cpu)
+{
+    cpu->exit_request = 1;
+    cpu->tcg_exit_req = 1;
+}
+
 int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
                              void *opaque)
 {
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 05/29] cpus: Change cpu_thread_is_idle() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (3 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 04/29] cpu: Change cpu_exit() argument to CPUState Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-17 20:00   ` Richard Henderson
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 06/29] cpus: Change qemu_kvm_wait_io_event() " Andreas Färber
                   ` (24 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

It no longer needs CPUArchState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/cpus.c b/cpus.c
index ab0eb4f..17cc85b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -62,10 +62,8 @@
 
 static CPUArchState *next_cpu;
 
-static bool cpu_thread_is_idle(CPUArchState *env)
+static bool cpu_thread_is_idle(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
-
     if (cpu->stop || cpu->queued_work_first) {
         return false;
     }
@@ -84,7 +82,7 @@ static bool all_cpu_threads_idle(void)
     CPUArchState *env;
 
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        if (!cpu_thread_is_idle(env)) {
+        if (!cpu_thread_is_idle(ENV_GET_CPU(env))) {
             return false;
         }
     }
@@ -723,7 +721,7 @@ static void qemu_kvm_wait_io_event(CPUArchState *env)
 {
     CPUState *cpu = ENV_GET_CPU(env);
 
-    while (cpu_thread_is_idle(env)) {
+    while (cpu_thread_is_idle(cpu)) {
         qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
     }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 06/29] cpus: Change qemu_kvm_wait_io_event() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (4 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 05/29] cpus: Change cpu_thread_is_idle() " Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-17 20:02   ` Richard Henderson
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
                   ` (23 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

It no longer uses CPUArchState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/cpus.c b/cpus.c
index 17cc85b..fe19962 100644
--- a/cpus.c
+++ b/cpus.c
@@ -717,10 +717,8 @@ static void qemu_tcg_wait_io_event(void)
     }
 }
 
-static void qemu_kvm_wait_io_event(CPUArchState *env)
+static void qemu_kvm_wait_io_event(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
-
     while (cpu_thread_is_idle(cpu)) {
         qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
     }
@@ -759,7 +757,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
                 cpu_handle_guest_debug(env);
             }
         }
-        qemu_kvm_wait_io_event(env);
+        qemu_kvm_wait_io_event(cpu);
     }
 
     return NULL;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH qom-cpu v2 07/29] kvm: Change kvm_set_signal_mask() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
@ 2013-06-16 15:57   ` Andreas Färber
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
                     ` (28 subsequent siblings)
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Andreas Färber, Gleb Natapov, Marcelo Tosatti, open list:Overall

CPUArchState is no longer needed.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c               | 3 ++-
 include/sysemu/kvm.h | 2 +-
 kvm-all.c            | 3 +--
 kvm-stub.c           | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/cpus.c b/cpus.c
index fe19962..fca5e1f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -570,6 +570,7 @@ static void dummy_signal(int sig)
 
 static void qemu_kvm_init_cpu_signals(CPUArchState *env)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     int r;
     sigset_t set;
     struct sigaction sigact;
@@ -581,7 +582,7 @@ static void qemu_kvm_init_cpu_signals(CPUArchState *env)
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
-    r = kvm_set_signal_mask(env, &set);
+    r = kvm_set_signal_mask(cpu, &set);
     if (r) {
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
         exit(1);
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 06da2b3..5adb044 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -166,7 +166,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
 void kvm_remove_all_breakpoints(CPUArchState *current_env);
 int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
 #ifndef _WIN32
-int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset);
+int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset);
 #endif
 
 int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
diff --git a/kvm-all.c b/kvm-all.c
index e7202ff..88297b1 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -2034,9 +2034,8 @@ void kvm_remove_all_breakpoints(CPUArchState *current_env)
 }
 #endif /* !KVM_CAP_SET_GUEST_DEBUG */
 
-int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
+int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_signal_mask *sigmask;
     int r;
 
diff --git a/kvm-stub.c b/kvm-stub.c
index 128faf7..50af700 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -100,7 +100,7 @@ void kvm_remove_all_breakpoints(CPUArchState *current_env)
 }
 
 #ifndef _WIN32
-int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
+int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)
 {
     abort();
 }
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 07/29] kvm: Change kvm_set_signal_mask() argument to CPUState
@ 2013-06-16 15:57   ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marcelo Tosatti, Andreas Färber, Gleb Natapov, open list:Overall

CPUArchState is no longer needed.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c               | 3 ++-
 include/sysemu/kvm.h | 2 +-
 kvm-all.c            | 3 +--
 kvm-stub.c           | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/cpus.c b/cpus.c
index fe19962..fca5e1f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -570,6 +570,7 @@ static void dummy_signal(int sig)
 
 static void qemu_kvm_init_cpu_signals(CPUArchState *env)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     int r;
     sigset_t set;
     struct sigaction sigact;
@@ -581,7 +582,7 @@ static void qemu_kvm_init_cpu_signals(CPUArchState *env)
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
-    r = kvm_set_signal_mask(env, &set);
+    r = kvm_set_signal_mask(cpu, &set);
     if (r) {
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
         exit(1);
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 06da2b3..5adb044 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -166,7 +166,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
 void kvm_remove_all_breakpoints(CPUArchState *current_env);
 int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
 #ifndef _WIN32
-int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset);
+int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset);
 #endif
 
 int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
diff --git a/kvm-all.c b/kvm-all.c
index e7202ff..88297b1 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -2034,9 +2034,8 @@ void kvm_remove_all_breakpoints(CPUArchState *current_env)
 }
 #endif /* !KVM_CAP_SET_GUEST_DEBUG */
 
-int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
+int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_signal_mask *sigmask;
     int r;
 
diff --git a/kvm-stub.c b/kvm-stub.c
index 128faf7..50af700 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -100,7 +100,7 @@ void kvm_remove_all_breakpoints(CPUArchState *current_env)
 }
 
 #ifndef _WIN32
-int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
+int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)
 {
     abort();
 }
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 08/29] cpus: Change qemu_kvm_init_cpu_signals() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (6 preceding siblings ...)
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-17 20:04   ` Richard Henderson
  2013-06-16 15:57   ` [Qemu-devel] [PATCH qom-cpu v2 09/29] cpu: Turn cpu_dump_{state, statistics}() " Andreas Färber
                   ` (21 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/cpus.c b/cpus.c
index fca5e1f..a5b0e46 100644
--- a/cpus.c
+++ b/cpus.c
@@ -568,9 +568,8 @@ static void dummy_signal(int sig)
 {
 }
 
-static void qemu_kvm_init_cpu_signals(CPUArchState *env)
+static void qemu_kvm_init_cpu_signals(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     int r;
     sigset_t set;
     struct sigaction sigact;
@@ -604,7 +603,7 @@ static void qemu_tcg_init_cpu_signals(void)
 }
 
 #else /* _WIN32 */
-static void qemu_kvm_init_cpu_signals(CPUArchState *env)
+static void qemu_kvm_init_cpu_signals(CPUState *cpu)
 {
     abort();
 }
@@ -745,7 +744,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
         exit(1);
     }
 
-    qemu_kvm_init_cpu_signals(env);
+    qemu_kvm_init_cpu_signals(cpu);
 
     /* signal CPU creation */
     cpu->created = true;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH qom-cpu v2 09/29] cpu: Turn cpu_dump_{state,statistics}() into CPUState hooks
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
@ 2013-06-16 15:57   ` Andreas Färber
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
                     ` (28 subsequent siblings)
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Andreas Färber, Blue Swirl, Gleb Natapov, Marcelo Tosatti,
	Riku Voipio, Luiz Capitulino, Richard Henderson, Paul Brook,
	Peter Maydell, Edgar E. Iglesias, Michael Walle, Aurelien Jarno,
	Anthony Green, Alexander Graf, Guan Xuetao, Max Filippov,
	open list:Overall, open list:PowerPC

Make cpustats monitor command available unconditionally.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 bsd-user/main.c               |  3 ++-
 cpus.c                        |  2 +-
 exec.c                        |  3 ++-
 include/exec/cpu-all.h        | 10 ----------
 include/qemu/log.h            |  2 +-
 include/qom/cpu.h             | 42 ++++++++++++++++++++++++++++++++++++++++++
 kvm-all.c                     |  4 ++--
 linux-user/main.c             | 38 +++++++++++++++++++++++---------------
 monitor.c                     | 13 ++++++-------
 qom/cpu.c                     | 22 +++++++++++++++++++++-
 stubs/cpus.c                  |  1 +
 target-alpha/cpu-qom.h        |  2 ++
 target-alpha/cpu.c            |  1 +
 target-alpha/helper.c         |  6 ++++--
 target-arm/arm-semi.c         |  3 ++-
 target-arm/cpu-qom.h          |  3 +++
 target-arm/cpu.c              |  1 +
 target-arm/translate.c        |  6 ++++--
 target-cris/cpu-qom.h         |  3 +++
 target-cris/cpu.c             |  1 +
 target-cris/helper.c          |  4 +++-
 target-cris/translate.c       |  6 ++++--
 target-i386/cpu-qom.h         |  3 +++
 target-i386/cpu.c             |  1 +
 target-i386/helper.c          |  7 ++++---
 target-lm32/cpu-qom.h         |  2 ++
 target-lm32/cpu.c             |  1 +
 target-lm32/translate.c       |  6 ++++--
 target-m68k/cpu-qom.h         |  2 ++
 target-m68k/cpu.c             |  1 +
 target-m68k/translate.c       |  6 ++++--
 target-microblaze/cpu-qom.h   |  2 ++
 target-microblaze/cpu.c       |  1 +
 target-microblaze/helper.c    |  4 +++-
 target-microblaze/translate.c |  6 ++++--
 target-mips/cpu-qom.h         |  2 ++
 target-mips/cpu.c             |  1 +
 target-mips/translate.c       |  6 ++++--
 target-moxie/cpu.c            |  3 ++-
 target-moxie/cpu.h            |  2 ++
 target-moxie/helper.c         |  4 +++-
 target-moxie/translate.c      |  6 ++++--
 target-openrisc/cpu.c         |  1 +
 target-openrisc/cpu.h         |  2 ++
 target-openrisc/translate.c   | 12 +++++++-----
 target-ppc/cpu-qom.h          |  4 ++++
 target-ppc/translate.c        | 15 +++++++++------
 target-ppc/translate_init.c   |  2 ++
 target-s390x/cpu-qom.h        |  2 ++
 target-s390x/cpu.c            |  1 +
 target-s390x/translate.c      |  6 ++++--
 target-sh4/cpu-qom.h          |  2 ++
 target-sh4/cpu.c              |  1 +
 target-sh4/translate.c        |  7 ++++---
 target-sparc/cpu-qom.h        |  2 ++
 target-sparc/cpu.c            |  7 +++++--
 target-unicore32/cpu-qom.h    |  2 ++
 target-unicore32/cpu.c        |  1 +
 target-unicore32/translate.c  |  6 ++++--
 target-xtensa/cpu-qom.h       |  2 ++
 target-xtensa/cpu.c           |  1 +
 target-xtensa/op_helper.c     |  4 +++-
 target-xtensa/translate.c     |  6 ++++--
 63 files changed, 242 insertions(+), 86 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 0da3ab9..b13803e 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -511,6 +511,7 @@ static void flush_windows(CPUSPARCState *env)
 
 void cpu_loop(CPUSPARCState *env)
 {
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
     int trapnr, ret, syscall_nr;
     //target_siginfo_t info;
 
@@ -659,7 +660,7 @@ void cpu_loop(CPUSPARCState *env)
         badtrap:
 #endif
             printf ("Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit (1);
         }
         process_pending_signals (env);
diff --git a/cpus.c b/cpus.c
index a5b0e46..bbaf13c 100644
--- a/cpus.c
+++ b/cpus.c
@@ -397,7 +397,7 @@ void hw_error(const char *fmt, ...)
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
         cpu = ENV_GET_CPU(env);
         fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
-        cpu_dump_state(env, stderr, fprintf, CPU_DUMP_FPU);
+        cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU);
     }
     va_end(ap);
     abort();
diff --git a/exec.c b/exec.c
index c0fa5a3..2b99bb9 100644
--- a/exec.c
+++ b/exec.c
@@ -517,6 +517,7 @@ void cpu_single_step(CPUArchState *env, int enabled)
 
 void cpu_abort(CPUArchState *env, const char *fmt, ...)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     va_list ap;
     va_list ap2;
 
@@ -525,7 +526,7 @@ void cpu_abort(CPUArchState *env, const char *fmt, ...)
     fprintf(stderr, "qemu: fatal: ");
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
-    cpu_dump_state(env, stderr, fprintf, CPU_DUMP_FPU | CPU_DUMP_CCOP);
+    cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU | CPU_DUMP_CCOP);
     if (qemu_log_enabled()) {
         qemu_log("qemu: fatal: ");
         qemu_log_vprintf(fmt, ap2);
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index e1cc62e..35bdf85 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -355,16 +355,6 @@ int page_check_range(target_ulong start, target_ulong len, int flags);
 
 CPUArchState *cpu_copy(CPUArchState *env);
 
-#define CPU_DUMP_CODE 0x00010000
-#define CPU_DUMP_FPU 0x00020000 /* dump FPU register state, not just integer */
-/* dump info about TCG QEMU's condition code optimization state */
-#define CPU_DUMP_CCOP 0x00040000
-
-void cpu_dump_state(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags);
-void cpu_dump_statistics(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
-                         int flags);
-
 void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 extern CPUArchState *first_cpu;
diff --git a/include/qemu/log.h b/include/qemu/log.h
index fd76f91..a9cf214 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -75,7 +75,7 @@ void GCC_FMT_ATTR(2, 3) qemu_log_mask(int mask, const char *fmt, ...);
 static inline void log_cpu_state(CPUArchState *env1, int flags)
 {
     if (qemu_log_enabled()) {
-        cpu_dump_state(env1, qemu_logfile, fprintf, flags);
+        cpu_dump_state(ENV_GET_CPU(env1), qemu_logfile, fprintf, flags);
     }
 }
 
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index f633686..e25898d 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -48,6 +48,8 @@ typedef struct CPUState CPUState;
  * instantiatable CPU type.
  * @reset: Callback to reset the #CPUState to its initial state.
  * @do_interrupt: Callback for interrupt handling.
+ * @dump_state: Callback for dumping state.
+ * @dump_statistics: Callback for dumping statistics.
  * @get_arch_id: Callback for getting architecture-dependent CPU ID.
  * @get_paging_enabled: Callback for inquiring whether paging is enabled.
  * @get_memory_mapping: Callback for obtaining the memory mappings.
@@ -64,6 +66,10 @@ typedef struct CPUClass {
 
     void (*reset)(CPUState *cpu);
     void (*do_interrupt)(CPUState *cpu);
+    void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                       int flags);
+    void (*dump_statistics)(CPUState *cpu, FILE *f,
+                            fprintf_function cpu_fprintf, int flags);
     int64_t (*get_arch_id)(CPUState *cpu);
     bool (*get_paging_enabled)(const CPUState *cpu);
     void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
@@ -201,6 +207,42 @@ int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
                              void *opaque);
 
 /**
+ * CPUDumpFlags:
+ * @CPU_DUMP_CODE:
+ * @CPU_DUMP_FPU: dump FPU register state, not just integer
+ * @CPU_DUMP_CCOP: dump info about TCG QEMU's condition code optimization state
+ */
+enum CPUDumpFlags {
+    CPU_DUMP_CODE = 0x00010000,
+    CPU_DUMP_FPU  = 0x00020000,
+    CPU_DUMP_CCOP = 0x00040000,
+};
+
+/**
+ * cpu_dump_state:
+ * @cpu: The CPU whose state is to be dumped.
+ * @f: File to dump to.
+ * @cpu_fprintf: Function to dump with.
+ * @flags: Flags what to dump.
+ *
+ * Dumps CPU state.
+ */
+void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                    int flags);
+
+/**
+ * cpu_dump_statistics:
+ * @cpu: The CPU whose state is to be dumped.
+ * @f: File to dump to.
+ * @cpu_fprintf: Function to dump with.
+ * @flags: Flags what to dump.
+ *
+ * Dumps CPU statistics.
+ */
+void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
+
+/**
  * cpu_reset:
  * @cpu: The CPU whose state is to be reset.
  */
diff --git a/kvm-all.c b/kvm-all.c
index 88297b1..1cd4573 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1539,7 +1539,7 @@ static int kvm_handle_internal_error(CPUArchState *env, struct kvm_run *run)
     if (run->internal.suberror == KVM_INTERNAL_ERROR_EMULATION) {
         fprintf(stderr, "emulation failure\n");
         if (!kvm_arch_stop_on_emulation_error(cpu)) {
-            cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
+            cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE);
             return EXCP_INTERRUPT;
         }
     }
@@ -1695,7 +1695,7 @@ int kvm_cpu_exec(CPUArchState *env)
     } while (ret == 0);
 
     if (ret < 0) {
-        cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
+        cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE);
         vm_stop(RUN_STATE_INTERNAL_ERROR);
     }
 
diff --git a/linux-user/main.c b/linux-user/main.c
index 30e7953..95e17cf 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -901,7 +901,7 @@ void cpu_loop(CPUARMState *env)
         error:
             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
                     trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             abort();
         }
         process_pending_signals(env);
@@ -985,7 +985,7 @@ void cpu_loop(CPUUniCore32State *env)
 
 error:
     fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
-    cpu_dump_state(env, stderr, fprintf, 0);
+    cpu_dump_state(cs, stderr, fprintf, 0);
     abort();
 }
 #endif
@@ -1115,6 +1115,7 @@ static void flush_windows(CPUSPARCState *env)
 
 void cpu_loop (CPUSPARCState *env)
 {
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
     int trapnr;
     abi_long ret;
     target_siginfo_t info;
@@ -1246,7 +1247,7 @@ void cpu_loop (CPUSPARCState *env)
             break;
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit (1);
         }
         process_pending_signals (env);
@@ -1304,7 +1305,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
 #define EXCP_DUMP(env, fmt, ...)                                        \
 do {                                                                    \
     fprintf(stderr, fmt , ## __VA_ARGS__);                              \
-    cpu_dump_state(env, stderr, fprintf, 0);                            \
+    cpu_dump_state(ENV_GET_CPU(env), stderr, fprintf, 0);               \
     qemu_log(fmt, ## __VA_ARGS__);                                      \
     if (qemu_log_enabled()) {                                           \
         log_cpu_state(env, 0);                                          \
@@ -2391,7 +2392,7 @@ done_syscall:
 error:
             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
                     trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             abort();
         }
         process_pending_signals(env);
@@ -2403,6 +2404,7 @@ error:
 
 void cpu_loop(CPUOpenRISCState *env)
 {
+    CPUState *cs = CPU(openrisc_env_get_cpu(env));
     int trapnr, gdbsig;
 
     for (;;) {
@@ -2420,7 +2422,7 @@ void cpu_loop(CPUOpenRISCState *env)
             break;
         case EXCP_DPF:
         case EXCP_IPF:
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             gdbsig = TARGET_SIGSEGV;
             break;
         case EXCP_TICK:
@@ -2469,7 +2471,7 @@ void cpu_loop(CPUOpenRISCState *env)
         default:
             qemu_log("\nqemu: unhandled CPU exception %#x - aborting\n",
                      trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             gdbsig = TARGET_SIGILL;
             break;
         }
@@ -2489,6 +2491,7 @@ void cpu_loop(CPUOpenRISCState *env)
 #ifdef TARGET_SH4
 void cpu_loop(CPUSH4State *env)
 {
+    CPUState *cs = CPU(sh_env_get_cpu(env));
     int trapnr, ret;
     target_siginfo_t info;
 
@@ -2537,7 +2540,7 @@ void cpu_loop(CPUSH4State *env)
 
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit (1);
         }
         process_pending_signals (env);
@@ -2548,6 +2551,7 @@ void cpu_loop(CPUSH4State *env)
 #ifdef TARGET_CRIS
 void cpu_loop(CPUCRISState *env)
 {
+    CPUState *cs = CPU(cris_env_get_cpu(env));
     int trapnr, ret;
     target_siginfo_t info;
     
@@ -2595,7 +2599,7 @@ void cpu_loop(CPUCRISState *env)
             break;
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit (1);
         }
         process_pending_signals (env);
@@ -2606,6 +2610,7 @@ void cpu_loop(CPUCRISState *env)
 #ifdef TARGET_MICROBLAZE
 void cpu_loop(CPUMBState *env)
 {
+    CPUState *cs = CPU(mb_env_get_cpu(env));
     int trapnr, ret;
     target_siginfo_t info;
     
@@ -2673,7 +2678,7 @@ void cpu_loop(CPUMBState *env)
                 default:
                     printf ("Unhandled hw-exception: 0x%x\n",
                             env->sregs[SR_ESR] & ESR_EC_MASK);
-                    cpu_dump_state(env, stderr, fprintf, 0);
+                    cpu_dump_state(cs, stderr, fprintf, 0);
                     exit (1);
                     break;
             }
@@ -2694,7 +2699,7 @@ void cpu_loop(CPUMBState *env)
             break;
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit (1);
         }
         process_pending_signals (env);
@@ -2706,6 +2711,7 @@ void cpu_loop(CPUMBState *env)
 
 void cpu_loop(CPUM68KState *env)
 {
+    CPUState *cs = CPU(m68k_env_get_cpu(env));
     int trapnr;
     unsigned int n;
     target_siginfo_t info;
@@ -2787,7 +2793,7 @@ void cpu_loop(CPUM68KState *env)
         default:
             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
                     trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             abort();
         }
         process_pending_signals(env);
@@ -2843,6 +2849,7 @@ static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
 
 void cpu_loop(CPUAlphaState *env)
 {
+    CPUState *cs = CPU(alpha_env_get_cpu(env));
     int trapnr;
     target_siginfo_t info;
     abi_long sysret;
@@ -3017,7 +3024,7 @@ void cpu_loop(CPUAlphaState *env)
             break;
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit (1);
         }
         process_pending_signals (env);
@@ -3028,6 +3035,7 @@ void cpu_loop(CPUAlphaState *env)
 #ifdef TARGET_S390X
 void cpu_loop(CPUS390XState *env)
 {
+    CPUState *cs = CPU(s390_env_get_cpu(env));
     int trapnr, n, sig;
     target_siginfo_t info;
     target_ulong addr;
@@ -3118,7 +3126,7 @@ void cpu_loop(CPUS390XState *env)
 
             default:
                 fprintf(stderr, "Unhandled program exception: %#x\n", n);
-                cpu_dump_state(env, stderr, fprintf, 0);
+                cpu_dump_state(cs, stderr, fprintf, 0);
                 exit(1);
             }
             break;
@@ -3135,7 +3143,7 @@ void cpu_loop(CPUS390XState *env)
 
         default:
             fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit(1);
         }
         process_pending_signals (env);
diff --git a/monitor.c b/monitor.c
index 19c297d..9be515c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -921,9 +921,11 @@ int monitor_get_cpu_index(void)
 
 static void do_info_registers(Monitor *mon, const QDict *qdict)
 {
+    CPUState *cpu;
     CPUArchState *env;
     env = mon_get_cpu();
-    cpu_dump_state(env, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
+    cpu = ENV_GET_CPU(env);
+    cpu_dump_state(cpu, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
 }
 
 static void do_info_jit(Monitor *mon, const QDict *qdict)
@@ -948,16 +950,15 @@ static void do_info_history(Monitor *mon, const QDict *qdict)
     }
 }
 
-#if defined(TARGET_PPC)
-/* XXX: not implemented in other targets */
 static void do_info_cpu_stats(Monitor *mon, const QDict *qdict)
 {
+    CPUState *cpu;
     CPUArchState *env;
 
     env = mon_get_cpu();
-    cpu_dump_statistics(env, (FILE *)mon, &monitor_fprintf, 0);
+    cpu = ENV_GET_CPU(env);
+    cpu_dump_statistics(cpu, (FILE *)mon, &monitor_fprintf, 0);
 }
-#endif
 
 static void do_trace_print_events(Monitor *mon, const QDict *qdict)
 {
@@ -2678,7 +2679,6 @@ static mon_cmd_t info_cmds[] = {
         .help       = "show the current VM UUID",
         .mhandler.cmd = hmp_info_uuid,
     },
-#if defined(TARGET_PPC)
     {
         .name       = "cpustats",
         .args_type  = "",
@@ -2686,7 +2686,6 @@ static mon_cmd_t info_cmds[] = {
         .help       = "show CPU statistics",
         .mhandler.cmd = do_info_cpu_stats,
     },
-#endif
 #if defined(CONFIG_SLIRP)
     {
         .name       = "usernet",
diff --git a/qom/cpu.c b/qom/cpu.c
index 8a122b0..4da6332 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -18,8 +18,8 @@
  * <http://www.gnu.org/licenses/gpl-2.0.html>
  */
 
-#include "qom/cpu.h"
 #include "qemu-common.h"
+#include "qom/cpu.h"
 #include "sysemu/kvm.h"
 #include "qemu/notify.h"
 #include "sysemu/sysemu.h"
@@ -156,6 +156,26 @@ static int cpu_common_write_elf64_note(WriteCoreDumpFunction f,
 }
 
 
+void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                    int flags)
+{
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    if (cc->dump_state) {
+        cc->dump_state(cpu, f, cpu_fprintf, flags);
+    }
+}
+
+void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
+{
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    if (cc->dump_statistics) {
+        cc->dump_statistics(cpu, f, cpu_fprintf, flags);
+    }
+}
+
 void cpu_reset(CPUState *cpu)
 {
     CPUClass *klass = CPU_GET_CLASS(cpu);
diff --git a/stubs/cpus.c b/stubs/cpus.c
index 37000dd..f0d56c5 100644
--- a/stubs/cpus.c
+++ b/stubs/cpus.c
@@ -1,3 +1,4 @@
+#include "qemu-common.h"
 #include "qom/cpu.h"
 
 void cpu_resume(CPUState *cpu)
diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h
index 32ee286..95ae747 100644
--- a/target-alpha/cpu-qom.h
+++ b/target-alpha/cpu-qom.h
@@ -75,5 +75,7 @@ static inline AlphaCPU *alpha_env_get_cpu(CPUAlphaState *env)
 #define ENV_OFFSET offsetof(AlphaCPU, env)
 
 void alpha_cpu_do_interrupt(CPUState *cpu);
+void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                          int flags);
 
 #endif
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index cad1716..395551a 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -264,6 +264,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = alpha_cpu_class_by_name;
     cc->do_interrupt = alpha_cpu_do_interrupt;
+    cc->dump_state = alpha_cpu_dump_state;
 }
 
 static const TypeInfo alpha_cpu_type_info = {
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 5741ec2..ff57dd6 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -464,8 +464,8 @@ void alpha_cpu_do_interrupt(CPUState *cs)
 #endif /* !USER_ONLY */
 }
 
-void cpu_dump_state (CPUAlphaState *env, FILE *f, fprintf_function cpu_fprintf,
-                     int flags)
+void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                          int flags)
 {
     static const char *linux_reg_names[] = {
         "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ",
@@ -473,6 +473,8 @@ void cpu_dump_state (CPUAlphaState *env, FILE *f, fprintf_function cpu_fprintf,
         "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ",
         "t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero",
     };
+    AlphaCPU *cpu = ALPHA_CPU(cs);
+    CPUAlphaState *env = &cpu->env;
     int i;
 
     cpu_fprintf(f, "     PC  " TARGET_FMT_lx "      PS  %02x\n",
diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
index f0637a4..5f01bca 100644
--- a/target-arm/arm-semi.c
+++ b/target-arm/arm-semi.c
@@ -178,6 +178,7 @@ static void arm_semi_flen_cb(CPUARMState *env, target_ulong ret, target_ulong er
 #define SET_ARG(n, val) put_user_ual(val, args + (n) * 4)
 uint32_t do_arm_semihosting(CPUARMState *env)
 {
+    ARMCPU *cpu = arm_env_get_cpu(env);
     target_ulong args;
     target_ulong arg0, arg1, arg2, arg3;
     char * s;
@@ -549,7 +550,7 @@ uint32_t do_arm_semihosting(CPUARMState *env)
         exit(0);
     default:
         fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);
-        cpu_dump_state(env, stderr, fprintf, 0);
+        cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
         abort();
     }
 }
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 12fcefe..9d70ec4 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -120,4 +120,7 @@ void register_cp_regs_for_features(ARMCPU *cpu);
 void arm_cpu_do_interrupt(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt(CPUState *cpu);
 
+void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags);
+
 #endif
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 496a59f..a40290c 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -814,6 +814,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = arm_cpu_class_by_name;
     cc->do_interrupt = arm_cpu_do_interrupt;
+    cc->dump_state = arm_cpu_dump_state;
     cpu_class_set_vmsd(cc, &vmstate_arm_cpu);
 }
 
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 2a18ffe..af2aef2 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -10085,9 +10085,11 @@ static const char *cpu_mode_names[16] = {
   "???", "???", "???", "und", "???", "???", "???", "sys"
 };
 
-void cpu_dump_state(CPUARMState *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags)
+void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags)
 {
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
     int i;
     uint32_t psr;
 
diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h
index 03829bd..e08bdb1 100644
--- a/target-cris/cpu-qom.h
+++ b/target-cris/cpu-qom.h
@@ -76,4 +76,7 @@ static inline CRISCPU *cris_env_get_cpu(CPUCRISState *env)
 void cris_cpu_do_interrupt(CPUState *cpu);
 void crisv10_cpu_do_interrupt(CPUState *cpu);
 
+void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
+
 #endif
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 67181e5..82271f7 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -252,6 +252,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = cris_cpu_class_by_name;
     cc->do_interrupt = cris_cpu_do_interrupt;
+    cc->dump_state = cris_cpu_dump_state;
 }
 
 static const TypeInfo cris_cpu_type_info = {
diff --git a/target-cris/helper.c b/target-cris/helper.c
index 466cc2f..aba7537 100644
--- a/target-cris/helper.c
+++ b/target-cris/helper.c
@@ -53,9 +53,11 @@ void crisv10_cpu_do_interrupt(CPUState *cs)
 int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw,
                               int mmu_idx)
 {
+    CRISCPU *cpu = cris_env_get_cpu(env);
+
     env->exception_index = 0xaa;
     env->pregs[PR_EDA] = address;
-    cpu_dump_state(env, stderr, fprintf, 0);
+    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
     return 1;
 }
 
diff --git a/target-cris/translate.c b/target-cris/translate.c
index dbcb811..09d0d2b 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3427,9 +3427,11 @@ void gen_intermediate_code_pc (CPUCRISState *env, struct TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state (CPUCRISState *env, FILE *f, fprintf_function cpu_fprintf,
-                     int flags)
+void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
 {
+    CRISCPU *cpu = CRIS_CPU(cs);
+    CPUCRISState *env = &cpu->env;
     int i;
     uint32_t srs;
 
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index e0ac072..b7c70d6 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -101,4 +101,7 @@ int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
 void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
                                 Error **errp);
 
+void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags);
+
 #endif
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index a7154af..48c062f 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2526,6 +2526,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->reset = x86_cpu_reset;
 
     cc->do_interrupt = x86_cpu_do_interrupt;
+    cc->dump_state = x86_cpu_dump_state;
     cc->get_arch_id = x86_cpu_get_arch_id;
     cc->get_paging_enabled = x86_cpu_get_paging_enabled;
 #ifndef CONFIG_USER_ONLY
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 803945d..5e5abe3 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -179,10 +179,11 @@ done:
 #define DUMP_CODE_BYTES_TOTAL    50
 #define DUMP_CODE_BYTES_BACKWARD 20
 
-void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags)
+void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags)
 {
-    CPUState *cs = CPU(x86_env_get_cpu(env));
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
     int eflags, i, nb;
     char cc_op_name[32];
     static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h
index 9571860..5ef884b 100644
--- a/target-lm32/cpu-qom.h
+++ b/target-lm32/cpu-qom.h
@@ -76,5 +76,7 @@ extern const struct VMStateDescription vmstate_lm32_cpu;
 #endif
 
 void lm32_cpu_do_interrupt(CPUState *cpu);
+void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
 
 #endif
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 23c05dd..2366152 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -85,6 +85,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
     cc->reset = lm32_cpu_reset;
 
     cc->do_interrupt = lm32_cpu_do_interrupt;
+    cc->dump_state = lm32_cpu_dump_state;
     cpu_class_set_vmsd(cc, &vmstate_lm32_cpu);
 }
 
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index af9ce8c..227a801 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1141,9 +1141,11 @@ void gen_intermediate_code_pc(CPULM32State *env, struct TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state(CPULM32State *env, FILE *f, fprintf_function cpu_fprintf,
-                     int flags)
+void lm32_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
 {
+    LM32CPU *cpu = LM32_CPU(cs);
+    CPULM32State *env = &cpu->env;
     int i;
 
     if (!env || !f) {
diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h
index 846aa74..2436c13 100644
--- a/target-m68k/cpu-qom.h
+++ b/target-m68k/cpu-qom.h
@@ -71,5 +71,7 @@ static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env)
 #define ENV_OFFSET offsetof(M68kCPU, env)
 
 void m68k_cpu_do_interrupt(CPUState *cpu);
+void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
 
 #endif
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 3c65b4e..d501027 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -187,6 +187,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = m68k_cpu_class_by_name;
     cc->do_interrupt = m68k_cpu_do_interrupt;
+    cc->dump_state = m68k_cpu_dump_state;
     dc->vmsd = &vmstate_m68k_cpu;
 }
 
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 32b8132..3752094 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -3104,9 +3104,11 @@ void gen_intermediate_code_pc(CPUM68KState *env, TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state(CPUM68KState *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags)
+void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
 {
+    M68kCPU *cpu = M68K_CPU(cs);
+    CPUM68KState *env = &cpu->env;
     int i;
     uint16_t sr;
     CPU_DoubleU u;
diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h
index ce92a4e..3e9c206 100644
--- a/target-microblaze/cpu-qom.h
+++ b/target-microblaze/cpu-qom.h
@@ -72,5 +72,7 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
 #define ENV_OFFSET offsetof(MicroBlazeCPU, env)
 
 void mb_cpu_do_interrupt(CPUState *cs);
+void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                       int flags);
 
 #endif
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index 404f82c..e8104d1 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -138,6 +138,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->reset = mb_cpu_reset;
 
     cc->do_interrupt = mb_cpu_do_interrupt;
+    cc->dump_state = mb_cpu_dump_state;
     dc->vmsd = &vmstate_mb_cpu;
 
     dc->props = mb_properties;
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index 0dd669d..01d4bbf 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -39,8 +39,10 @@ void mb_cpu_do_interrupt(CPUState *cs)
 int cpu_mb_handle_mmu_fault(CPUMBState * env, target_ulong address, int rw,
                             int mmu_idx)
 {
+    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
+
     env->exception_index = 0xaa;
-    cpu_dump_state(env, stderr, fprintf, 0);
+    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
     return 1;
 }
 
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 06d2346..54f439f 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1949,9 +1949,11 @@ void gen_intermediate_code_pc (CPUMBState *env, struct TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state (CPUMBState *env, FILE *f, fprintf_function cpu_fprintf,
-                     int flags)
+void mb_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                       int flags)
 {
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+    CPUMBState *env = &cpu->env;
     int i;
 
     if (!env || !f)
diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h
index 32e3cad..a7ff9e6 100644
--- a/target-mips/cpu-qom.h
+++ b/target-mips/cpu-qom.h
@@ -75,5 +75,7 @@ static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
 #define ENV_OFFSET offsetof(MIPSCPU, env)
 
 void mips_cpu_do_interrupt(CPUState *cpu);
+void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
 
 #endif
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 5315f7b..b685d39 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -80,6 +80,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->reset = mips_cpu_reset;
 
     cc->do_interrupt = mips_cpu_do_interrupt;
+    cc->dump_state = mips_cpu_dump_state;
 }
 
 static const TypeInfo mips_cpu_type_info = {
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 0a53203..160c0c0 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15780,9 +15780,11 @@ cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
 }
 #endif
 
-void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
-                     int flags)
+void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
 {
+    MIPSCPU *cpu = MIPS_CPU(cs);
+    CPUMIPSState *env = &cpu->env;
     int i;
 
     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
index f2b0791..3c3932c 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -97,8 +97,9 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = moxie_cpu_class_by_name;
 
-    cpu_class_set_vmsd(cc, &vmstate_moxie_cpu);
     cc->do_interrupt = moxie_cpu_do_interrupt;
+    cc->dump_state = moxie_cpu_dump_state;
+    cpu_class_set_vmsd(cc, &vmstate_moxie_cpu);
 }
 
 static void moxielite_initfn(Object *obj)
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index a9d9ace..374b24a 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -116,6 +116,8 @@ static inline MoxieCPU *moxie_env_get_cpu(CPUMoxieState *env)
 MoxieCPU *cpu_moxie_init(const char *cpu_model);
 int cpu_moxie_exec(CPUMoxieState *s);
 void moxie_cpu_do_interrupt(CPUState *cs);
+void moxie_cpu_dump_state(CPUState *cpu, FILE *f,
+                          fprintf_function cpu_fprintf, int flags);
 void moxie_translate_init(void);
 int cpu_moxie_signal_handler(int host_signum, void *pinfo,
                              void *puc);
diff --git a/target-moxie/helper.c b/target-moxie/helper.c
index 5cfe889..ea0788f 100644
--- a/target-moxie/helper.c
+++ b/target-moxie/helper.c
@@ -110,9 +110,11 @@ void moxie_cpu_do_interrupt(CPUState *env)
 int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
                                int rw, int mmu_idx)
 {
+    MoxieCPU *cpu = moxie_env_get_cpu(env);
+
     env->exception_index = 0xaa;
     env->debug1 = address;
-    cpu_dump_state(env, stderr, fprintf, 0);
+    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
     return 1;
 }
 
diff --git a/target-moxie/translate.c b/target-moxie/translate.c
index cc02bd3..b0ae38a 100644
--- a/target-moxie/translate.c
+++ b/target-moxie/translate.c
@@ -74,9 +74,11 @@ static int extract_branch_offset(int opcode)
   return (((signed short)((opcode & ((1 << 10) - 1)) << 6)) >> 6) << 1;
 }
 
-void cpu_dump_state(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags)
+void moxie_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                          int flags)
 {
+    MoxieCPU *cpu = MOXIE_CPU(cs);
+    CPUMoxieState *env = &cpu->env;
     int i;
     cpu_fprintf(f, "pc=0x%08x\n", env->pc);
     cpu_fprintf(f, "$fp=0x%08x $sp=0x%08x $r0=0x%08x $r1=0x%08x\n",
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index ffe14f3..82bee2a 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -149,6 +149,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = openrisc_cpu_class_by_name;
     cc->do_interrupt = openrisc_cpu_do_interrupt;
+    cc->dump_state = openrisc_cpu_dump_state;
 }
 
 static void cpu_register(const OpenRISCCPUInfo *info)
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index b9c55ba..eb4d282 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -347,6 +347,8 @@ OpenRISCCPU *cpu_openrisc_init(const char *cpu_model);
 void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf);
 int cpu_openrisc_exec(CPUOpenRISCState *s);
 void openrisc_cpu_do_interrupt(CPUState *cpu);
+void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
+                             fprintf_function cpu_fprintf, int flags);
 void openrisc_translate_init(void);
 int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
                                   target_ulong address,
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 0eafd02..c59fd02 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1814,15 +1814,17 @@ void gen_intermediate_code_pc(CPUOpenRISCState *env,
     gen_intermediate_code_internal(openrisc_env_get_cpu(env), tb, 1);
 }
 
-void cpu_dump_state(CPUOpenRISCState *env, FILE *f,
-                    fprintf_function cpu_fprintf,
-                    int flags)
+void openrisc_cpu_dump_state(CPUState *cs, FILE *f,
+                             fprintf_function cpu_fprintf,
+                             int flags)
 {
+    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
+    CPUOpenRISCState *env = &cpu->env;
     int i;
-    uint32_t *regs = env->gpr;
+
     cpu_fprintf(f, "PC=%08x\n", env->pc);
     for (i = 0; i < 32; ++i) {
-        cpu_fprintf(f, "R%02d=%08x%c", i, regs[i],
+        cpu_fprintf(f, "R%02d=%08x%c", i, env->gpr[i],
                     (i % 4) == 3 ? '\n' : ' ');
     }
 }
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index eb03a00..84ba105 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -101,5 +101,9 @@ static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
 PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
 
 void ppc_cpu_do_interrupt(CPUState *cpu);
+void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                        int flags);
+void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
+                             fprintf_function cpu_fprintf, int flags);
 
 #endif
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 076cdac..3643863 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9526,15 +9526,17 @@ GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
 
 /*****************************************************************************/
 /* Misc PowerPC helpers */
-void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
-                     int flags)
+void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags)
 {
 #define RGPL  4
 #define RFPL  4
 
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
     int i;
 
-    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
+    cpu_synchronize_state(cs);
 
     cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
                 TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
@@ -9675,14 +9677,15 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
 #undef RFPL
 }
 
-void cpu_dump_statistics (CPUPPCState *env, FILE*f, fprintf_function cpu_fprintf,
-                          int flags)
+void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
+                             fprintf_function cpu_fprintf, int flags)
 {
 #if defined(DO_PPC_STATISTICS)
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
     opc_handler_t **t1, **t2, **t3, *handler;
     int op1, op2, op3;
 
-    t1 = env->opcodes;
+    t1 = cpu->env.opcodes;
     for (op1 = 0; op1 < 64; op1++) {
         handler = t1[op1];
         if (is_indirect_opcode(handler)) {
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 021a31e..0edb336 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8309,6 +8309,8 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = ppc_cpu_class_by_name;
     cc->do_interrupt = ppc_cpu_do_interrupt;
+    cc->dump_state = ppc_cpu_dump_state;
+    cc->dump_statistics = ppc_cpu_dump_statistics;
 }
 
 static const TypeInfo ppc_cpu_type_info = {
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index 34d45c2..ec32d21 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -72,5 +72,7 @@ static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
 #define ENV_OFFSET offsetof(S390CPU, env)
 
 void s390_cpu_do_interrupt(CPUState *cpu);
+void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
 
 #endif
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 23fe51f..8ec2f9b 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -170,6 +170,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->reset = s390_cpu_reset;
 
     cc->do_interrupt = s390_cpu_do_interrupt;
+    cc->dump_state = s390_cpu_dump_state;
     dc->vmsd = &vmstate_s390_cpu;
 }
 
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index f97e431..cd9880e 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -86,9 +86,11 @@ static uint64_t pc_to_link_info(DisasContext *s, uint64_t pc)
     return pc;
 }
 
-void cpu_dump_state(CPUS390XState *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags)
+void s390_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
 {
+    S390CPU *cpu = S390_CPU(cs);
+    CPUS390XState *env = &cpu->env;
     int i;
 
     if (env->cc_op > 3) {
diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h
index f8c80d3..01d1637 100644
--- a/target-sh4/cpu-qom.h
+++ b/target-sh4/cpu-qom.h
@@ -84,5 +84,7 @@ static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env)
 #define ENV_OFFSET offsetof(SuperHCPU, env)
 
 void superh_cpu_do_interrupt(CPUState *cpu);
+void superh_cpu_dump_state(CPUState *cpu, FILE *f,
+                           fprintf_function cpu_fprintf, int flags);
 
 #endif
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index 898aecd..a7d5213 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -274,6 +274,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = superh_cpu_class_by_name;
     cc->do_interrupt = superh_cpu_do_interrupt;
+    cc->dump_state = superh_cpu_dump_state;
     dc->vmsd = &vmstate_sh_cpu;
 }
 
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 14fdb8f..292c9e9 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -150,10 +150,11 @@ void sh4_translate_init(void)
     done_init = 1;
 }
 
-void cpu_dump_state(CPUSH4State * env, FILE * f,
-		    int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
-		    int flags)
+void superh_cpu_dump_state(CPUState *cs, FILE *f,
+                           fprintf_function cpu_fprintf, int flags)
 {
+    SuperHCPU *cpu = SUPERH_CPU(cs);
+    CPUSH4State *env = &cpu->env;
     int i;
     cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
 		env->pc, env->sr, env->pr, env->fpscr);
diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h
index d4fe89e..97c1ec7 100644
--- a/target-sparc/cpu-qom.h
+++ b/target-sparc/cpu-qom.h
@@ -76,5 +76,7 @@ static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
 #define ENV_OFFSET offsetof(SPARCCPU, env)
 
 void sparc_cpu_do_interrupt(CPUState *cpu);
+void sparc_cpu_dump_state(CPUState *cpu, FILE *f,
+                          fprintf_function cpu_fprintf, int flags);
 
 #endif
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 13bb7bb..72700cd 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -660,9 +660,11 @@ static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
 #define REGS_PER_LINE 8
 #endif
 
-void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags)
+void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                          int flags)
 {
+    SPARCCPU *cpu = SPARC_CPU(cs);
+    CPUSPARCState *env = &cpu->env;
     int i, x;
 
     cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc,
@@ -771,6 +773,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->reset = sparc_cpu_reset;
 
     cc->do_interrupt = sparc_cpu_do_interrupt;
+    cc->dump_state = sparc_cpu_dump_state;
 }
 
 static const TypeInfo sparc_cpu_type_info = {
diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h
index ba4dee4..7eec448 100644
--- a/target-unicore32/cpu-qom.h
+++ b/target-unicore32/cpu-qom.h
@@ -61,5 +61,7 @@ static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env)
 #define ENV_OFFSET offsetof(UniCore32CPU, env)
 
 void uc32_cpu_do_interrupt(CPUState *cpu);
+void uc32_cpu_dump_state(CPUState *cpu, FILE *f,
+                         fprintf_function cpu_fprintf, int flags);
 
 #endif
diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
index 66a1a74..1a97e6b 100644
--- a/target-unicore32/cpu.c
+++ b/target-unicore32/cpu.c
@@ -133,6 +133,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = uc32_cpu_class_by_name;
     cc->do_interrupt = uc32_cpu_do_interrupt;
+    cc->dump_state = uc32_cpu_dump_state;
     dc->vmsd = &vmstate_uc32_cpu;
 }
 
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 3dc7856..e1fe4e6 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -2113,9 +2113,11 @@ static void cpu_dump_state_ucf64(CPUUniCore32State *env, FILE *f,
 #define cpu_dump_state_ucf64(env, file, pr, flags)      do { } while (0)
 #endif
 
-void cpu_dump_state(CPUUniCore32State *env, FILE *f,
-        fprintf_function cpu_fprintf, int flags)
+void uc32_cpu_dump_state(CPUState *cs, FILE *f,
+                         fprintf_function cpu_fprintf, int flags)
 {
+    UniCore32CPU *cpu = UNICORE32_CPU(cs);
+    CPUUniCore32State *env = &cpu->env;
     int i;
     uint32_t psr;
 
diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h
index af0ce28..30506cf 100644
--- a/target-xtensa/cpu-qom.h
+++ b/target-xtensa/cpu-qom.h
@@ -81,5 +81,7 @@ static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
 #define ENV_OFFSET offsetof(XtensaCPU, env)
 
 void xtensa_cpu_do_interrupt(CPUState *cpu);
+void xtensa_cpu_dump_state(CPUState *cpu, FILE *f,
+                           fprintf_function cpu_fprintf, int flags);
 
 #endif
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index 6e93dd8..b5df321 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -102,6 +102,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
     cc->reset = xtensa_cpu_reset;
 
     cc->do_interrupt = xtensa_cpu_do_interrupt;
+    cc->dump_state = xtensa_cpu_dump_state;
     dc->vmsd = &vmstate_xtensa_cpu;
 }
 
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 1037101..4c41de0 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -368,7 +368,9 @@ void HELPER(wsr_lend)(CPUXtensaState *env, uint32_t v)
 
 void HELPER(dump_state)(CPUXtensaState *env)
 {
-    cpu_dump_state(env, stderr, fprintf, 0);
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+
+    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
 }
 
 void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel)
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 06d68db..dcb90a5 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -3014,9 +3014,11 @@ void gen_intermediate_code_pc(CPUXtensaState *env, TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf,
-        int flags)
+void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
+                           fprintf_function cpu_fprintf, int flags)
 {
+    XtensaCPU *cpu = XTENSA_CPU(cs);
+    CPUXtensaState *env = &cpu->env;
     int i, j;
 
     cpu_fprintf(f, "PC=%08x\n\n", env->pc);
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 09/29] cpu: Turn cpu_dump_{state, statistics}() into CPUState hooks
@ 2013-06-16 15:57   ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Marcelo Tosatti, open list:Overall, Gleb Natapov,
	Anthony Green, Riku Voipio, Alexander Graf, Luiz Capitulino,
	Blue Swirl, Max Filippov, Michael Walle, open list:PowerPC,
	Paul Brook, Edgar E. Iglesias, Guan Xuetao, Andreas Färber,
	Aurelien Jarno, Richard Henderson

Make cpustats monitor command available unconditionally.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 bsd-user/main.c               |  3 ++-
 cpus.c                        |  2 +-
 exec.c                        |  3 ++-
 include/exec/cpu-all.h        | 10 ----------
 include/qemu/log.h            |  2 +-
 include/qom/cpu.h             | 42 ++++++++++++++++++++++++++++++++++++++++++
 kvm-all.c                     |  4 ++--
 linux-user/main.c             | 38 +++++++++++++++++++++++---------------
 monitor.c                     | 13 ++++++-------
 qom/cpu.c                     | 22 +++++++++++++++++++++-
 stubs/cpus.c                  |  1 +
 target-alpha/cpu-qom.h        |  2 ++
 target-alpha/cpu.c            |  1 +
 target-alpha/helper.c         |  6 ++++--
 target-arm/arm-semi.c         |  3 ++-
 target-arm/cpu-qom.h          |  3 +++
 target-arm/cpu.c              |  1 +
 target-arm/translate.c        |  6 ++++--
 target-cris/cpu-qom.h         |  3 +++
 target-cris/cpu.c             |  1 +
 target-cris/helper.c          |  4 +++-
 target-cris/translate.c       |  6 ++++--
 target-i386/cpu-qom.h         |  3 +++
 target-i386/cpu.c             |  1 +
 target-i386/helper.c          |  7 ++++---
 target-lm32/cpu-qom.h         |  2 ++
 target-lm32/cpu.c             |  1 +
 target-lm32/translate.c       |  6 ++++--
 target-m68k/cpu-qom.h         |  2 ++
 target-m68k/cpu.c             |  1 +
 target-m68k/translate.c       |  6 ++++--
 target-microblaze/cpu-qom.h   |  2 ++
 target-microblaze/cpu.c       |  1 +
 target-microblaze/helper.c    |  4 +++-
 target-microblaze/translate.c |  6 ++++--
 target-mips/cpu-qom.h         |  2 ++
 target-mips/cpu.c             |  1 +
 target-mips/translate.c       |  6 ++++--
 target-moxie/cpu.c            |  3 ++-
 target-moxie/cpu.h            |  2 ++
 target-moxie/helper.c         |  4 +++-
 target-moxie/translate.c      |  6 ++++--
 target-openrisc/cpu.c         |  1 +
 target-openrisc/cpu.h         |  2 ++
 target-openrisc/translate.c   | 12 +++++++-----
 target-ppc/cpu-qom.h          |  4 ++++
 target-ppc/translate.c        | 15 +++++++++------
 target-ppc/translate_init.c   |  2 ++
 target-s390x/cpu-qom.h        |  2 ++
 target-s390x/cpu.c            |  1 +
 target-s390x/translate.c      |  6 ++++--
 target-sh4/cpu-qom.h          |  2 ++
 target-sh4/cpu.c              |  1 +
 target-sh4/translate.c        |  7 ++++---
 target-sparc/cpu-qom.h        |  2 ++
 target-sparc/cpu.c            |  7 +++++--
 target-unicore32/cpu-qom.h    |  2 ++
 target-unicore32/cpu.c        |  1 +
 target-unicore32/translate.c  |  6 ++++--
 target-xtensa/cpu-qom.h       |  2 ++
 target-xtensa/cpu.c           |  1 +
 target-xtensa/op_helper.c     |  4 +++-
 target-xtensa/translate.c     |  6 ++++--
 63 files changed, 242 insertions(+), 86 deletions(-)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 0da3ab9..b13803e 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -511,6 +511,7 @@ static void flush_windows(CPUSPARCState *env)
 
 void cpu_loop(CPUSPARCState *env)
 {
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
     int trapnr, ret, syscall_nr;
     //target_siginfo_t info;
 
@@ -659,7 +660,7 @@ void cpu_loop(CPUSPARCState *env)
         badtrap:
 #endif
             printf ("Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit (1);
         }
         process_pending_signals (env);
diff --git a/cpus.c b/cpus.c
index a5b0e46..bbaf13c 100644
--- a/cpus.c
+++ b/cpus.c
@@ -397,7 +397,7 @@ void hw_error(const char *fmt, ...)
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
         cpu = ENV_GET_CPU(env);
         fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
-        cpu_dump_state(env, stderr, fprintf, CPU_DUMP_FPU);
+        cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU);
     }
     va_end(ap);
     abort();
diff --git a/exec.c b/exec.c
index c0fa5a3..2b99bb9 100644
--- a/exec.c
+++ b/exec.c
@@ -517,6 +517,7 @@ void cpu_single_step(CPUArchState *env, int enabled)
 
 void cpu_abort(CPUArchState *env, const char *fmt, ...)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     va_list ap;
     va_list ap2;
 
@@ -525,7 +526,7 @@ void cpu_abort(CPUArchState *env, const char *fmt, ...)
     fprintf(stderr, "qemu: fatal: ");
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
-    cpu_dump_state(env, stderr, fprintf, CPU_DUMP_FPU | CPU_DUMP_CCOP);
+    cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU | CPU_DUMP_CCOP);
     if (qemu_log_enabled()) {
         qemu_log("qemu: fatal: ");
         qemu_log_vprintf(fmt, ap2);
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index e1cc62e..35bdf85 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -355,16 +355,6 @@ int page_check_range(target_ulong start, target_ulong len, int flags);
 
 CPUArchState *cpu_copy(CPUArchState *env);
 
-#define CPU_DUMP_CODE 0x00010000
-#define CPU_DUMP_FPU 0x00020000 /* dump FPU register state, not just integer */
-/* dump info about TCG QEMU's condition code optimization state */
-#define CPU_DUMP_CCOP 0x00040000
-
-void cpu_dump_state(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags);
-void cpu_dump_statistics(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
-                         int flags);
-
 void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 extern CPUArchState *first_cpu;
diff --git a/include/qemu/log.h b/include/qemu/log.h
index fd76f91..a9cf214 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -75,7 +75,7 @@ void GCC_FMT_ATTR(2, 3) qemu_log_mask(int mask, const char *fmt, ...);
 static inline void log_cpu_state(CPUArchState *env1, int flags)
 {
     if (qemu_log_enabled()) {
-        cpu_dump_state(env1, qemu_logfile, fprintf, flags);
+        cpu_dump_state(ENV_GET_CPU(env1), qemu_logfile, fprintf, flags);
     }
 }
 
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index f633686..e25898d 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -48,6 +48,8 @@ typedef struct CPUState CPUState;
  * instantiatable CPU type.
  * @reset: Callback to reset the #CPUState to its initial state.
  * @do_interrupt: Callback for interrupt handling.
+ * @dump_state: Callback for dumping state.
+ * @dump_statistics: Callback for dumping statistics.
  * @get_arch_id: Callback for getting architecture-dependent CPU ID.
  * @get_paging_enabled: Callback for inquiring whether paging is enabled.
  * @get_memory_mapping: Callback for obtaining the memory mappings.
@@ -64,6 +66,10 @@ typedef struct CPUClass {
 
     void (*reset)(CPUState *cpu);
     void (*do_interrupt)(CPUState *cpu);
+    void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                       int flags);
+    void (*dump_statistics)(CPUState *cpu, FILE *f,
+                            fprintf_function cpu_fprintf, int flags);
     int64_t (*get_arch_id)(CPUState *cpu);
     bool (*get_paging_enabled)(const CPUState *cpu);
     void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
@@ -201,6 +207,42 @@ int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
                              void *opaque);
 
 /**
+ * CPUDumpFlags:
+ * @CPU_DUMP_CODE:
+ * @CPU_DUMP_FPU: dump FPU register state, not just integer
+ * @CPU_DUMP_CCOP: dump info about TCG QEMU's condition code optimization state
+ */
+enum CPUDumpFlags {
+    CPU_DUMP_CODE = 0x00010000,
+    CPU_DUMP_FPU  = 0x00020000,
+    CPU_DUMP_CCOP = 0x00040000,
+};
+
+/**
+ * cpu_dump_state:
+ * @cpu: The CPU whose state is to be dumped.
+ * @f: File to dump to.
+ * @cpu_fprintf: Function to dump with.
+ * @flags: Flags what to dump.
+ *
+ * Dumps CPU state.
+ */
+void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                    int flags);
+
+/**
+ * cpu_dump_statistics:
+ * @cpu: The CPU whose state is to be dumped.
+ * @f: File to dump to.
+ * @cpu_fprintf: Function to dump with.
+ * @flags: Flags what to dump.
+ *
+ * Dumps CPU statistics.
+ */
+void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
+
+/**
  * cpu_reset:
  * @cpu: The CPU whose state is to be reset.
  */
diff --git a/kvm-all.c b/kvm-all.c
index 88297b1..1cd4573 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1539,7 +1539,7 @@ static int kvm_handle_internal_error(CPUArchState *env, struct kvm_run *run)
     if (run->internal.suberror == KVM_INTERNAL_ERROR_EMULATION) {
         fprintf(stderr, "emulation failure\n");
         if (!kvm_arch_stop_on_emulation_error(cpu)) {
-            cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
+            cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE);
             return EXCP_INTERRUPT;
         }
     }
@@ -1695,7 +1695,7 @@ int kvm_cpu_exec(CPUArchState *env)
     } while (ret == 0);
 
     if (ret < 0) {
-        cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
+        cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE);
         vm_stop(RUN_STATE_INTERNAL_ERROR);
     }
 
diff --git a/linux-user/main.c b/linux-user/main.c
index 30e7953..95e17cf 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -901,7 +901,7 @@ void cpu_loop(CPUARMState *env)
         error:
             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
                     trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             abort();
         }
         process_pending_signals(env);
@@ -985,7 +985,7 @@ void cpu_loop(CPUUniCore32State *env)
 
 error:
     fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
-    cpu_dump_state(env, stderr, fprintf, 0);
+    cpu_dump_state(cs, stderr, fprintf, 0);
     abort();
 }
 #endif
@@ -1115,6 +1115,7 @@ static void flush_windows(CPUSPARCState *env)
 
 void cpu_loop (CPUSPARCState *env)
 {
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
     int trapnr;
     abi_long ret;
     target_siginfo_t info;
@@ -1246,7 +1247,7 @@ void cpu_loop (CPUSPARCState *env)
             break;
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit (1);
         }
         process_pending_signals (env);
@@ -1304,7 +1305,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
 #define EXCP_DUMP(env, fmt, ...)                                        \
 do {                                                                    \
     fprintf(stderr, fmt , ## __VA_ARGS__);                              \
-    cpu_dump_state(env, stderr, fprintf, 0);                            \
+    cpu_dump_state(ENV_GET_CPU(env), stderr, fprintf, 0);               \
     qemu_log(fmt, ## __VA_ARGS__);                                      \
     if (qemu_log_enabled()) {                                           \
         log_cpu_state(env, 0);                                          \
@@ -2391,7 +2392,7 @@ done_syscall:
 error:
             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
                     trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             abort();
         }
         process_pending_signals(env);
@@ -2403,6 +2404,7 @@ error:
 
 void cpu_loop(CPUOpenRISCState *env)
 {
+    CPUState *cs = CPU(openrisc_env_get_cpu(env));
     int trapnr, gdbsig;
 
     for (;;) {
@@ -2420,7 +2422,7 @@ void cpu_loop(CPUOpenRISCState *env)
             break;
         case EXCP_DPF:
         case EXCP_IPF:
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             gdbsig = TARGET_SIGSEGV;
             break;
         case EXCP_TICK:
@@ -2469,7 +2471,7 @@ void cpu_loop(CPUOpenRISCState *env)
         default:
             qemu_log("\nqemu: unhandled CPU exception %#x - aborting\n",
                      trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             gdbsig = TARGET_SIGILL;
             break;
         }
@@ -2489,6 +2491,7 @@ void cpu_loop(CPUOpenRISCState *env)
 #ifdef TARGET_SH4
 void cpu_loop(CPUSH4State *env)
 {
+    CPUState *cs = CPU(sh_env_get_cpu(env));
     int trapnr, ret;
     target_siginfo_t info;
 
@@ -2537,7 +2540,7 @@ void cpu_loop(CPUSH4State *env)
 
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit (1);
         }
         process_pending_signals (env);
@@ -2548,6 +2551,7 @@ void cpu_loop(CPUSH4State *env)
 #ifdef TARGET_CRIS
 void cpu_loop(CPUCRISState *env)
 {
+    CPUState *cs = CPU(cris_env_get_cpu(env));
     int trapnr, ret;
     target_siginfo_t info;
     
@@ -2595,7 +2599,7 @@ void cpu_loop(CPUCRISState *env)
             break;
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit (1);
         }
         process_pending_signals (env);
@@ -2606,6 +2610,7 @@ void cpu_loop(CPUCRISState *env)
 #ifdef TARGET_MICROBLAZE
 void cpu_loop(CPUMBState *env)
 {
+    CPUState *cs = CPU(mb_env_get_cpu(env));
     int trapnr, ret;
     target_siginfo_t info;
     
@@ -2673,7 +2678,7 @@ void cpu_loop(CPUMBState *env)
                 default:
                     printf ("Unhandled hw-exception: 0x%x\n",
                             env->sregs[SR_ESR] & ESR_EC_MASK);
-                    cpu_dump_state(env, stderr, fprintf, 0);
+                    cpu_dump_state(cs, stderr, fprintf, 0);
                     exit (1);
                     break;
             }
@@ -2694,7 +2699,7 @@ void cpu_loop(CPUMBState *env)
             break;
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit (1);
         }
         process_pending_signals (env);
@@ -2706,6 +2711,7 @@ void cpu_loop(CPUMBState *env)
 
 void cpu_loop(CPUM68KState *env)
 {
+    CPUState *cs = CPU(m68k_env_get_cpu(env));
     int trapnr;
     unsigned int n;
     target_siginfo_t info;
@@ -2787,7 +2793,7 @@ void cpu_loop(CPUM68KState *env)
         default:
             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
                     trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             abort();
         }
         process_pending_signals(env);
@@ -2843,6 +2849,7 @@ static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
 
 void cpu_loop(CPUAlphaState *env)
 {
+    CPUState *cs = CPU(alpha_env_get_cpu(env));
     int trapnr;
     target_siginfo_t info;
     abi_long sysret;
@@ -3017,7 +3024,7 @@ void cpu_loop(CPUAlphaState *env)
             break;
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit (1);
         }
         process_pending_signals (env);
@@ -3028,6 +3035,7 @@ void cpu_loop(CPUAlphaState *env)
 #ifdef TARGET_S390X
 void cpu_loop(CPUS390XState *env)
 {
+    CPUState *cs = CPU(s390_env_get_cpu(env));
     int trapnr, n, sig;
     target_siginfo_t info;
     target_ulong addr;
@@ -3118,7 +3126,7 @@ void cpu_loop(CPUS390XState *env)
 
             default:
                 fprintf(stderr, "Unhandled program exception: %#x\n", n);
-                cpu_dump_state(env, stderr, fprintf, 0);
+                cpu_dump_state(cs, stderr, fprintf, 0);
                 exit(1);
             }
             break;
@@ -3135,7 +3143,7 @@ void cpu_loop(CPUS390XState *env)
 
         default:
             fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(env, stderr, fprintf, 0);
+            cpu_dump_state(cs, stderr, fprintf, 0);
             exit(1);
         }
         process_pending_signals (env);
diff --git a/monitor.c b/monitor.c
index 19c297d..9be515c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -921,9 +921,11 @@ int monitor_get_cpu_index(void)
 
 static void do_info_registers(Monitor *mon, const QDict *qdict)
 {
+    CPUState *cpu;
     CPUArchState *env;
     env = mon_get_cpu();
-    cpu_dump_state(env, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
+    cpu = ENV_GET_CPU(env);
+    cpu_dump_state(cpu, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
 }
 
 static void do_info_jit(Monitor *mon, const QDict *qdict)
@@ -948,16 +950,15 @@ static void do_info_history(Monitor *mon, const QDict *qdict)
     }
 }
 
-#if defined(TARGET_PPC)
-/* XXX: not implemented in other targets */
 static void do_info_cpu_stats(Monitor *mon, const QDict *qdict)
 {
+    CPUState *cpu;
     CPUArchState *env;
 
     env = mon_get_cpu();
-    cpu_dump_statistics(env, (FILE *)mon, &monitor_fprintf, 0);
+    cpu = ENV_GET_CPU(env);
+    cpu_dump_statistics(cpu, (FILE *)mon, &monitor_fprintf, 0);
 }
-#endif
 
 static void do_trace_print_events(Monitor *mon, const QDict *qdict)
 {
@@ -2678,7 +2679,6 @@ static mon_cmd_t info_cmds[] = {
         .help       = "show the current VM UUID",
         .mhandler.cmd = hmp_info_uuid,
     },
-#if defined(TARGET_PPC)
     {
         .name       = "cpustats",
         .args_type  = "",
@@ -2686,7 +2686,6 @@ static mon_cmd_t info_cmds[] = {
         .help       = "show CPU statistics",
         .mhandler.cmd = do_info_cpu_stats,
     },
-#endif
 #if defined(CONFIG_SLIRP)
     {
         .name       = "usernet",
diff --git a/qom/cpu.c b/qom/cpu.c
index 8a122b0..4da6332 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -18,8 +18,8 @@
  * <http://www.gnu.org/licenses/gpl-2.0.html>
  */
 
-#include "qom/cpu.h"
 #include "qemu-common.h"
+#include "qom/cpu.h"
 #include "sysemu/kvm.h"
 #include "qemu/notify.h"
 #include "sysemu/sysemu.h"
@@ -156,6 +156,26 @@ static int cpu_common_write_elf64_note(WriteCoreDumpFunction f,
 }
 
 
+void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                    int flags)
+{
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    if (cc->dump_state) {
+        cc->dump_state(cpu, f, cpu_fprintf, flags);
+    }
+}
+
+void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
+{
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    if (cc->dump_statistics) {
+        cc->dump_statistics(cpu, f, cpu_fprintf, flags);
+    }
+}
+
 void cpu_reset(CPUState *cpu)
 {
     CPUClass *klass = CPU_GET_CLASS(cpu);
diff --git a/stubs/cpus.c b/stubs/cpus.c
index 37000dd..f0d56c5 100644
--- a/stubs/cpus.c
+++ b/stubs/cpus.c
@@ -1,3 +1,4 @@
+#include "qemu-common.h"
 #include "qom/cpu.h"
 
 void cpu_resume(CPUState *cpu)
diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h
index 32ee286..95ae747 100644
--- a/target-alpha/cpu-qom.h
+++ b/target-alpha/cpu-qom.h
@@ -75,5 +75,7 @@ static inline AlphaCPU *alpha_env_get_cpu(CPUAlphaState *env)
 #define ENV_OFFSET offsetof(AlphaCPU, env)
 
 void alpha_cpu_do_interrupt(CPUState *cpu);
+void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                          int flags);
 
 #endif
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index cad1716..395551a 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -264,6 +264,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = alpha_cpu_class_by_name;
     cc->do_interrupt = alpha_cpu_do_interrupt;
+    cc->dump_state = alpha_cpu_dump_state;
 }
 
 static const TypeInfo alpha_cpu_type_info = {
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 5741ec2..ff57dd6 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -464,8 +464,8 @@ void alpha_cpu_do_interrupt(CPUState *cs)
 #endif /* !USER_ONLY */
 }
 
-void cpu_dump_state (CPUAlphaState *env, FILE *f, fprintf_function cpu_fprintf,
-                     int flags)
+void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                          int flags)
 {
     static const char *linux_reg_names[] = {
         "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ",
@@ -473,6 +473,8 @@ void cpu_dump_state (CPUAlphaState *env, FILE *f, fprintf_function cpu_fprintf,
         "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ",
         "t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero",
     };
+    AlphaCPU *cpu = ALPHA_CPU(cs);
+    CPUAlphaState *env = &cpu->env;
     int i;
 
     cpu_fprintf(f, "     PC  " TARGET_FMT_lx "      PS  %02x\n",
diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
index f0637a4..5f01bca 100644
--- a/target-arm/arm-semi.c
+++ b/target-arm/arm-semi.c
@@ -178,6 +178,7 @@ static void arm_semi_flen_cb(CPUARMState *env, target_ulong ret, target_ulong er
 #define SET_ARG(n, val) put_user_ual(val, args + (n) * 4)
 uint32_t do_arm_semihosting(CPUARMState *env)
 {
+    ARMCPU *cpu = arm_env_get_cpu(env);
     target_ulong args;
     target_ulong arg0, arg1, arg2, arg3;
     char * s;
@@ -549,7 +550,7 @@ uint32_t do_arm_semihosting(CPUARMState *env)
         exit(0);
     default:
         fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);
-        cpu_dump_state(env, stderr, fprintf, 0);
+        cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
         abort();
     }
 }
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 12fcefe..9d70ec4 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -120,4 +120,7 @@ void register_cp_regs_for_features(ARMCPU *cpu);
 void arm_cpu_do_interrupt(CPUState *cpu);
 void arm_v7m_cpu_do_interrupt(CPUState *cpu);
 
+void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags);
+
 #endif
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 496a59f..a40290c 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -814,6 +814,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = arm_cpu_class_by_name;
     cc->do_interrupt = arm_cpu_do_interrupt;
+    cc->dump_state = arm_cpu_dump_state;
     cpu_class_set_vmsd(cc, &vmstate_arm_cpu);
 }
 
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 2a18ffe..af2aef2 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -10085,9 +10085,11 @@ static const char *cpu_mode_names[16] = {
   "???", "???", "???", "und", "???", "???", "???", "sys"
 };
 
-void cpu_dump_state(CPUARMState *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags)
+void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags)
 {
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
     int i;
     uint32_t psr;
 
diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h
index 03829bd..e08bdb1 100644
--- a/target-cris/cpu-qom.h
+++ b/target-cris/cpu-qom.h
@@ -76,4 +76,7 @@ static inline CRISCPU *cris_env_get_cpu(CPUCRISState *env)
 void cris_cpu_do_interrupt(CPUState *cpu);
 void crisv10_cpu_do_interrupt(CPUState *cpu);
 
+void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
+
 #endif
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 67181e5..82271f7 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -252,6 +252,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = cris_cpu_class_by_name;
     cc->do_interrupt = cris_cpu_do_interrupt;
+    cc->dump_state = cris_cpu_dump_state;
 }
 
 static const TypeInfo cris_cpu_type_info = {
diff --git a/target-cris/helper.c b/target-cris/helper.c
index 466cc2f..aba7537 100644
--- a/target-cris/helper.c
+++ b/target-cris/helper.c
@@ -53,9 +53,11 @@ void crisv10_cpu_do_interrupt(CPUState *cs)
 int cpu_cris_handle_mmu_fault(CPUCRISState * env, target_ulong address, int rw,
                               int mmu_idx)
 {
+    CRISCPU *cpu = cris_env_get_cpu(env);
+
     env->exception_index = 0xaa;
     env->pregs[PR_EDA] = address;
-    cpu_dump_state(env, stderr, fprintf, 0);
+    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
     return 1;
 }
 
diff --git a/target-cris/translate.c b/target-cris/translate.c
index dbcb811..09d0d2b 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3427,9 +3427,11 @@ void gen_intermediate_code_pc (CPUCRISState *env, struct TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state (CPUCRISState *env, FILE *f, fprintf_function cpu_fprintf,
-                     int flags)
+void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
 {
+    CRISCPU *cpu = CRIS_CPU(cs);
+    CPUCRISState *env = &cpu->env;
     int i;
     uint32_t srs;
 
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index e0ac072..b7c70d6 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -101,4 +101,7 @@ int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
 void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
                                 Error **errp);
 
+void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags);
+
 #endif
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index a7154af..48c062f 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2526,6 +2526,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
     cc->reset = x86_cpu_reset;
 
     cc->do_interrupt = x86_cpu_do_interrupt;
+    cc->dump_state = x86_cpu_dump_state;
     cc->get_arch_id = x86_cpu_get_arch_id;
     cc->get_paging_enabled = x86_cpu_get_paging_enabled;
 #ifndef CONFIG_USER_ONLY
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 803945d..5e5abe3 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -179,10 +179,11 @@ done:
 #define DUMP_CODE_BYTES_TOTAL    50
 #define DUMP_CODE_BYTES_BACKWARD 20
 
-void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags)
+void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags)
 {
-    CPUState *cs = CPU(x86_env_get_cpu(env));
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
     int eflags, i, nb;
     char cc_op_name[32];
     static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h
index 9571860..5ef884b 100644
--- a/target-lm32/cpu-qom.h
+++ b/target-lm32/cpu-qom.h
@@ -76,5 +76,7 @@ extern const struct VMStateDescription vmstate_lm32_cpu;
 #endif
 
 void lm32_cpu_do_interrupt(CPUState *cpu);
+void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
 
 #endif
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 23c05dd..2366152 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -85,6 +85,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
     cc->reset = lm32_cpu_reset;
 
     cc->do_interrupt = lm32_cpu_do_interrupt;
+    cc->dump_state = lm32_cpu_dump_state;
     cpu_class_set_vmsd(cc, &vmstate_lm32_cpu);
 }
 
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index af9ce8c..227a801 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1141,9 +1141,11 @@ void gen_intermediate_code_pc(CPULM32State *env, struct TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state(CPULM32State *env, FILE *f, fprintf_function cpu_fprintf,
-                     int flags)
+void lm32_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
 {
+    LM32CPU *cpu = LM32_CPU(cs);
+    CPULM32State *env = &cpu->env;
     int i;
 
     if (!env || !f) {
diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h
index 846aa74..2436c13 100644
--- a/target-m68k/cpu-qom.h
+++ b/target-m68k/cpu-qom.h
@@ -71,5 +71,7 @@ static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env)
 #define ENV_OFFSET offsetof(M68kCPU, env)
 
 void m68k_cpu_do_interrupt(CPUState *cpu);
+void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
 
 #endif
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 3c65b4e..d501027 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -187,6 +187,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
 
     cc->class_by_name = m68k_cpu_class_by_name;
     cc->do_interrupt = m68k_cpu_do_interrupt;
+    cc->dump_state = m68k_cpu_dump_state;
     dc->vmsd = &vmstate_m68k_cpu;
 }
 
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 32b8132..3752094 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -3104,9 +3104,11 @@ void gen_intermediate_code_pc(CPUM68KState *env, TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state(CPUM68KState *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags)
+void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
 {
+    M68kCPU *cpu = M68K_CPU(cs);
+    CPUM68KState *env = &cpu->env;
     int i;
     uint16_t sr;
     CPU_DoubleU u;
diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h
index ce92a4e..3e9c206 100644
--- a/target-microblaze/cpu-qom.h
+++ b/target-microblaze/cpu-qom.h
@@ -72,5 +72,7 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
 #define ENV_OFFSET offsetof(MicroBlazeCPU, env)
 
 void mb_cpu_do_interrupt(CPUState *cs);
+void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                       int flags);
 
 #endif
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index 404f82c..e8104d1 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -138,6 +138,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
     cc->reset = mb_cpu_reset;
 
     cc->do_interrupt = mb_cpu_do_interrupt;
+    cc->dump_state = mb_cpu_dump_state;
     dc->vmsd = &vmstate_mb_cpu;
 
     dc->props = mb_properties;
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index 0dd669d..01d4bbf 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -39,8 +39,10 @@ void mb_cpu_do_interrupt(CPUState *cs)
 int cpu_mb_handle_mmu_fault(CPUMBState * env, target_ulong address, int rw,
                             int mmu_idx)
 {
+    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
+
     env->exception_index = 0xaa;
-    cpu_dump_state(env, stderr, fprintf, 0);
+    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
     return 1;
 }
 
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 06d2346..54f439f 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1949,9 +1949,11 @@ void gen_intermediate_code_pc (CPUMBState *env, struct TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state (CPUMBState *env, FILE *f, fprintf_function cpu_fprintf,
-                     int flags)
+void mb_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                       int flags)
 {
+    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+    CPUMBState *env = &cpu->env;
     int i;
 
     if (!env || !f)
diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h
index 32e3cad..a7ff9e6 100644
--- a/target-mips/cpu-qom.h
+++ b/target-mips/cpu-qom.h
@@ -75,5 +75,7 @@ static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
 #define ENV_OFFSET offsetof(MIPSCPU, env)
 
 void mips_cpu_do_interrupt(CPUState *cpu);
+void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
 
 #endif
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 5315f7b..b685d39 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -80,6 +80,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
     cc->reset = mips_cpu_reset;
 
     cc->do_interrupt = mips_cpu_do_interrupt;
+    cc->dump_state = mips_cpu_dump_state;
 }
 
 static const TypeInfo mips_cpu_type_info = {
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 0a53203..160c0c0 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15780,9 +15780,11 @@ cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
 }
 #endif
 
-void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
-                     int flags)
+void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
 {
+    MIPSCPU *cpu = MIPS_CPU(cs);
+    CPUMIPSState *env = &cpu->env;
     int i;
 
     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
index f2b0791..3c3932c 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -97,8 +97,9 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = moxie_cpu_class_by_name;
 
-    cpu_class_set_vmsd(cc, &vmstate_moxie_cpu);
     cc->do_interrupt = moxie_cpu_do_interrupt;
+    cc->dump_state = moxie_cpu_dump_state;
+    cpu_class_set_vmsd(cc, &vmstate_moxie_cpu);
 }
 
 static void moxielite_initfn(Object *obj)
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index a9d9ace..374b24a 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -116,6 +116,8 @@ static inline MoxieCPU *moxie_env_get_cpu(CPUMoxieState *env)
 MoxieCPU *cpu_moxie_init(const char *cpu_model);
 int cpu_moxie_exec(CPUMoxieState *s);
 void moxie_cpu_do_interrupt(CPUState *cs);
+void moxie_cpu_dump_state(CPUState *cpu, FILE *f,
+                          fprintf_function cpu_fprintf, int flags);
 void moxie_translate_init(void);
 int cpu_moxie_signal_handler(int host_signum, void *pinfo,
                              void *puc);
diff --git a/target-moxie/helper.c b/target-moxie/helper.c
index 5cfe889..ea0788f 100644
--- a/target-moxie/helper.c
+++ b/target-moxie/helper.c
@@ -110,9 +110,11 @@ void moxie_cpu_do_interrupt(CPUState *env)
 int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
                                int rw, int mmu_idx)
 {
+    MoxieCPU *cpu = moxie_env_get_cpu(env);
+
     env->exception_index = 0xaa;
     env->debug1 = address;
-    cpu_dump_state(env, stderr, fprintf, 0);
+    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
     return 1;
 }
 
diff --git a/target-moxie/translate.c b/target-moxie/translate.c
index cc02bd3..b0ae38a 100644
--- a/target-moxie/translate.c
+++ b/target-moxie/translate.c
@@ -74,9 +74,11 @@ static int extract_branch_offset(int opcode)
   return (((signed short)((opcode & ((1 << 10) - 1)) << 6)) >> 6) << 1;
 }
 
-void cpu_dump_state(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags)
+void moxie_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                          int flags)
 {
+    MoxieCPU *cpu = MOXIE_CPU(cs);
+    CPUMoxieState *env = &cpu->env;
     int i;
     cpu_fprintf(f, "pc=0x%08x\n", env->pc);
     cpu_fprintf(f, "$fp=0x%08x $sp=0x%08x $r0=0x%08x $r1=0x%08x\n",
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index ffe14f3..82bee2a 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -149,6 +149,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = openrisc_cpu_class_by_name;
     cc->do_interrupt = openrisc_cpu_do_interrupt;
+    cc->dump_state = openrisc_cpu_dump_state;
 }
 
 static void cpu_register(const OpenRISCCPUInfo *info)
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index b9c55ba..eb4d282 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -347,6 +347,8 @@ OpenRISCCPU *cpu_openrisc_init(const char *cpu_model);
 void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf);
 int cpu_openrisc_exec(CPUOpenRISCState *s);
 void openrisc_cpu_do_interrupt(CPUState *cpu);
+void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
+                             fprintf_function cpu_fprintf, int flags);
 void openrisc_translate_init(void);
 int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
                                   target_ulong address,
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 0eafd02..c59fd02 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1814,15 +1814,17 @@ void gen_intermediate_code_pc(CPUOpenRISCState *env,
     gen_intermediate_code_internal(openrisc_env_get_cpu(env), tb, 1);
 }
 
-void cpu_dump_state(CPUOpenRISCState *env, FILE *f,
-                    fprintf_function cpu_fprintf,
-                    int flags)
+void openrisc_cpu_dump_state(CPUState *cs, FILE *f,
+                             fprintf_function cpu_fprintf,
+                             int flags)
 {
+    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
+    CPUOpenRISCState *env = &cpu->env;
     int i;
-    uint32_t *regs = env->gpr;
+
     cpu_fprintf(f, "PC=%08x\n", env->pc);
     for (i = 0; i < 32; ++i) {
-        cpu_fprintf(f, "R%02d=%08x%c", i, regs[i],
+        cpu_fprintf(f, "R%02d=%08x%c", i, env->gpr[i],
                     (i % 4) == 3 ? '\n' : ' ');
     }
 }
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index eb03a00..84ba105 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -101,5 +101,9 @@ static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
 PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
 
 void ppc_cpu_do_interrupt(CPUState *cpu);
+void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                        int flags);
+void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
+                             fprintf_function cpu_fprintf, int flags);
 
 #endif
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 076cdac..3643863 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9526,15 +9526,17 @@ GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
 
 /*****************************************************************************/
 /* Misc PowerPC helpers */
-void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
-                     int flags)
+void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags)
 {
 #define RGPL  4
 #define RFPL  4
 
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
     int i;
 
-    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
+    cpu_synchronize_state(cs);
 
     cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
                 TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
@@ -9675,14 +9677,15 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
 #undef RFPL
 }
 
-void cpu_dump_statistics (CPUPPCState *env, FILE*f, fprintf_function cpu_fprintf,
-                          int flags)
+void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
+                             fprintf_function cpu_fprintf, int flags)
 {
 #if defined(DO_PPC_STATISTICS)
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
     opc_handler_t **t1, **t2, **t3, *handler;
     int op1, op2, op3;
 
-    t1 = env->opcodes;
+    t1 = cpu->env.opcodes;
     for (op1 = 0; op1 < 64; op1++) {
         handler = t1[op1];
         if (is_indirect_opcode(handler)) {
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 021a31e..0edb336 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8309,6 +8309,8 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = ppc_cpu_class_by_name;
     cc->do_interrupt = ppc_cpu_do_interrupt;
+    cc->dump_state = ppc_cpu_dump_state;
+    cc->dump_statistics = ppc_cpu_dump_statistics;
 }
 
 static const TypeInfo ppc_cpu_type_info = {
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index 34d45c2..ec32d21 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -72,5 +72,7 @@ static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
 #define ENV_OFFSET offsetof(S390CPU, env)
 
 void s390_cpu_do_interrupt(CPUState *cpu);
+void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
 
 #endif
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 23fe51f..8ec2f9b 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -170,6 +170,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->reset = s390_cpu_reset;
 
     cc->do_interrupt = s390_cpu_do_interrupt;
+    cc->dump_state = s390_cpu_dump_state;
     dc->vmsd = &vmstate_s390_cpu;
 }
 
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index f97e431..cd9880e 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -86,9 +86,11 @@ static uint64_t pc_to_link_info(DisasContext *s, uint64_t pc)
     return pc;
 }
 
-void cpu_dump_state(CPUS390XState *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags)
+void s390_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
 {
+    S390CPU *cpu = S390_CPU(cs);
+    CPUS390XState *env = &cpu->env;
     int i;
 
     if (env->cc_op > 3) {
diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h
index f8c80d3..01d1637 100644
--- a/target-sh4/cpu-qom.h
+++ b/target-sh4/cpu-qom.h
@@ -84,5 +84,7 @@ static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env)
 #define ENV_OFFSET offsetof(SuperHCPU, env)
 
 void superh_cpu_do_interrupt(CPUState *cpu);
+void superh_cpu_dump_state(CPUState *cpu, FILE *f,
+                           fprintf_function cpu_fprintf, int flags);
 
 #endif
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index 898aecd..a7d5213 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -274,6 +274,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = superh_cpu_class_by_name;
     cc->do_interrupt = superh_cpu_do_interrupt;
+    cc->dump_state = superh_cpu_dump_state;
     dc->vmsd = &vmstate_sh_cpu;
 }
 
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 14fdb8f..292c9e9 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -150,10 +150,11 @@ void sh4_translate_init(void)
     done_init = 1;
 }
 
-void cpu_dump_state(CPUSH4State * env, FILE * f,
-		    int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
-		    int flags)
+void superh_cpu_dump_state(CPUState *cs, FILE *f,
+                           fprintf_function cpu_fprintf, int flags)
 {
+    SuperHCPU *cpu = SUPERH_CPU(cs);
+    CPUSH4State *env = &cpu->env;
     int i;
     cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
 		env->pc, env->sr, env->pr, env->fpscr);
diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h
index d4fe89e..97c1ec7 100644
--- a/target-sparc/cpu-qom.h
+++ b/target-sparc/cpu-qom.h
@@ -76,5 +76,7 @@ static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
 #define ENV_OFFSET offsetof(SPARCCPU, env)
 
 void sparc_cpu_do_interrupt(CPUState *cpu);
+void sparc_cpu_dump_state(CPUState *cpu, FILE *f,
+                          fprintf_function cpu_fprintf, int flags);
 
 #endif
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 13bb7bb..72700cd 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -660,9 +660,11 @@ static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
 #define REGS_PER_LINE 8
 #endif
 
-void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags)
+void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                          int flags)
 {
+    SPARCCPU *cpu = SPARC_CPU(cs);
+    CPUSPARCState *env = &cpu->env;
     int i, x;
 
     cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc,
@@ -771,6 +773,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
     cc->reset = sparc_cpu_reset;
 
     cc->do_interrupt = sparc_cpu_do_interrupt;
+    cc->dump_state = sparc_cpu_dump_state;
 }
 
 static const TypeInfo sparc_cpu_type_info = {
diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h
index ba4dee4..7eec448 100644
--- a/target-unicore32/cpu-qom.h
+++ b/target-unicore32/cpu-qom.h
@@ -61,5 +61,7 @@ static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env)
 #define ENV_OFFSET offsetof(UniCore32CPU, env)
 
 void uc32_cpu_do_interrupt(CPUState *cpu);
+void uc32_cpu_dump_state(CPUState *cpu, FILE *f,
+                         fprintf_function cpu_fprintf, int flags);
 
 #endif
diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
index 66a1a74..1a97e6b 100644
--- a/target-unicore32/cpu.c
+++ b/target-unicore32/cpu.c
@@ -133,6 +133,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = uc32_cpu_class_by_name;
     cc->do_interrupt = uc32_cpu_do_interrupt;
+    cc->dump_state = uc32_cpu_dump_state;
     dc->vmsd = &vmstate_uc32_cpu;
 }
 
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 3dc7856..e1fe4e6 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -2113,9 +2113,11 @@ static void cpu_dump_state_ucf64(CPUUniCore32State *env, FILE *f,
 #define cpu_dump_state_ucf64(env, file, pr, flags)      do { } while (0)
 #endif
 
-void cpu_dump_state(CPUUniCore32State *env, FILE *f,
-        fprintf_function cpu_fprintf, int flags)
+void uc32_cpu_dump_state(CPUState *cs, FILE *f,
+                         fprintf_function cpu_fprintf, int flags)
 {
+    UniCore32CPU *cpu = UNICORE32_CPU(cs);
+    CPUUniCore32State *env = &cpu->env;
     int i;
     uint32_t psr;
 
diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h
index af0ce28..30506cf 100644
--- a/target-xtensa/cpu-qom.h
+++ b/target-xtensa/cpu-qom.h
@@ -81,5 +81,7 @@ static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
 #define ENV_OFFSET offsetof(XtensaCPU, env)
 
 void xtensa_cpu_do_interrupt(CPUState *cpu);
+void xtensa_cpu_dump_state(CPUState *cpu, FILE *f,
+                           fprintf_function cpu_fprintf, int flags);
 
 #endif
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index 6e93dd8..b5df321 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -102,6 +102,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
     cc->reset = xtensa_cpu_reset;
 
     cc->do_interrupt = xtensa_cpu_do_interrupt;
+    cc->dump_state = xtensa_cpu_dump_state;
     dc->vmsd = &vmstate_xtensa_cpu;
 }
 
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 1037101..4c41de0 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -368,7 +368,9 @@ void HELPER(wsr_lend)(CPUXtensaState *env, uint32_t v)
 
 void HELPER(dump_state)(CPUXtensaState *env)
 {
-    cpu_dump_state(env, stderr, fprintf, 0);
+    XtensaCPU *cpu = xtensa_env_get_cpu(env);
+
+    cpu_dump_state(CPU(cpu), stderr, fprintf, 0);
 }
 
 void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel)
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 06d68db..dcb90a5 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -3014,9 +3014,11 @@ void gen_intermediate_code_pc(CPUXtensaState *env, TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state(CPUXtensaState *env, FILE *f, fprintf_function cpu_fprintf,
-        int flags)
+void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
+                           fprintf_function cpu_fprintf, int flags)
 {
+    XtensaCPU *cpu = XTENSA_CPU(cs);
+    CPUXtensaState *env = &cpu->env;
     int i, j;
 
     cpu_fprintf(f, "PC=%08x\n\n", env->pc);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH qom-cpu v2 10/29] kvm: Change kvm_handle_internal_error() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
@ 2013-06-16 15:57   ` Andreas Färber
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
                     ` (28 subsequent siblings)
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Andreas Färber, Gleb Natapov, Marcelo Tosatti, open list:Overall

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 kvm-all.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 1cd4573..1675311 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1520,10 +1520,8 @@ static void kvm_handle_io(uint16_t port, void *data, int direction, int size,
     }
 }
 
-static int kvm_handle_internal_error(CPUArchState *env, struct kvm_run *run)
+static int kvm_handle_internal_error(CPUState *cpu, struct kvm_run *run)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
-
     fprintf(stderr, "KVM internal error.");
     if (kvm_check_extension(kvm_state, KVM_CAP_INTERNAL_ERROR_DATA)) {
         int i;
@@ -1685,7 +1683,7 @@ int kvm_cpu_exec(CPUArchState *env)
             ret = -1;
             break;
         case KVM_EXIT_INTERNAL_ERROR:
-            ret = kvm_handle_internal_error(env, run);
+            ret = kvm_handle_internal_error(cpu, run);
             break;
         default:
             DPRINTF("kvm_arch_handle_exit\n");
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 10/29] kvm: Change kvm_handle_internal_error() argument to CPUState
@ 2013-06-16 15:57   ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marcelo Tosatti, Andreas Färber, Gleb Natapov, open list:Overall

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 kvm-all.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 1cd4573..1675311 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1520,10 +1520,8 @@ static void kvm_handle_io(uint16_t port, void *data, int direction, int size,
     }
 }
 
-static int kvm_handle_internal_error(CPUArchState *env, struct kvm_run *run)
+static int kvm_handle_internal_error(CPUState *cpu, struct kvm_run *run)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
-
     fprintf(stderr, "KVM internal error.");
     if (kvm_check_extension(kvm_state, KVM_CAP_INTERNAL_ERROR_DATA)) {
         int i;
@@ -1685,7 +1683,7 @@ int kvm_cpu_exec(CPUArchState *env)
             ret = -1;
             break;
         case KVM_EXIT_INTERNAL_ERROR:
-            ret = kvm_handle_internal_error(env, run);
+            ret = kvm_handle_internal_error(cpu, run);
             break;
         default:
             DPRINTF("kvm_arch_handle_exit\n");
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH qom-cpu v2 11/29] kvm: Change kvm_cpu_exec() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
@ 2013-06-16 15:57   ` Andreas Färber
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
                     ` (28 subsequent siblings)
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Andreas Färber, Gleb Natapov, Marcelo Tosatti, open list:Overall

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c               | 2 +-
 include/sysemu/kvm.h | 2 +-
 kvm-all.c            | 3 +--
 kvm-stub.c           | 4 ++--
 4 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/cpus.c b/cpus.c
index bbaf13c..47ab818 100644
--- a/cpus.c
+++ b/cpus.c
@@ -752,7 +752,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
 
     while (1) {
         if (cpu_can_run(cpu)) {
-            r = kvm_cpu_exec(env);
+            r = kvm_cpu_exec(cpu);
             if (r == EXCP_DEBUG) {
                 cpu_handle_guest_debug(env);
             }
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 5adb044..fe8bc40 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -147,9 +147,9 @@ int kvm_has_gsi_routing(void);
 int kvm_has_intx_set_mask(void);
 
 int kvm_init_vcpu(CPUState *cpu);
+int kvm_cpu_exec(CPUState *cpu);
 
 #ifdef NEED_CPU_H
-int kvm_cpu_exec(CPUArchState *env);
 
 #if !defined(CONFIG_USER_ONLY)
 void *kvm_ram_alloc(ram_addr_t size);
diff --git a/kvm-all.c b/kvm-all.c
index 1675311..90b89cd 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1602,9 +1602,8 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
     cpu->kvm_vcpu_dirty = false;
 }
 
-int kvm_cpu_exec(CPUArchState *env)
+int kvm_cpu_exec(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_run *run = cpu->kvm_run;
     int ret, run_ret;
 
diff --git a/kvm-stub.c b/kvm-stub.c
index 50af700..5457fe8 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -54,9 +54,9 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
 {
 }
 
-int kvm_cpu_exec(CPUArchState *env)
+int kvm_cpu_exec(CPUState *cpu)
 {
-    abort ();
+    abort();
 }
 
 int kvm_has_sync_mmu(void)
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 11/29] kvm: Change kvm_cpu_exec() argument to CPUState
@ 2013-06-16 15:57   ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marcelo Tosatti, Andreas Färber, Gleb Natapov, open list:Overall

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c               | 2 +-
 include/sysemu/kvm.h | 2 +-
 kvm-all.c            | 3 +--
 kvm-stub.c           | 4 ++--
 4 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/cpus.c b/cpus.c
index bbaf13c..47ab818 100644
--- a/cpus.c
+++ b/cpus.c
@@ -752,7 +752,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
 
     while (1) {
         if (cpu_can_run(cpu)) {
-            r = kvm_cpu_exec(env);
+            r = kvm_cpu_exec(cpu);
             if (r == EXCP_DEBUG) {
                 cpu_handle_guest_debug(env);
             }
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 5adb044..fe8bc40 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -147,9 +147,9 @@ int kvm_has_gsi_routing(void);
 int kvm_has_intx_set_mask(void);
 
 int kvm_init_vcpu(CPUState *cpu);
+int kvm_cpu_exec(CPUState *cpu);
 
 #ifdef NEED_CPU_H
-int kvm_cpu_exec(CPUArchState *env);
 
 #if !defined(CONFIG_USER_ONLY)
 void *kvm_ram_alloc(ram_addr_t size);
diff --git a/kvm-all.c b/kvm-all.c
index 1675311..90b89cd 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1602,9 +1602,8 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
     cpu->kvm_vcpu_dirty = false;
 }
 
-int kvm_cpu_exec(CPUArchState *env)
+int kvm_cpu_exec(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_run *run = cpu->kvm_run;
     int ret, run_ret;
 
diff --git a/kvm-stub.c b/kvm-stub.c
index 50af700..5457fe8 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -54,9 +54,9 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
 {
 }
 
-int kvm_cpu_exec(CPUArchState *env)
+int kvm_cpu_exec(CPUState *cpu)
 {
-    abort ();
+    abort();
 }
 
 int kvm_has_sync_mmu(void)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 12/29] gdbstub: Set gdb_set_stop_cpu() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (10 preceding siblings ...)
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-17 20:15   ` Richard Henderson
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 13/29] cpus: Change cpu_handle_guest_debug() " Andreas Färber
                   ` (17 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Use CPUState::env_ptr for now.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c                 | 2 +-
 gdbstub.c              | 4 +++-
 include/exec/gdbstub.h | 2 +-
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/cpus.c b/cpus.c
index 47ab818..44ec34f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -463,7 +463,7 @@ static void cpu_handle_guest_debug(CPUArchState *env)
 {
     CPUState *cpu = ENV_GET_CPU(env);
 
-    gdb_set_stop_cpu(env);
+    gdb_set_stop_cpu(cpu);
     qemu_system_debug_request();
     cpu->stopped = true;
 }
diff --git a/gdbstub.c b/gdbstub.c
index 0f15c7c..3101a43 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2506,8 +2506,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
     return RS_IDLE;
 }
 
-void gdb_set_stop_cpu(CPUArchState *env)
+void gdb_set_stop_cpu(CPUState *cpu)
 {
+    CPUArchState *env = cpu->env_ptr;
+
     gdbserver_state->c_cpu = env;
     gdbserver_state->g_cpu = env;
 }
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index ba20afa..ded4160 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -16,7 +16,7 @@ typedef void (*gdb_syscall_complete_cb)(CPUArchState *env,
 
 void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
 int use_gdb_syscalls(void);
-void gdb_set_stop_cpu(CPUArchState *env);
+void gdb_set_stop_cpu(CPUState *cpu);
 void gdb_exit(CPUArchState *, int);
 #ifdef CONFIG_USER_ONLY
 int gdb_queuesig (void);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 13/29] cpus: Change cpu_handle_guest_debug() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (11 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 12/29] gdbstub: Set gdb_set_stop_cpu() " Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-17 20:17   ` Richard Henderson
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 14/29] cpus: Change qemu_kvm_start_vcpu() " Andreas Färber
                   ` (16 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/cpus.c b/cpus.c
index 44ec34f..1694455 100644
--- a/cpus.c
+++ b/cpus.c
@@ -459,10 +459,8 @@ static bool cpu_can_run(CPUState *cpu)
     return true;
 }
 
-static void cpu_handle_guest_debug(CPUArchState *env)
+static void cpu_handle_guest_debug(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
-
     gdb_set_stop_cpu(cpu);
     qemu_system_debug_request();
     cpu->stopped = true;
@@ -754,7 +752,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
         if (cpu_can_run(cpu)) {
             r = kvm_cpu_exec(cpu);
             if (r == EXCP_DEBUG) {
-                cpu_handle_guest_debug(env);
+                cpu_handle_guest_debug(cpu);
             }
         }
         qemu_kvm_wait_io_event(cpu);
@@ -1172,7 +1170,7 @@ static void tcg_exec_all(void)
         if (cpu_can_run(cpu)) {
             r = tcg_cpu_exec(env);
             if (r == EXCP_DEBUG) {
-                cpu_handle_guest_debug(env);
+                cpu_handle_guest_debug(cpu);
                 break;
             }
         } else if (cpu->stop || cpu->stopped) {
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 14/29] cpus: Change qemu_kvm_start_vcpu() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (12 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 13/29] cpus: Change cpu_handle_guest_debug() " Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-17 20:18   ` Richard Henderson
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 15/29] cpus: Change qemu_dummy_start_vcpu() " Andreas Färber
                   ` (15 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Pass it on to qemu_kvm_cpu_thread_fn().

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/cpus.c b/cpus.c
index 1694455..bad42a2 100644
--- a/cpus.c
+++ b/cpus.c
@@ -727,14 +727,13 @@ static void qemu_kvm_wait_io_event(CPUState *cpu)
 
 static void *qemu_kvm_cpu_thread_fn(void *arg)
 {
-    CPUArchState *env = arg;
-    CPUState *cpu = ENV_GET_CPU(env);
+    CPUState *cpu = arg;
     int r;
 
     qemu_mutex_lock(&qemu_global_mutex);
     qemu_thread_get_self(cpu->thread);
     cpu->thread_id = qemu_get_thread_id();
-    cpu_single_env = env;
+    cpu_single_env = cpu->env_ptr;
 
     r = kvm_init_vcpu(cpu);
     if (r < 0) {
@@ -1031,14 +1030,12 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
     }
 }
 
-static void qemu_kvm_start_vcpu(CPUArchState *env)
+static void qemu_kvm_start_vcpu(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
-
     cpu->thread = g_malloc0(sizeof(QemuThread));
     cpu->halt_cond = g_malloc0(sizeof(QemuCond));
     qemu_cond_init(cpu->halt_cond);
-    qemu_thread_create(cpu->thread, qemu_kvm_cpu_thread_fn, env,
+    qemu_thread_create(cpu->thread, qemu_kvm_cpu_thread_fn, cpu,
                        QEMU_THREAD_JOINABLE);
     while (!cpu->created) {
         qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
@@ -1068,7 +1065,7 @@ void qemu_init_vcpu(void *_env)
     cpu->nr_threads = smp_threads;
     cpu->stopped = true;
     if (kvm_enabled()) {
-        qemu_kvm_start_vcpu(env);
+        qemu_kvm_start_vcpu(cpu);
     } else if (tcg_enabled()) {
         qemu_tcg_init_vcpu(cpu);
     } else {
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 15/29] cpus: Change qemu_dummy_start_vcpu() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (13 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 14/29] cpus: Change qemu_kvm_start_vcpu() " Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-17 20:19   ` Richard Henderson
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 16/29] cpu: Change qemu_init_vcpu() " Andreas Färber
                   ` (14 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Pass it to qemu_dummy_cpu_thread_fn().
Use CPUState::env_ptr for cpu_single_env.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/cpus.c b/cpus.c
index bad42a2..a9a7074 100644
--- a/cpus.c
+++ b/cpus.c
@@ -766,8 +766,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
     fprintf(stderr, "qtest is not supported under Windows\n");
     exit(1);
 #else
-    CPUArchState *env = arg;
-    CPUState *cpu = ENV_GET_CPU(env);
+    CPUState *cpu = arg;
     sigset_t waitset;
     int r;
 
@@ -782,7 +781,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
     cpu->created = true;
     qemu_cond_signal(&qemu_cpu_cond);
 
-    cpu_single_env = env;
+    cpu_single_env = cpu->env_ptr;
     while (1) {
         cpu_single_env = NULL;
         qemu_mutex_unlock_iothread();
@@ -795,7 +794,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
             exit(1);
         }
         qemu_mutex_lock_iothread();
-        cpu_single_env = env;
+        cpu_single_env = cpu->env_ptr;
         qemu_wait_io_event_common(cpu);
     }
 
@@ -1042,14 +1041,12 @@ static void qemu_kvm_start_vcpu(CPUState *cpu)
     }
 }
 
-static void qemu_dummy_start_vcpu(CPUArchState *env)
+static void qemu_dummy_start_vcpu(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
-
     cpu->thread = g_malloc0(sizeof(QemuThread));
     cpu->halt_cond = g_malloc0(sizeof(QemuCond));
     qemu_cond_init(cpu->halt_cond);
-    qemu_thread_create(cpu->thread, qemu_dummy_cpu_thread_fn, env,
+    qemu_thread_create(cpu->thread, qemu_dummy_cpu_thread_fn, cpu,
                        QEMU_THREAD_JOINABLE);
     while (!cpu->created) {
         qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
@@ -1069,7 +1066,7 @@ void qemu_init_vcpu(void *_env)
     } else if (tcg_enabled()) {
         qemu_tcg_init_vcpu(cpu);
     } else {
-        qemu_dummy_start_vcpu(env);
+        qemu_dummy_start_vcpu(cpu);
     }
 }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 16/29] cpu: Change qemu_init_vcpu() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (14 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 15/29] cpus: Change qemu_dummy_start_vcpu() " Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-17 20:23   ` Richard Henderson
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 17/29] hwaddr: Make hwaddr type usable beyond softmmu Andreas Färber
                   ` (13 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Anthony Green, Alexander Graf, Blue Swirl,
	Max Filippov, Michael Walle, open list:PowerPC, Paul Brook,
	Edgar E. Iglesias, Guan Xuetao, Andreas Färber,
	Aurelien Jarno, Richard Henderson

This allows to move the call to CPUState's realizefn.
Therefore move the stub into libqemustub.a.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c                      | 5 +----
 include/qemu-common.h       | 8 --------
 include/qom/cpu.h           | 8 ++++++++
 qom/cpu.c                   | 2 ++
 stubs/cpus.c                | 4 ++++
 target-alpha/cpu.c          | 3 ---
 target-arm/cpu.c            | 1 -
 target-cris/cpu.c           | 1 -
 target-i386/cpu.c           | 1 -
 target-lm32/cpu.c           | 2 --
 target-m68k/cpu.c           | 1 -
 target-microblaze/cpu.c     | 1 -
 target-mips/cpu.c           | 1 -
 target-moxie/cpu.c          | 5 ++---
 target-openrisc/cpu.c       | 1 -
 target-ppc/translate_init.c | 2 --
 target-s390x/cpu.c          | 1 -
 target-sh4/cpu.c            | 1 -
 target-sparc/cpu.c          | 3 ---
 target-unicore32/cpu.c      | 3 ---
 target-xtensa/cpu.c         | 3 ---
 21 files changed, 17 insertions(+), 40 deletions(-)

diff --git a/cpus.c b/cpus.c
index a9a7074..775d998 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1053,11 +1053,8 @@ static void qemu_dummy_start_vcpu(CPUState *cpu)
     }
 }
 
-void qemu_init_vcpu(void *_env)
+void qemu_init_vcpu(CPUState *cpu)
 {
-    CPUArchState *env = _env;
-    CPUState *cpu = ENV_GET_CPU(env);
-
     cpu->nr_cores = smp_cores;
     cpu->nr_threads = smp_threads;
     cpu->stopped = true;
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 3c91375..15b5f9f 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -293,14 +293,6 @@ struct qemu_work_item {
     int done;
 };
 
-#ifdef CONFIG_USER_ONLY
-static inline void qemu_init_vcpu(void *env)
-{
-}
-#else
-void qemu_init_vcpu(void *env);
-#endif
-
 
 /**
  * Sends a (part of) iovec down a socket, yielding when the socket is full, or
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index e25898d..be2a0bd 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -407,4 +407,12 @@ void cpu_exit(CPUState *cpu);
  */
 void cpu_resume(CPUState *cpu);
 
+/**
+ * qemu_init_vcpu:
+ * @cpu: The vCPU to initialize.
+ *
+ * Initializes a vCPU.
+ */
+void qemu_init_vcpu(CPUState *cpu);
+
 #endif
diff --git a/qom/cpu.c b/qom/cpu.c
index 4da6332..ee8f632 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -209,6 +209,8 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp)
 {
     CPUState *cpu = CPU(dev);
 
+    qemu_init_vcpu(cpu);
+
     if (dev->hotplugged) {
         cpu_synchronize_post_init(cpu);
         notifier_list_notify(&cpu_added_notifiers, dev);
diff --git a/stubs/cpus.c b/stubs/cpus.c
index f0d56c5..8e6f06b 100644
--- a/stubs/cpus.c
+++ b/stubs/cpus.c
@@ -4,3 +4,7 @@
 void cpu_resume(CPUState *cpu)
 {
 }
+
+void qemu_init_vcpu(CPUState *cpu)
+{
+}
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index 395551a..7d5d6f9 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -25,11 +25,8 @@
 
 static void alpha_cpu_realizefn(DeviceState *dev, Error **errp)
 {
-    AlphaCPU *cpu = ALPHA_CPU(dev);
     AlphaCPUClass *acc = ALPHA_CPU_GET_CLASS(dev);
 
-    qemu_init_vcpu(&cpu->env);
-
     acc->parent_realize(dev, errp);
 }
 
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index a40290c..88ee61b 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -205,7 +205,6 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
     arm_cpu_register_gdb_regs_for_features(cpu);
 
     cpu_reset(CPU(cpu));
-    qemu_init_vcpu(env);
 
     acc->parent_realize(dev, errp);
 }
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 82271f7..6a3bdf0 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -139,7 +139,6 @@ static void cris_cpu_realizefn(DeviceState *dev, Error **errp)
     CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(dev);
 
     cpu_reset(CPU(cpu));
-    qemu_init_vcpu(&cpu->env);
 
     ccc->parent_realize(dev, errp);
 }
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 48c062f..b7416fe 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2392,7 +2392,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
 #endif
 
     mce_init(cpu);
-    qemu_init_vcpu(&cpu->env);
 
     x86_cpu_apic_realize(cpu, &local_err);
     if (local_err != NULL) {
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 2366152..02f8436 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -49,8 +49,6 @@ static void lm32_cpu_realizefn(DeviceState *dev, Error **errp)
 
     cpu_reset(CPU(cpu));
 
-    qemu_init_vcpu(&cpu->env);
-
     lcc->parent_realize(dev, errp);
 }
 
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index d501027..799869f 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -147,7 +147,6 @@ static void m68k_cpu_realizefn(DeviceState *dev, Error **errp)
     m68k_cpu_init_gdb(cpu);
 
     cpu_reset(CPU(cpu));
-    qemu_init_vcpu(&cpu->env);
 
     mcc->parent_realize(dev, errp);
 }
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index e8104d1..b9a097c 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -92,7 +92,6 @@ static void mb_cpu_realizefn(DeviceState *dev, Error **errp)
     MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(dev);
 
     cpu_reset(CPU(cpu));
-    qemu_init_vcpu(&cpu->env);
 
     mcc->parent_realize(dev, errp);
 }
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index b685d39..0fdc316 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -48,7 +48,6 @@ static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
     MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(dev);
 
     cpu_reset(CPU(cpu));
-    qemu_init_vcpu(&cpu->env);
 
     mcc->parent_realize(dev, errp);
 }
diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
index 3c3932c..f3c0d22 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -44,12 +44,11 @@ static void moxie_cpu_reset(CPUState *s)
 static void moxie_cpu_realizefn(DeviceState *dev, Error **errp)
 {
     MoxieCPU *cpu = MOXIE_CPU(dev);
-    MoxieCPUClass *occ = MOXIE_CPU_GET_CLASS(dev);
+    MoxieCPUClass *mcc = MOXIE_CPU_GET_CLASS(dev);
 
-    qemu_init_vcpu(&cpu->env);
     cpu_reset(CPU(cpu));
 
-    occ->parent_realize(dev, errp);
+    mcc->parent_realize(dev, errp);
 }
 
 static void moxie_cpu_initfn(Object *obj)
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index 82bee2a..dff357f 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -67,7 +67,6 @@ static void openrisc_cpu_realizefn(DeviceState *dev, Error **errp)
     OpenRISCCPU *cpu = OPENRISC_CPU(dev);
     OpenRISCCPUClass *occ = OPENRISC_CPU_GET_CLASS(dev);
 
-    qemu_init_vcpu(&cpu->env);
     cpu_reset(CPU(cpu));
 
     occ->parent_realize(dev, errp);
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 0edb336..fa5e09f 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7752,8 +7752,6 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
                                  34, "power-spe.xml", 0);
     }
 
-    qemu_init_vcpu(env);
-
     pcc->parent_realize(dev, errp);
 
 #if defined(PPC_DUMP_CPU)
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 8ec2f9b..c3697cd 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -102,7 +102,6 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
     S390CPU *cpu = S390_CPU(dev);
     S390CPUClass *scc = S390_CPU_GET_CLASS(dev);
 
-    qemu_init_vcpu(&cpu->env);
     cpu_reset(CPU(cpu));
 
     scc->parent_realize(dev, errp);
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index a7d5213..e739156 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -234,7 +234,6 @@ static void superh_cpu_realizefn(DeviceState *dev, Error **errp)
     SuperHCPUClass *scc = SUPERH_CPU_GET_CLASS(dev);
 
     cpu_reset(CPU(cpu));
-    qemu_init_vcpu(&cpu->env);
 
     scc->parent_realize(dev, errp);
 }
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 72700cd..ff1200c 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -730,11 +730,8 @@ void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
 
 static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
 {
-    SPARCCPU *cpu = SPARC_CPU(dev);
     SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
 
-    qemu_init_vcpu(&cpu->env);
-
     scc->parent_realize(dev, errp);
 }
 
diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
index 1a97e6b..6572f01 100644
--- a/target-unicore32/cpu.c
+++ b/target-unicore32/cpu.c
@@ -83,11 +83,8 @@ static const UniCore32CPUInfo uc32_cpus[] = {
 
 static void uc32_cpu_realizefn(DeviceState *dev, Error **errp)
 {
-    UniCore32CPU *cpu = UNICORE32_CPU(dev);
     UniCore32CPUClass *ucc = UNICORE32_CPU_GET_CLASS(dev);
 
-    qemu_init_vcpu(&cpu->env);
-
     ucc->parent_realize(dev, errp);
 }
 
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index b5df321..0488984 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -59,11 +59,8 @@ static void xtensa_cpu_reset(CPUState *s)
 
 static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
 {
-    XtensaCPU *cpu = XTENSA_CPU(dev);
     XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev);
 
-    qemu_init_vcpu(&cpu->env);
-
     xcc->parent_realize(dev, errp);
 }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 17/29] hwaddr: Make hwaddr type usable beyond softmmu
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (15 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 16/29] cpu: Change qemu_init_vcpu() " Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 18/29] cpu: Turn cpu_unassigned_access() into a CPUState hook Andreas Färber
                   ` (12 subsequent siblings)
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

While not normally needed for *-user, it can safely be used there since
always based on uint64_t, to avoid ifdeffery.

To avoid accidental uses, move the guards from exec/hwaddr.h to its
inclusion sites.  No need for them in include/hw/.

Prepares for hwaddr use in qom/cpu.h.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 include/exec/cpu-common.h | 2 ++
 include/exec/cpu-defs.h   | 2 ++
 include/exec/hwaddr.h     | 4 ----
 include/exec/memory.h     | 2 ++
 4 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index e061e21..e6f1c30 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -3,7 +3,9 @@
 
 /* CPU interfaces that are target independent.  */
 
+#ifndef CONFIG_USER_ONLY
 #include "exec/hwaddr.h"
+#endif
 
 #ifndef NEED_CPU_H
 #include "exec/poison.h"
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 2e5a9ba..c4ac929 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -28,7 +28,9 @@
 #include <inttypes.h>
 #include "qemu/osdep.h"
 #include "qemu/queue.h"
+#ifndef CONFIG_USER_ONLY
 #include "exec/hwaddr.h"
+#endif
 
 #ifndef TARGET_LONG_BITS
 #error TARGET_LONG_BITS must be defined before including this header
diff --git a/include/exec/hwaddr.h b/include/exec/hwaddr.h
index 251cf92..c9eb78f 100644
--- a/include/exec/hwaddr.h
+++ b/include/exec/hwaddr.h
@@ -3,8 +3,6 @@
 #ifndef HWADDR_H
 #define HWADDR_H
 
-#ifndef CONFIG_USER_ONLY
-
 #define HWADDR_BITS 64
 /* hwaddr is the type of a physical address (its size can
    be different from 'target_ulong').  */
@@ -20,5 +18,3 @@ typedef uint64_t hwaddr;
 #define HWADDR_PRIX PRIX64
 
 #endif
-
-#endif
diff --git a/include/exec/memory.h b/include/exec/memory.h
index d53a6a1..d93d085 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -20,7 +20,9 @@
 #include <stdbool.h>
 #include "qemu-common.h"
 #include "exec/cpu-common.h"
+#ifndef CONFIG_USER_ONLY
 #include "exec/hwaddr.h"
+#endif
 #include "qemu/queue.h"
 #include "exec/iorange.h"
 #include "exec/ioport.h"
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 18/29] cpu: Turn cpu_unassigned_access() into a CPUState hook
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (16 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 17/29] hwaddr: Make hwaddr type usable beyond softmmu Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-17 20:34   ` Richard Henderson
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu Andreas Färber
                   ` (11 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Blue Swirl, Edgar E. Iglesias, Andreas Färber,
	Aurelien Jarno, Richard Henderson

Use it for all targets, but be careful not to pass invalid CPUState.
cpu_single_env can be NULL, e.g. on Xen.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cputlb.c                      | 15 +++++++++------
 hw/alpha/typhoon.c            | 14 ++++++++++----
 include/qom/cpu.h             | 33 +++++++++++++++++++++++++++++++++
 memory.c                      | 14 ++++++++------
 target-alpha/cpu.c            |  1 +
 target-alpha/cpu.h            |  6 +++---
 target-alpha/mem_helper.c     | 10 +++++++---
 target-microblaze/cpu.c       |  2 +-
 target-microblaze/cpu.h       |  5 +++--
 target-microblaze/op_helper.c | 17 +++++++++++++----
 target-mips/cpu.c             |  1 +
 target-mips/cpu.h             |  5 +++--
 target-mips/op_helper.c       | 13 +++++++++----
 target-sparc/cpu.c            |  1 +
 target-sparc/cpu.h            |  5 +++--
 target-sparc/ldst_helper.c    | 27 +++++++++++++++++++--------
 16 files changed, 124 insertions(+), 45 deletions(-)

diff --git a/cputlb.c b/cputlb.c
index 1230e9e..232c488 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -331,12 +331,15 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
     pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
     mr = iotlb_to_region(pd);
     if (memory_region_is_unassigned(mr)) {
-#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC)
-        cpu_unassigned_access(env1, addr, 0, 1, 0, 4);
-#else
-        cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x"
-                  TARGET_FMT_lx "\n", addr);
-#endif
+        CPUState *cpu = ENV_GET_CPU(env1);
+        CPUClass *cc = CPU_GET_CLASS(cpu);
+
+        if (cc->do_unassigned_access) {
+            cc->do_unassigned_access(cpu, addr, false, true, 0, 4);
+        } else {
+            cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x"
+                      TARGET_FMT_lx "\n", addr);
+        }
     }
     p = (void *)((uintptr_t)addr + env1->tlb_table[mmu_idx][page_index].addend);
     return qemu_ram_addr_from_host_nofail(p);
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index 1ead187..207dcad 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -197,7 +197,8 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
         break;
 
     default:
-        cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, size);
+        cpu = CPU(alpha_env_get_cpu(cpu_single_env));
+        cpu_unassigned_access(cpu, addr, false, false, 0, size);
         return -1;
     }
 
@@ -214,6 +215,7 @@ static uint64_t dchip_read(void *opaque, hwaddr addr, unsigned size)
 static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
 {
     TyphoonState *s = opaque;
+    CPUState *cs;
     uint64_t ret = 0;
 
     if (addr & 4) {
@@ -300,7 +302,8 @@ static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
         break;
 
     default:
-        cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, size);
+        cs = CPU(alpha_env_get_cpu(cpu_single_env));
+        cpu_unassigned_access(cs, addr, false, false, 0, size);
         return -1;
     }
 
@@ -312,6 +315,7 @@ static void cchip_write(void *opaque, hwaddr addr,
                         uint64_t v32, unsigned size)
 {
     TyphoonState *s = opaque;
+    CPUState *cpu_single_cpu = CPU(alpha_env_get_cpu(cpu_single_env));
     uint64_t val, oldval, newval;
 
     if (addr & 4) {
@@ -461,7 +465,7 @@ static void cchip_write(void *opaque, hwaddr addr,
         break;
 
     default:
-        cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, size);
+        cpu_unassigned_access(cpu_single_cpu, addr, true, false, 0, size);
         return;
     }
 }
@@ -476,6 +480,7 @@ static void pchip_write(void *opaque, hwaddr addr,
                         uint64_t v32, unsigned size)
 {
     TyphoonState *s = opaque;
+    CPUState *cs;
     uint64_t val, oldval;
 
     if (addr & 4) {
@@ -577,7 +582,8 @@ static void pchip_write(void *opaque, hwaddr addr,
         break;
 
     default:
-        cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, size);
+        cs = CPU(alpha_env_get_cpu(cpu_single_env));
+        cpu_unassigned_access(cs, addr, true, false, 0, size);
         return;
     }
 }
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index be2a0bd..7afc442 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -22,6 +22,7 @@
 
 #include <signal.h>
 #include "hw/qdev-core.h"
+#include "exec/hwaddr.h"
 #include "qemu/thread.h"
 #include "qemu/typedefs.h"
 
@@ -42,12 +43,17 @@ typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque);
 
 typedef struct CPUState CPUState;
 
+typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
+                                    bool is_write, bool is_exec, int opaque,
+                                    unsigned size);
+
 /**
  * CPUClass:
  * @class_by_name: Callback to map -cpu command line model name to an
  * instantiatable CPU type.
  * @reset: Callback to reset the #CPUState to its initial state.
  * @do_interrupt: Callback for interrupt handling.
+ * @do_unassigned_access: Callback for unassigned access handling.
  * @dump_state: Callback for dumping state.
  * @dump_statistics: Callback for dumping statistics.
  * @get_arch_id: Callback for getting architecture-dependent CPU ID.
@@ -66,6 +72,7 @@ typedef struct CPUClass {
 
     void (*reset)(CPUState *cpu);
     void (*do_interrupt)(CPUState *cpu);
+    CPUUnassignedAccess do_unassigned_access;
     void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                        int flags);
     void (*dump_statistics)(CPUState *cpu, FILE *f,
@@ -280,6 +287,17 @@ static inline void cpu_class_set_vmsd(CPUClass *cc,
 #define cpu_class_set_vmsd(cc, value) ((cc)->vmsd = NULL)
 #endif
 
+#ifndef CONFIG_USER_ONLY
+static inline void cpu_class_set_do_unassigned_access(CPUClass *cc,
+                                                      CPUUnassignedAccess value)
+{
+    cc->do_unassigned_access = value;
+}
+#else
+#define cpu_class_set_do_unassigned_access(cc, value) \
+    ((cc)->do_unassigned_access = NULL)
+#endif
+
 /**
  * qemu_cpu_has_work:
  * @cpu: The vCPU to check.
@@ -382,6 +400,21 @@ void cpu_interrupt(CPUState *cpu, int mask);
 
 #endif /* USER_ONLY */
 
+#ifndef CONFIG_USER_ONLY
+
+static inline void cpu_unassigned_access(CPUState *cpu, hwaddr addr,
+                                         bool is_write, bool is_exec,
+                                         int opaque, unsigned size)
+{
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    if (cc->do_unassigned_access) {
+        cc->do_unassigned_access(cpu, addr, is_write, is_exec, opaque, size);
+    }
+}
+
+#endif
+
 /**
  * cpu_reset_interrupt:
  * @cpu: The CPU to clear the interrupt on.
diff --git a/memory.c b/memory.c
index 5cb8f4a..3bc98ad 100644
--- a/memory.c
+++ b/memory.c
@@ -857,9 +857,10 @@ static uint64_t unassigned_mem_read(void *opaque, hwaddr addr,
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
 #endif
-#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
-    cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, size);
-#endif
+    if (cpu_single_env != NULL) {
+        cpu_unassigned_access(ENV_GET_CPU(cpu_single_env),
+                              addr, false, false, 0, size);
+    }
     return 0;
 }
 
@@ -869,9 +870,10 @@ static void unassigned_mem_write(void *opaque, hwaddr addr,
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val);
 #endif
-#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
-    cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, size);
-#endif
+    if (cpu_single_env != NULL) {
+        cpu_unassigned_access(ENV_GET_CPU(cpu_single_env),
+                              addr, true, false, 0, size);
+    }
 }
 
 static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index 7d5d6f9..71da1af 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -262,6 +262,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->class_by_name = alpha_cpu_class_by_name;
     cc->do_interrupt = alpha_cpu_do_interrupt;
     cc->dump_state = alpha_cpu_dump_state;
+    cpu_class_set_do_unassigned_access(cc, alpha_cpu_unassigned_access);
 }
 
 static const TypeInfo alpha_cpu_type_info = {
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 2156a1e..01f4ebb 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -457,9 +457,9 @@ uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env);
 void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val);
 #ifndef CONFIG_USER_ONLY
 void swap_shadow_regs(CPUAlphaState *env);
-QEMU_NORETURN void cpu_unassigned_access(CPUAlphaState *env1,
-                                         hwaddr addr, int is_write,
-                                         int is_exec, int unused, int size);
+QEMU_NORETURN void alpha_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
+                                               bool is_write, bool is_exec,
+                                               int unused, unsigned size);
 #endif
 
 /* Bits in TB->FLAGS that control how translation is processed.  */
diff --git a/target-alpha/mem_helper.c b/target-alpha/mem_helper.c
index 3d2cd61..7160a1c 100644
--- a/target-alpha/mem_helper.c
+++ b/target-alpha/mem_helper.c
@@ -109,11 +109,15 @@ static void do_unaligned_access(CPUAlphaState *env, target_ulong addr,
     cpu_loop_exit(env);
 }
 
-void cpu_unassigned_access(CPUAlphaState *env, hwaddr addr,
-                           int is_write, int is_exec, int unused, int size)
+void alpha_cpu_unassigned_access(CPUState *cs, hwaddr addr,
+                                 bool is_write, bool is_exec, int unused,
+                                 unsigned size)
 {
+    AlphaCPU *cpu = ALPHA_CPU(cs);
+    CPUAlphaState *env = &cpu->env;
+
     env->trap_arg0 = addr;
-    env->trap_arg1 = is_write;
+    env->trap_arg1 = is_write ? 1 : 0;
     dynamic_excp(env, 0, EXCP_MCHK, 0);
 }
 
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index b9a097c..a0fcdf4 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -138,8 +138,8 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->do_interrupt = mb_cpu_do_interrupt;
     cc->dump_state = mb_cpu_dump_state;
+    cpu_class_set_do_unassigned_access(cc, mb_cpu_unassigned_access);
     dc->vmsd = &vmstate_mb_cpu;
-
     dc->props = mb_properties;
 }
 
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 1813939..75ae5ba 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -367,8 +367,9 @@ static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc,
 }
 
 #if !defined(CONFIG_USER_ONLY)
-void cpu_unassigned_access(CPUMBState *env1, hwaddr addr,
-                           int is_write, int is_exec, int is_asi, int size);
+void mb_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
+                              bool is_write, bool is_exec, int is_asi,
+                              unsigned size);
 #endif
 
 static inline bool cpu_has_work(CPUState *cpu)
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index f2cb88b..14baa84 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -495,12 +495,21 @@ void helper_mmu_write(CPUMBState *env, uint32_t rn, uint32_t v)
     mmu_write(env, rn, v);
 }
 
-void cpu_unassigned_access(CPUMBState *env, hwaddr addr,
-                           int is_write, int is_exec, int is_asi, int size)
+void mb_cpu_unassigned_access(CPUState *cs, hwaddr addr,
+                              bool is_write, bool is_exec, int is_asi,
+                              unsigned size)
 {
+    MicroBlazeCPU *cpu;
+    CPUMBState *env;
+
     qemu_log_mask(CPU_LOG_INT, "Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n",
-             addr, is_write, is_exec);
-    if (!env || !(env->sregs[SR_MSR] & MSR_EE)) {
+             addr, is_write ? 1 : 0, is_exec ? 1 : 0);
+    if (cs == NULL) {
+        return;
+    }
+    cpu = MICROBLAZE_CPU(cs);
+    env = &cpu->env;
+    if (!(env->sregs[SR_MSR] & MSR_EE)) {
         return;
     }
 
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 0fdc316..b61e207 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -80,6 +80,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
 
     cc->do_interrupt = mips_cpu_do_interrupt;
     cc->dump_state = mips_cpu_dump_state;
+    cpu_class_set_do_unassigned_access(cc, mips_cpu_unassigned_access);
 }
 
 static const TypeInfo mips_cpu_type_info = {
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 6e761e0..fa0f0d1 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -493,8 +493,9 @@ void r4k_helper_tlbwr(CPUMIPSState *env);
 void r4k_helper_tlbp(CPUMIPSState *env);
 void r4k_helper_tlbr(CPUMIPSState *env);
 
-void cpu_unassigned_access(CPUMIPSState *env, hwaddr addr,
-                           int is_write, int is_exec, int unused, int size);
+void mips_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
+                                bool is_write, bool is_exec, int unused,
+                                unsigned size);
 #endif
 
 void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf);
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 3fa0d00..f6838ec 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2147,13 +2147,18 @@ void tlb_fill(CPUMIPSState *env, target_ulong addr, int is_write, int mmu_idx,
     }
 }
 
-void cpu_unassigned_access(CPUMIPSState *env, hwaddr addr,
-                           int is_write, int is_exec, int unused, int size)
+void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr,
+                                bool is_write, bool is_exec, int unused,
+                                unsigned size)
 {
-    if (is_exec)
+    MIPSCPU *cpu = MIPS_CPU(cs);
+    CPUMIPSState *env = &cpu->env;
+
+    if (is_exec) {
         helper_raise_exception(env, EXCP_IBE);
-    else
+    } else {
         helper_raise_exception(env, EXCP_DBE);
+    }
 }
 #endif /* !CONFIG_USER_ONLY */
 
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index ff1200c..65ae6f7 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -771,6 +771,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->do_interrupt = sparc_cpu_do_interrupt;
     cc->dump_state = sparc_cpu_dump_state;
+    cpu_class_set_do_unassigned_access(cc, sparc_cpu_unassigned_access);
 }
 
 static const TypeInfo sparc_cpu_type_info = {
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 6fa7778..021eb157 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -582,8 +582,9 @@ static inline int tlb_compare_context(const SparcTLBEntry *tlb,
 
 /* cpu-exec.c */
 #if !defined(CONFIG_USER_ONLY)
-void cpu_unassigned_access(CPUSPARCState *env1, hwaddr addr,
-                           int is_write, int is_exec, int is_asi, int size);
+void sparc_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
+                                 bool is_write, bool is_exec, int is_asi,
+                                 unsigned size);
 #if defined(TARGET_SPARC64)
 hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr,
                                            int mmu_idx);
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 6d767fb..2936b58 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -686,7 +686,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
         break;
     case 8: /* User code access, XXX */
     default:
-        cpu_unassigned_access(env, addr, 0, 0, asi, size);
+        cpu_unassigned_access(CPU(sparc_env_get_cpu(env)),
+                              addr, false, false, asi, size);
         ret = 0;
         break;
     }
@@ -1088,7 +1089,8 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val, int asi,
     case 8: /* User code access, XXX */
     case 9: /* Supervisor code access, XXX */
     default:
-        cpu_unassigned_access(env, addr, 1, 0, asi, size);
+        cpu_unassigned_access(CPU(sparc_env_get_cpu(env)),
+                              addr, true, false, asi, size);
         break;
     }
 #ifdef DEBUG_ASI
@@ -1594,7 +1596,8 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
     case 0x5f: /* D-MMU demap, WO */
     case 0x77: /* Interrupt vector, WO */
     default:
-        cpu_unassigned_access(env, addr, 0, 0, 1, size);
+        cpu_unassigned_access(CPU(sparc_env_get_cpu(env)),
+                              addr, false, false, 1, size);
         ret = 0;
         break;
     }
@@ -2027,7 +2030,8 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
     case 0x8a: /* Primary no-fault LE, RO */
     case 0x8b: /* Secondary no-fault LE, RO */
     default:
-        cpu_unassigned_access(env, addr, 1, 0, 1, size);
+        cpu_unassigned_access(CPU(sparc_env_get_cpu(env)),
+                              addr, true, false, 1, size);
         return;
     }
 }
@@ -2322,9 +2326,12 @@ void helper_stqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
 
 #if !defined(CONFIG_USER_ONLY)
 #ifndef TARGET_SPARC64
-void cpu_unassigned_access(CPUSPARCState *env, hwaddr addr,
-                           int is_write, int is_exec, int is_asi, int size)
+void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr,
+                                 bool is_write, bool is_exec, int is_asi,
+                                 unsigned size)
 {
+    SPARCCPU *cpu = SPARC_CPU(cs);
+    CPUSPARCState *env = &cpu->env;
     int fault_type;
 
 #ifdef DEBUG_UNASSIGNED
@@ -2382,9 +2389,13 @@ void cpu_unassigned_access(CPUSPARCState *env, hwaddr addr,
     }
 }
 #else
-void cpu_unassigned_access(CPUSPARCState *env, hwaddr addr,
-                           int is_write, int is_exec, int is_asi, int size)
+void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr,
+                                 bool is_write, bool is_exec, int is_asi,
+                                 unsigned size)
 {
+    SPARCCPU *cpu = SPARC_CPU(cs);
+    CPUSPARCState *env = &cpu->env;
+
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
            "\n", addr, env->pc);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (17 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 18/29] cpu: Turn cpu_unassigned_access() into a CPUState hook Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-16 20:49   ` Blue Swirl
                     ` (2 more replies)
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
                   ` (10 subsequent siblings)
  29 siblings, 3 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Anthony Liguori, Alexander Graf, Blue Swirl,
	Andreas Färber, Hervé Poussineau, Paul Brook,
	Scott Wood, open list:mpc8544ds, Andreas Färber,
	Aurelien Jarno, Richard Henderson

Move it to qom/cpu.h.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpu-exec.c              | 13 +++++++------
 cpus.c                  | 29 ++++++++++++++---------------
 exec.c                  | 12 +++++++-----
 hw/alpha/typhoon.c      | 16 ++++------------
 hw/arm/pxa2xx.c         |  3 +--
 hw/i386/kvmvapic.c      |  6 ++++--
 hw/i386/pc.c            | 11 ++++++-----
 hw/intc/arm_gic.c       |  3 +--
 hw/intc/armv7m_nvic.c   | 11 ++++++++---
 hw/intc/openpic.c       |  5 +----
 hw/mips/mips_fulong2e.c |  6 +++---
 hw/mips/mips_jazz.c     |  6 +++---
 hw/mips/mips_malta.c    |  6 +++---
 hw/misc/vmport.c        | 26 ++++++++++++++++----------
 hw/ppc/mpc8544_guts.c   |  3 ++-
 hw/ppc/prep.c           |  6 +++---
 hw/sparc/sun4m.c        |  5 ++---
 hw/timer/arm_mptimer.c  |  2 --
 include/exec/cpu-all.h  |  3 ---
 include/qom/cpu.h       |  4 ++++
 memory.c                | 10 ++++------
 translate-all.c         | 20 ++++++++++++--------
 user-exec.c             |  9 +++++----
 23 files changed, 110 insertions(+), 105 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index ec46380..1858c2e 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -213,12 +213,12 @@ int cpu_exec(CPUArchState *env)
         cpu->halted = 0;
     }
 
-    cpu_single_env = env;
+    cpu_single_cpu = cpu;
 
-    /* As long as cpu_single_env is null, up to the assignment just above,
+    /* As long as cpu_single_cpu is null, up to the assignment just above,
      * requests by other threads to exit the execution loop are expected to
      * be issued using the exit_request global. We must make sure that our
-     * evaluation of the global value is performed past the cpu_single_env
+     * evaluation of the global value is performed past the cpu_single_cpu
      * value transition point, which requires a memory barrier as well as
      * an instruction scheduling constraint on modern architectures.  */
     smp_mb();
@@ -673,7 +673,8 @@ int cpu_exec(CPUArchState *env)
         } else {
             /* Reload env after longjmp - the compiler may have smashed all
              * local variables as longjmp is marked 'noreturn'. */
-            env = cpu_single_env;
+            cpu = cpu_single_cpu;
+            env = cpu->env_ptr;
         }
     } /* for(;;) */
 
@@ -707,7 +708,7 @@ int cpu_exec(CPUArchState *env)
 #error unsupported target CPU
 #endif
 
-    /* fail safe : never use cpu_single_env outside cpu_exec() */
-    cpu_single_env = NULL;
+    /* fail safe : never use cpu_single_cpu outside cpu_exec() */
+    cpu_single_cpu = NULL;
     return ret;
 }
diff --git a/cpus.c b/cpus.c
index 775d998..808503b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -118,10 +118,11 @@ TimersState timers_state;
 int64_t cpu_get_icount(void)
 {
     int64_t icount;
-    CPUArchState *env = cpu_single_env;
+    CPUState *cpu = cpu_single_cpu;
 
     icount = qemu_icount;
-    if (env) {
+    if (cpu) {
+        CPUArchState *env = cpu->env_ptr;
         if (!can_do_io(env)) {
             fprintf(stderr, "Bad clock read\n");
         }
@@ -468,8 +469,8 @@ static void cpu_handle_guest_debug(CPUState *cpu)
 
 static void cpu_signal(int sig)
 {
-    if (cpu_single_env) {
-        cpu_exit(ENV_GET_CPU(cpu_single_env));
+    if (cpu_single_cpu) {
+        cpu_exit(cpu_single_cpu);
     }
     exit_request = 1;
 }
@@ -660,10 +661,10 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)
 
     qemu_cpu_kick(cpu);
     while (!wi.done) {
-        CPUArchState *self_env = cpu_single_env;
+        CPUState *self_cpu = cpu_single_cpu;
 
         qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex);
-        cpu_single_env = self_env;
+        cpu_single_cpu = self_cpu;
     }
 }
 
@@ -733,7 +734,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
     qemu_mutex_lock(&qemu_global_mutex);
     qemu_thread_get_self(cpu->thread);
     cpu->thread_id = qemu_get_thread_id();
-    cpu_single_env = cpu->env_ptr;
+    cpu_single_cpu = cpu;
 
     r = kvm_init_vcpu(cpu);
     if (r < 0) {
@@ -781,9 +782,9 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
     cpu->created = true;
     qemu_cond_signal(&qemu_cpu_cond);
 
-    cpu_single_env = cpu->env_ptr;
+    cpu_single_cpu = cpu;
     while (1) {
-        cpu_single_env = NULL;
+        cpu_single_cpu = NULL;
         qemu_mutex_unlock_iothread();
         do {
             int sig;
@@ -794,7 +795,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
             exit(1);
         }
         qemu_mutex_lock_iothread();
-        cpu_single_env = cpu->env_ptr;
+        cpu_single_cpu = cpu;
         qemu_wait_io_event_common(cpu);
     }
 
@@ -894,8 +895,7 @@ void qemu_cpu_kick(CPUState *cpu)
 void qemu_cpu_kick_self(void)
 {
 #ifndef _WIN32
-    assert(cpu_single_env);
-    CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
+    assert(cpu_single_cpu);
 
     if (!cpu_single_cpu->thread_kicked) {
         qemu_cpu_kick_thread(cpu_single_cpu);
@@ -913,7 +913,7 @@ bool qemu_cpu_is_self(CPUState *cpu)
 
 static bool qemu_in_vcpu_thread(void)
 {
-    return cpu_single_env && qemu_cpu_is_self(ENV_GET_CPU(cpu_single_env));
+    return cpu_single_cpu && qemu_cpu_is_self(cpu_single_cpu);
 }
 
 void qemu_mutex_lock_iothread(void)
@@ -1069,8 +1069,7 @@ void qemu_init_vcpu(CPUState *cpu)
 
 void cpu_stop_current(void)
 {
-    if (cpu_single_env) {
-        CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
+    if (cpu_single_cpu) {
         cpu_single_cpu->stop = false;
         cpu_single_cpu->stopped = true;
         cpu_exit(cpu_single_cpu);
diff --git a/exec.c b/exec.c
index 2b99bb9..e14a815 100644
--- a/exec.c
+++ b/exec.c
@@ -73,7 +73,7 @@ static MemoryRegion io_mem_unassigned, io_mem_subpage_ram;
 CPUArchState *first_cpu;
 /* current CPU in the current thread. It is only valid inside
    cpu_exec() */
-DEFINE_TLS(CPUArchState *,cpu_single_env);
+DEFINE_TLS(CPUState *,cpu_single_cpu);
 /* 0 = Do not count executed instructions.
    1 = Precise instruction counting.
    2 = Adaptive rate instruction counting.  */
@@ -1420,8 +1420,10 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
     cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
     /* we remove the notdirty callback only if the code has been
        flushed */
-    if (dirty_flags == 0xff)
-        tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
+    if (dirty_flags == 0xff) {
+        CPUArchState *env = cpu_single_cpu->env_ptr;
+        tlb_set_dirty(env, env->mem_io_vaddr);
+    }
 }
 
 static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
@@ -1439,7 +1441,7 @@ static const MemoryRegionOps notdirty_mem_ops = {
 /* Generate a debug exception if a watchpoint has been hit.  */
 static void check_watchpoint(int offset, int len_mask, int flags)
 {
-    CPUArchState *env = cpu_single_env;
+    CPUArchState *env = cpu_single_cpu->env_ptr;
     target_ulong pc, cs_base;
     target_ulong vaddr;
     CPUWatchpoint *wp;
@@ -1912,7 +1914,7 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
         if (is_write) {
             if (!memory_access_is_direct(section->mr, is_write)) {
                 l = memory_access_size(l, addr1);
-                /* XXX: could force cpu_single_env to NULL to avoid
+                /* XXX: could force cpu_single_cpu to NULL to avoid
                    potential bugs */
                 if (l == 4) {
                     /* 32 bit write access */
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index 207dcad..f0b1f6f 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -72,9 +72,8 @@ static void cpu_irq_change(AlphaCPU *cpu, uint64_t req)
 
 static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
 {
-    CPUAlphaState *env = cpu_single_env;
+    CPUState *cpu = cpu_single_cpu;
     TyphoonState *s = opaque;
-    CPUState *cpu;
     uint64_t ret = 0;
 
     if (addr & 4) {
@@ -95,7 +94,6 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
 
     case 0x0080:
         /* MISC: Miscellaneous Register.  */
-        cpu = ENV_GET_CPU(env);
         ret = s->cchip.misc | (cpu->cpu_index & 3);
         break;
 
@@ -197,8 +195,7 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
         break;
 
     default:
-        cpu = CPU(alpha_env_get_cpu(cpu_single_env));
-        cpu_unassigned_access(cpu, addr, false, false, 0, size);
+        cpu_unassigned_access(cpu_single_cpu, addr, false, false, 0, size);
         return -1;
     }
 
@@ -215,7 +212,6 @@ static uint64_t dchip_read(void *opaque, hwaddr addr, unsigned size)
 static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
 {
     TyphoonState *s = opaque;
-    CPUState *cs;
     uint64_t ret = 0;
 
     if (addr & 4) {
@@ -302,8 +298,7 @@ static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
         break;
 
     default:
-        cs = CPU(alpha_env_get_cpu(cpu_single_env));
-        cpu_unassigned_access(cs, addr, false, false, 0, size);
+        cpu_unassigned_access(cpu_single_cpu, addr, false, false, 0, size);
         return -1;
     }
 
@@ -315,7 +310,6 @@ static void cchip_write(void *opaque, hwaddr addr,
                         uint64_t v32, unsigned size)
 {
     TyphoonState *s = opaque;
-    CPUState *cpu_single_cpu = CPU(alpha_env_get_cpu(cpu_single_env));
     uint64_t val, oldval, newval;
 
     if (addr & 4) {
@@ -480,7 +474,6 @@ static void pchip_write(void *opaque, hwaddr addr,
                         uint64_t v32, unsigned size)
 {
     TyphoonState *s = opaque;
-    CPUState *cs;
     uint64_t val, oldval;
 
     if (addr & 4) {
@@ -582,8 +575,7 @@ static void pchip_write(void *opaque, hwaddr addr,
         break;
 
     default:
-        cs = CPU(alpha_env_get_cpu(cpu_single_env));
-        cpu_unassigned_access(cs, addr, true, false, 0, size);
+        cpu_unassigned_access(cpu_single_cpu, addr, true, false, 0, size);
         return;
     }
 }
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 24b03a0..d023167 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -301,8 +301,7 @@ static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
 #endif
 
         /* Suspend */
-        cpu_interrupt(CPU(arm_env_get_cpu(cpu_single_env)),
-                      CPU_INTERRUPT_HALT);
+        cpu_interrupt(cpu_single_cpu, CPU_INTERRUPT_HALT);
 
         goto message;
 
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index f93629f..9aac9de 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -623,11 +623,13 @@ static int vapic_prepare(VAPICROMState *s)
 static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
                         unsigned int size)
 {
-    CPUX86State *env = cpu_single_env;
+    CPUState *cs = cpu_single_cpu;
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
     hwaddr rom_paddr;
     VAPICROMState *s = opaque;
 
-    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
+    cpu_synchronize_state(cs);
 
     /*
      * The VAPIC supports two PIO-based hypercalls, both via port 0x7E.
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index d7e8507..c43be54 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -887,8 +887,9 @@ void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd)
 
 DeviceState *cpu_get_current_apic(void)
 {
-    if (cpu_single_env) {
-        return cpu_single_env->apic_state;
+    if (cpu_single_cpu) {
+        X86CPU *cpu = X86_CPU(cpu_single_cpu);
+        return cpu->env.apic_state;
     } else {
         return NULL;
     }
@@ -1107,10 +1108,10 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
 
 static void cpu_request_exit(void *opaque, int irq, int level)
 {
-    CPUX86State *env = cpu_single_env;
+    CPUState *cpu = cpu_single_cpu;
 
-    if (env && level) {
-        cpu_exit(CPU(x86_env_get_cpu(env)));
+    if (cpu && level) {
+        cpu_exit(cpu);
     }
 }
 
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index bae6572..79fd4a9 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -39,8 +39,7 @@ static const uint8_t gic_id[] = {
 static inline int gic_get_current_cpu(GICState *s)
 {
     if (s->num_cpu > 1) {
-        CPUState *cpu = ENV_GET_CPU(cpu_single_env);
-        return cpu->cpu_index;
+        return cpu_single_cpu->cpu_index;
     }
     return 0;
 }
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 25fa43c..53576c8 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -140,6 +140,7 @@ void armv7m_nvic_complete_irq(void *opaque, int irq)
 
 static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
 {
+    ARMCPU *cpu;
     uint32_t val;
     int irq;
 
@@ -171,7 +172,8 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
     case 0x1c: /* SysTick Calibration Value.  */
         return 10000;
     case 0xd00: /* CPUID Base.  */
-        return cpu_single_env->cp15.c0_cpuid;
+        cpu = ARM_CPU(cpu_single_cpu);
+        return cpu->env.cp15.c0_cpuid;
     case 0xd04: /* Interrupt Control State.  */
         /* VECTACTIVE */
         val = s->gic.running_irq[0];
@@ -206,7 +208,8 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
             val |= (1 << 31);
         return val;
     case 0xd08: /* Vector Table Offset.  */
-        return cpu_single_env->v7m.vecbase;
+        cpu = ARM_CPU(cpu_single_cpu);
+        return cpu->env.v7m.vecbase;
     case 0xd0c: /* Application Interrupt/Reset Control.  */
         return 0xfa05000;
     case 0xd10: /* System Control.  */
@@ -279,6 +282,7 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
 
 static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)
 {
+    ARMCPU *cpu;
     uint32_t oldval;
     switch (offset) {
     case 0x10: /* SysTick Control and Status.  */
@@ -331,7 +335,8 @@ static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)
         }
         break;
     case 0xd08: /* Vector Table Offset.  */
-        cpu_single_env->v7m.vecbase = value & 0xffffff80;
+        cpu = ARM_CPU(cpu_single_cpu);
+        cpu->env.v7m.vecbase = value & 0xffffff80;
         break;
     case 0xd0c: /* Application Interrupt/Reset Control.  */
         if ((value >> 16) == 0x05fa) {
diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c
index c788714..6f152e0 100644
--- a/hw/intc/openpic.c
+++ b/hw/intc/openpic.c
@@ -184,13 +184,10 @@ static int output_to_inttgt(int output)
 
 static int get_current_cpu(void)
 {
-    CPUState *cpu_single_cpu;
-
-    if (!cpu_single_env) {
+    if (!cpu_single_cpu) {
         return -1;
     }
 
-    cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
     return cpu_single_cpu->cpu_index;
 }
 
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index 00c9071..59ee1b4 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -250,10 +250,10 @@ static void network_init (void)
 
 static void cpu_request_exit(void *opaque, int irq, int level)
 {
-    CPUMIPSState *env = cpu_single_env;
+    CPUState *cpu = cpu_single_cpu;
 
-    if (env && level) {
-        cpu_exit(CPU(mips_env_get_cpu(env)));
+    if (cpu && level) {
+        cpu_exit(cpu);
     }
 }
 
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 2ad0c0b..2ffae59 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -99,10 +99,10 @@ static const MemoryRegionOps dma_dummy_ops = {
 
 static void cpu_request_exit(void *opaque, int irq, int level)
 {
-    CPUMIPSState *env = cpu_single_env;
+    CPUState *cpu = cpu_single_cpu;
 
-    if (env && level) {
-        cpu_exit(CPU(mips_env_get_cpu(env)));
+    if (cpu && level) {
+        cpu_exit(cpu);
     }
 }
 
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 8a4459d..4fc611c 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -770,10 +770,10 @@ static void main_cpu_reset(void *opaque)
 
 static void cpu_request_exit(void *opaque, int irq, int level)
 {
-    CPUMIPSState *env = cpu_single_env;
+    CPUState *cpu = cpu_single_cpu;
 
-    if (env && level) {
-        cpu_exit(CPU(mips_env_get_cpu(env)));
+    if (cpu && level) {
+        cpu_exit(cpu);
     }
 }
 
diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c
index 8363dfd..deb2232 100644
--- a/hw/misc/vmport.c
+++ b/hw/misc/vmport.c
@@ -62,11 +62,13 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
                                    unsigned size)
 {
     VMPortState *s = opaque;
-    CPUX86State *env = cpu_single_env;
+    CPUState *cs = cpu_single_cpu;
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
     unsigned char command;
     uint32_t eax;
 
-    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
+    cpu_synchronize_state(cs);
 
     eax = env->regs[R_EAX];
     if (eax != VMPORT_MAGIC)
@@ -89,29 +91,32 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
 static void vmport_ioport_write(void *opaque, hwaddr addr,
                                 uint64_t val, unsigned size)
 {
-    CPUX86State *env = cpu_single_env;
+    X86CPU *cpu = X86_CPU(cpu_single_cpu);
 
-    env->regs[R_EAX] = vmport_ioport_read(opaque, addr, 4);
+    cpu->env.regs[R_EAX] = vmport_ioport_read(opaque, addr, 4);
 }
 
 static uint32_t vmport_cmd_get_version(void *opaque, uint32_t addr)
 {
-    CPUX86State *env = cpu_single_env;
-    env->regs[R_EBX] = VMPORT_MAGIC;
+    X86CPU *cpu = X86_CPU(cpu_single_cpu);
+
+    cpu->env.regs[R_EBX] = VMPORT_MAGIC;
     return 6;
 }
 
 static uint32_t vmport_cmd_ram_size(void *opaque, uint32_t addr)
 {
-    CPUX86State *env = cpu_single_env;
-    env->regs[R_EBX] = 0x1177;
+    X86CPU *cpu = X86_CPU(cpu_single_cpu);
+
+    cpu->env.regs[R_EBX] = 0x1177;
     return ram_size;
 }
 
 /* vmmouse helpers */
 void vmmouse_get_data(uint32_t *data)
 {
-    CPUX86State *env = cpu_single_env;
+    X86CPU *cpu = X86_CPU(cpu_single_cpu);
+    CPUX86State *env = &cpu->env;
 
     data[0] = env->regs[R_EAX]; data[1] = env->regs[R_EBX];
     data[2] = env->regs[R_ECX]; data[3] = env->regs[R_EDX];
@@ -120,7 +125,8 @@ void vmmouse_get_data(uint32_t *data)
 
 void vmmouse_set_data(const uint32_t *data)
 {
-    CPUX86State *env = cpu_single_env;
+    X86CPU *cpu = X86_CPU(cpu_single_cpu);
+    CPUX86State *env = &cpu->env;
 
     env->regs[R_EAX] = data[0]; env->regs[R_EBX] = data[1];
     env->regs[R_ECX] = data[2]; env->regs[R_EDX] = data[3];
diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c
index 193beab..89f950f 100644
--- a/hw/ppc/mpc8544_guts.c
+++ b/hw/ppc/mpc8544_guts.c
@@ -62,7 +62,8 @@ static uint64_t mpc8544_guts_read(void *opaque, hwaddr addr,
                                   unsigned size)
 {
     uint32_t value = 0;
-    CPUPPCState *env = cpu_single_env;
+    PowerPCCPU *cpu = POWERPC_CPU(cpu_single_cpu);
+    CPUPPCState *env = &cpu->env;
 
     addr &= MPC8544_GUTS_MMIO_SIZE - 1;
     switch (addr) {
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 90828f2..16e3132 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -417,10 +417,10 @@ static const MemoryRegionOps PPC_prep_io_ops = {
 
 static void cpu_request_exit(void *opaque, int irq, int level)
 {
-    CPUPPCState *env = cpu_single_env;
+    CPUState *cpu = cpu_single_cpu;
 
-    if (env && level) {
-        cpu_exit(CPU(ppc_env_get_cpu(env)));
+    if (cpu && level) {
+        cpu_exit(cpu);
     }
 }
 
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 0e86ca7..1273533 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -264,9 +264,8 @@ static void secondary_cpu_reset(void *opaque)
 
 static void cpu_halt_signal(void *opaque, int irq, int level)
 {
-    if (level && cpu_single_env) {
-        cpu_interrupt(CPU(sparc_env_get_cpu(cpu_single_env)),
-                      CPU_INTERRUPT_HALT);
+    if (level && cpu_single_cpu) {
+        cpu_interrupt(cpu_single_cpu, CPU_INTERRUPT_HALT);
     }
 }
 
diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
index 317f5e4..1aa300b 100644
--- a/hw/timer/arm_mptimer.c
+++ b/hw/timer/arm_mptimer.c
@@ -49,8 +49,6 @@ typedef struct {
 
 static inline int get_current_cpu(ARMMPTimerState *s)
 {
-    CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
-
     if (cpu_single_cpu->cpu_index >= s->num_cpu) {
         hw_error("arm_mptimer: num-cpu %d but this cpu is %d!\n",
                  s->num_cpu, cpu_single_cpu->cpu_index);
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 35bdf85..6760851 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -20,7 +20,6 @@
 #define CPU_ALL_H
 
 #include "qemu-common.h"
-#include "qemu/tls.h"
 #include "exec/cpu-common.h"
 #include "qemu/thread.h"
 
@@ -358,8 +357,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
 void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 extern CPUArchState *first_cpu;
-DECLARE_TLS(CPUArchState *,cpu_single_env);
-#define cpu_single_env tls_var(cpu_single_env)
 
 /* Flags for use in ENV->INTERRUPT_PENDING.
 
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 7afc442..0e2e76c 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -24,6 +24,7 @@
 #include "hw/qdev-core.h"
 #include "exec/hwaddr.h"
 #include "qemu/thread.h"
+#include "qemu/tls.h"
 #include "qemu/typedefs.h"
 
 typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque);
@@ -156,6 +157,9 @@ struct CPUState {
     uint32_t halted; /* used by alpha, cris, ppc TCG */
 };
 
+DECLARE_TLS(CPUState *, cpu_single_cpu);
+#define cpu_single_cpu tls_var(cpu_single_cpu)
+
 /**
  * cpu_paging_enabled:
  * @cpu: The CPU whose state is to be inspected.
diff --git a/memory.c b/memory.c
index 3bc98ad..f960bd0 100644
--- a/memory.c
+++ b/memory.c
@@ -857,9 +857,8 @@ static uint64_t unassigned_mem_read(void *opaque, hwaddr addr,
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
 #endif
-    if (cpu_single_env != NULL) {
-        cpu_unassigned_access(ENV_GET_CPU(cpu_single_env),
-                              addr, false, false, 0, size);
+    if (cpu_single_cpu != NULL) {
+        cpu_unassigned_access(cpu_single_cpu, addr, false, false, 0, size);
     }
     return 0;
 }
@@ -870,9 +869,8 @@ static void unassigned_mem_write(void *opaque, hwaddr addr,
 #ifdef DEBUG_UNASSIGNED
     printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val);
 #endif
-    if (cpu_single_env != NULL) {
-        cpu_unassigned_access(ENV_GET_CPU(cpu_single_env),
-                              addr, true, false, 0, size);
+    if (cpu_single_cpu != NULL) {
+        cpu_unassigned_access(cpu_single_cpu, addr, true, false, 0, size);
     }
 }
 
diff --git a/translate-all.c b/translate-all.c
index df7c697..4177293 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -999,8 +999,10 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
                                    int is_cpu_write_access)
 {
     TranslationBlock *tb, *tb_next, *saved_tb;
-    CPUArchState *env = cpu_single_env;
-    CPUState *cpu = NULL;
+    CPUState *cpu = cpu_single_cpu;
+#if defined(TARGET_HAS_PRECISE_SMC) || !defined(CONFIG_USER_ONLY)
+    CPUArchState *env = NULL;
+#endif
     tb_page_addr_t tb_start, tb_end;
     PageDesc *p;
     int n;
@@ -1023,9 +1025,11 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
         /* build code bitmap */
         build_page_bitmap(p);
     }
-    if (env != NULL) {
-        cpu = ENV_GET_CPU(env);
+#if defined(TARGET_HAS_PRECISE_SMC) || !defined(CONFIG_USER_ONLY)
+    if (cpu != NULL) {
+        env = cpu->env_ptr;
     }
+#endif
 
     /* we remove all the TBs in the range [start, end[ */
     /* XXX: see if in some cases it could be faster to invalidate all
@@ -1147,8 +1151,8 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr,
     int n;
 #ifdef TARGET_HAS_PRECISE_SMC
     TranslationBlock *current_tb = NULL;
-    CPUArchState *env = cpu_single_env;
-    CPUState *cpu = NULL;
+    CPUState *cpu = cpu_single_cpu;
+    CPUArchState *env = NULL;
     int current_tb_modified = 0;
     target_ulong current_pc = 0;
     target_ulong current_cs_base = 0;
@@ -1165,8 +1169,8 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr,
     if (tb && pc != 0) {
         current_tb = tb_find_pc(pc);
     }
-    if (env != NULL) {
-        cpu = ENV_GET_CPU(env);
+    if (cpu != NULL) {
+        env = cpu->env_ptr;
     }
 #endif
     while (tb != NULL) {
diff --git a/user-exec.c b/user-exec.c
index fa7f1f1..aebdf1e 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -81,6 +81,7 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
                                     int is_write, sigset_t *old_set,
                                     void *puc)
 {
+    CPUArchState *env;
     int ret;
 
 #if defined(DEBUG_SIGNAL)
@@ -93,9 +94,9 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
         return 1;
     }
 
+    env = cpu_single_cpu->env_ptr;
     /* see if it is an MMU fault */
-    ret = cpu_handle_mmu_fault(cpu_single_env, address, is_write,
-                               MMU_USER_IDX);
+    ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX);
     if (ret < 0) {
         return 0; /* not an MMU fault */
     }
@@ -103,12 +104,12 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
         return 1; /* the MMU fault was handled without causing real CPU fault */
     }
     /* now we have a real cpu fault */
-    cpu_restore_state(cpu_single_env, pc);
+    cpu_restore_state(env, pc);
 
     /* we restore the process signal mask as the sigreturn should
        do it (XXX: use sigsetjmp) */
     sigprocmask(SIG_SETMASK, old_set, NULL);
-    exception_action(cpu_single_env);
+    exception_action(env);
 
     /* never comes here */
     return 1;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH qom-cpu v2 20/29] kvm: Change kvm_remove_all_breakpoints() argument to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
@ 2013-06-16 15:57   ` Andreas Färber
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
                     ` (28 subsequent siblings)
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Andreas Färber, Gleb Natapov, Marcelo Tosatti, open list:Overall

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c            | 2 +-
 include/sysemu/kvm.h | 2 +-
 kvm-all.c            | 5 ++---
 kvm-stub.c           | 2 +-
 4 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 3101a43..9e7f7a1 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2019,7 +2019,7 @@ static void gdb_breakpoint_remove_all(void)
     CPUArchState *env;
 
     if (kvm_enabled()) {
-        kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
+        kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu));
         return;
     }
 
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index fe8bc40..c767488 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -163,7 +163,7 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
                           target_ulong len, int type);
 int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
                           target_ulong len, int type);
-void kvm_remove_all_breakpoints(CPUArchState *current_env);
+void kvm_remove_all_breakpoints(CPUState *current_cpu);
 int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
 #ifndef _WIN32
 int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset);
diff --git a/kvm-all.c b/kvm-all.c
index 90b89cd..b3ba6aa 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1979,9 +1979,8 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
     return 0;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *current_env)
+void kvm_remove_all_breakpoints(CPUState *current_cpu)
 {
-    CPUState *current_cpu = ENV_GET_CPU(current_env);
     struct kvm_sw_breakpoint *bp, *next;
     KVMState *s = current_cpu->kvm_state;
     CPUArchState *env;
@@ -2026,7 +2025,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *current_env)
+void kvm_remove_all_breakpoints(CPUState *current_cpu)
 {
 }
 #endif /* !KVM_CAP_SET_GUEST_DEBUG */
diff --git a/kvm-stub.c b/kvm-stub.c
index 5457fe8..f614f92 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -95,7 +95,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *current_env)
+void kvm_remove_all_breakpoints(CPUState *current_cpu)
 {
 }
 
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 20/29] kvm: Change kvm_remove_all_breakpoints() argument to CPUState
@ 2013-06-16 15:57   ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marcelo Tosatti, Andreas Färber, Gleb Natapov, open list:Overall

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c            | 2 +-
 include/sysemu/kvm.h | 2 +-
 kvm-all.c            | 5 ++---
 kvm-stub.c           | 2 +-
 4 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 3101a43..9e7f7a1 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2019,7 +2019,7 @@ static void gdb_breakpoint_remove_all(void)
     CPUArchState *env;
 
     if (kvm_enabled()) {
-        kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
+        kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu));
         return;
     }
 
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index fe8bc40..c767488 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -163,7 +163,7 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
                           target_ulong len, int type);
 int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
                           target_ulong len, int type);
-void kvm_remove_all_breakpoints(CPUArchState *current_env);
+void kvm_remove_all_breakpoints(CPUState *current_cpu);
 int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
 #ifndef _WIN32
 int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset);
diff --git a/kvm-all.c b/kvm-all.c
index 90b89cd..b3ba6aa 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1979,9 +1979,8 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
     return 0;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *current_env)
+void kvm_remove_all_breakpoints(CPUState *current_cpu)
 {
-    CPUState *current_cpu = ENV_GET_CPU(current_env);
     struct kvm_sw_breakpoint *bp, *next;
     KVMState *s = current_cpu->kvm_state;
     CPUArchState *env;
@@ -2026,7 +2025,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *current_env)
+void kvm_remove_all_breakpoints(CPUState *current_cpu)
 {
 }
 #endif /* !KVM_CAP_SET_GUEST_DEBUG */
diff --git a/kvm-stub.c b/kvm-stub.c
index 5457fe8..f614f92 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -95,7 +95,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *current_env)
+void kvm_remove_all_breakpoints(CPUState *current_cpu)
 {
 }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [PATCH qom-cpu v2 21/29] cpu: Make first_cpu and next_cpu CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
@ 2013-06-16 15:57   ` Andreas Färber
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
                     ` (28 subsequent siblings)
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Andreas Färber, Paul Brook, Peter Maydell, Evgeny Voevodin,
	Maksim Kozlov, Igor Mitsyanko, Dmitry Solodkiy, Mark Langsdorf,
	Peter Crosthwaite, Edgar E. Iglesias, Anthony Liguori,
	Aurelien Jarno, Alexander Graf, Andreas Färber,
	David Gibson, Gleb Natapov, Marcelo Tosatti, Riku Voipio,
	Luiz Capitulino, open list:PowerPC

Move first_cpu to qom/cpu.h.

gdbstub needs to use CPUState::env_ptr for now.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c                    | 126 ++++++++++++++++++++++++----------------------
 cputlb.c                  |   4 +-
 dump.c                    |  16 +++---
 exec.c                    |  43 ++++++++--------
 gdbstub.c                 |  33 +++++++-----
 hw/arm/boot.c             |  10 ++--
 hw/arm/exynos4_boards.c   |   4 +-
 hw/arm/highbank.c         |   2 +-
 hw/arm/realview.c         |   2 +-
 hw/arm/vexpress.c         |   2 +-
 hw/arm/xilinx_zynq.c      |   2 +-
 hw/i386/kvm/clock.c       |  12 +++--
 hw/i386/kvmvapic.c        |  13 +++--
 hw/i386/pc.c              |  17 ++++---
 hw/i386/pc_piix.c         |   3 +-
 hw/intc/sh_intc.c         |   5 +-
 hw/isa/lpc_ich9.c         |   2 +-
 hw/mips/mips_malta.c      |   3 +-
 hw/ppc/ppc.c              |  11 ++--
 hw/ppc/prep.c             |   6 ++-
 hw/ppc/spapr.c            |  27 +++++-----
 include/exec/cpu-all.h    |   1 -
 include/exec/cpu-defs.h   |   1 -
 include/qom/cpu.h         |   4 ++
 kvm-all.c                 |  20 +++++---
 linux-user/elfload.c      |   7 +--
 linux-user/main.c         |   8 ++-
 linux-user/syscall.c      |   9 ++--
 memory_mapping.c          |  16 +++---
 monitor.c                 |   4 +-
 target-i386/arch_dump.c   |   7 ++-
 target-i386/helper.c      |  15 +++---
 target-i386/kvm.c         |   8 +--
 target-i386/misc_helper.c |   2 +-
 target-mips/op_helper.c   |  25 +++++----
 target-ppc/excp_helper.c  |   9 ++--
 target-ppc/kvm.c          |   2 +-
 translate-all.c           |  12 +++--
 38 files changed, 267 insertions(+), 226 deletions(-)

diff --git a/cpus.c b/cpus.c
index 808503b..ec38644 100644
--- a/cpus.c
+++ b/cpus.c
@@ -60,7 +60,7 @@
 
 #endif /* CONFIG_LINUX */
 
-static CPUArchState *next_cpu;
+static CPUState *next_cpu;
 
 static bool cpu_thread_is_idle(CPUState *cpu)
 {
@@ -79,10 +79,10 @@ static bool cpu_thread_is_idle(CPUState *cpu)
 
 static bool all_cpu_threads_idle(void)
 {
-    CPUArchState *env;
+    CPUState *cpu;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        if (!cpu_thread_is_idle(ENV_GET_CPU(env))) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        if (!cpu_thread_is_idle(cpu)) {
             return false;
         }
     }
@@ -388,15 +388,13 @@ void configure_icount(const char *option)
 void hw_error(const char *fmt, ...)
 {
     va_list ap;
-    CPUArchState *env;
     CPUState *cpu;
 
     va_start(ap, fmt);
     fprintf(stderr, "qemu: hardware error: ");
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = ENV_GET_CPU(env);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
         cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU);
     }
@@ -406,28 +404,28 @@ void hw_error(const char *fmt, ...)
 
 void cpu_synchronize_all_states(void)
 {
-    CPUArchState *env;
+    CPUState *cpu;
 
-    for (env = first_cpu; env; env = env->next_cpu) {
-        cpu_synchronize_state(ENV_GET_CPU(env));
+    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
+        cpu_synchronize_state(cpu);
     }
 }
 
 void cpu_synchronize_all_post_reset(void)
 {
-    CPUArchState *cpu;
+    CPUState *cpu;
 
     for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
-        cpu_synchronize_post_reset(ENV_GET_CPU(cpu));
+        cpu_synchronize_post_reset(cpu);
     }
 }
 
 void cpu_synchronize_all_post_init(void)
 {
-    CPUArchState *cpu;
+    CPUState *cpu;
 
     for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
-        cpu_synchronize_post_init(ENV_GET_CPU(cpu));
+        cpu_synchronize_post_init(cpu);
     }
 }
 
@@ -698,7 +696,7 @@ static void qemu_wait_io_event_common(CPUState *cpu)
 
 static void qemu_tcg_wait_io_event(void)
 {
-    CPUArchState *env;
+    CPUState *cpu;
 
     while (all_cpu_threads_idle()) {
        /* Start accounting real time to the virtual clock if the CPUs
@@ -711,8 +709,8 @@ static void qemu_tcg_wait_io_event(void)
         qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex);
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        qemu_wait_io_event_common(ENV_GET_CPU(env));
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        qemu_wait_io_event_common(cpu);
     }
 }
 
@@ -814,7 +812,6 @@ static void tcg_signal_cpu_creation(CPUState *cpu, void *data)
 static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
     CPUState *cpu = arg;
-    CPUArchState *env;
 
     qemu_tcg_init_cpu_signals();
     qemu_thread_get_self(cpu->thread);
@@ -824,12 +821,12 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
     qemu_cond_signal(&qemu_cpu_cond);
 
     /* wait for initial kick-off after machine start */
-    while (ENV_GET_CPU(first_cpu)->stopped) {
+    while (first_cpu->stopped) {
         qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
 
         /* process any pending work */
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
-            qemu_wait_io_event_common(ENV_GET_CPU(env));
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            qemu_wait_io_event_common(cpu);
         }
     }
 
@@ -923,7 +920,7 @@ void qemu_mutex_lock_iothread(void)
     } else {
         iothread_requesting_mutex = true;
         if (qemu_mutex_trylock(&qemu_global_mutex)) {
-            qemu_cpu_kick_thread(ENV_GET_CPU(first_cpu));
+            qemu_cpu_kick_thread(first_cpu);
             qemu_mutex_lock(&qemu_global_mutex);
         }
         iothread_requesting_mutex = false;
@@ -938,14 +935,13 @@ void qemu_mutex_unlock_iothread(void)
 
 static int all_vcpus_paused(void)
 {
-    CPUArchState *penv = first_cpu;
+    CPUState *cpu = first_cpu;
 
-    while (penv) {
-        CPUState *pcpu = ENV_GET_CPU(penv);
-        if (!pcpu->stopped) {
+    while (cpu) {
+        if (!cpu->stopped) {
             return 0;
         }
-        penv = penv->next_cpu;
+        cpu = cpu->next_cpu;
     }
 
     return 1;
@@ -953,25 +949,23 @@ static int all_vcpus_paused(void)
 
 void pause_all_vcpus(void)
 {
-    CPUArchState *penv = first_cpu;
+    CPUState *cpu = first_cpu;
 
     qemu_clock_enable(vm_clock, false);
-    while (penv) {
-        CPUState *pcpu = ENV_GET_CPU(penv);
-        pcpu->stop = true;
-        qemu_cpu_kick(pcpu);
-        penv = penv->next_cpu;
+    while (cpu) {
+        cpu->stop = true;
+        qemu_cpu_kick(cpu);
+        cpu = cpu->next_cpu;
     }
 
     if (qemu_in_vcpu_thread()) {
         cpu_stop_current();
         if (!kvm_enabled()) {
-            penv = first_cpu;
-            while (penv) {
-                CPUState *pcpu = ENV_GET_CPU(penv);
-                pcpu->stop = false;
-                pcpu->stopped = true;
-                penv = penv->next_cpu;
+            cpu = first_cpu;
+            while (cpu) {
+                cpu->stop = false;
+                cpu->stopped = true;
+                cpu = cpu->next_cpu;
             }
             return;
         }
@@ -979,10 +973,10 @@ void pause_all_vcpus(void)
 
     while (!all_vcpus_paused()) {
         qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
-        penv = first_cpu;
-        while (penv) {
-            qemu_cpu_kick(ENV_GET_CPU(penv));
-            penv = penv->next_cpu;
+        cpu = first_cpu;
+        while (cpu) {
+            qemu_cpu_kick(cpu);
+            cpu = cpu->next_cpu;
         }
     }
 }
@@ -996,13 +990,12 @@ void cpu_resume(CPUState *cpu)
 
 void resume_all_vcpus(void)
 {
-    CPUArchState *penv = first_cpu;
+    CPUState *cpu = first_cpu;
 
     qemu_clock_enable(vm_clock, true);
-    while (penv) {
-        CPUState *pcpu = ENV_GET_CPU(penv);
-        cpu_resume(pcpu);
-        penv = penv->next_cpu;
+    while (cpu) {
+        cpu_resume(cpu);
+        cpu = cpu->next_cpu;
     }
 }
 
@@ -1151,8 +1144,8 @@ static void tcg_exec_all(void)
         next_cpu = first_cpu;
     }
     for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
-        CPUArchState *env = next_cpu;
-        CPUState *cpu = ENV_GET_CPU(env);
+        CPUState *cpu = next_cpu;
+        CPUArchState *env = cpu->env_ptr;
 
         qemu_clock_enable(vm_clock,
                           (env->singlestep_enabled & SSTEP_NOTIMER) == 0);
@@ -1172,12 +1165,10 @@ static void tcg_exec_all(void)
 
 void set_numa_modes(void)
 {
-    CPUArchState *env;
     CPUState *cpu;
     int i;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = ENV_GET_CPU(env);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         for (i = 0; i < nb_numa_nodes; i++) {
             if (test_bit(cpu->cpu_index, node_cpumask[i])) {
                 cpu->numa_node = i;
@@ -1197,18 +1188,30 @@ void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
 CpuInfoList *qmp_query_cpus(Error **errp)
 {
     CpuInfoList *head = NULL, *cur_item = NULL;
-    CPUArchState *env;
+    CPUState *cpu;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        CPUState *cpu = ENV_GET_CPU(env);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         CpuInfoList *info;
+#if defined(TARGET_I386)
+        X86CPU *x86_cpu = X86_CPU(cpu);
+        CPUX86State *env = &x86_cpu->env;
+#elif defined(TARGET_PPC)
+        PowerPCCPU *ppc_cpu = POWERPC_CPU(cpu);
+        CPUPPCState *env = &ppc_cpu->env;
+#elif defined(TARGET_SPARC)
+        SPARCCPU *sparc_cpu = SPARC_CPU(cpu);
+        CPUSPARCState *env = &sparc_cpu->env;
+#elif defined(TARGET_MIPS)
+        MIPSCPU *mips_cpu = MIPS_CPU(cpu);
+        CPUMIPSState *env = &mips_cpu->env;
+#endif
 
         cpu_synchronize_state(cpu);
 
         info = g_malloc0(sizeof(*info));
         info->value = g_malloc0(sizeof(*info->value));
         info->value->CPU = cpu->cpu_index;
-        info->value->current = (env == first_cpu);
+        info->value->current = (cpu == first_cpu);
         info->value->halted = cpu->halted;
         info->value->thread_id = cpu->thread_id;
 #if defined(TARGET_I386)
@@ -1316,11 +1319,14 @@ exit:
 void qmp_inject_nmi(Error **errp)
 {
 #if defined(TARGET_I386)
-    CPUArchState *env;
+    CPUState *cs;
+
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+        X86CPU *cpu = X86_CPU(cs);
+        CPUX86State *env = &cpu->env;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
         if (!env->apic_state) {
-            cpu_interrupt(CPU(x86_env_get_cpu(env)), CPU_INTERRUPT_NMI);
+            cpu_interrupt(cs, CPU_INTERRUPT_NMI);
         } else {
             apic_deliver_nmi(env->apic_state);
         }
diff --git a/cputlb.c b/cputlb.c
index 232c488..74b98ec 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -175,11 +175,13 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
 
 void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length)
 {
+    CPUState *cpu;
     CPUArchState *env;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         int mmu_idx;
 
+        env = cpu->env_ptr;
         for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
             unsigned int i;
 
diff --git a/dump.c b/dump.c
index 44a1339..e414515 100644
--- a/dump.c
+++ b/dump.c
@@ -275,13 +275,11 @@ static inline int cpu_index(CPUState *cpu)
 
 static int write_elf64_notes(DumpState *s)
 {
-    CPUArchState *env;
     CPUState *cpu;
     int ret;
     int id;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = ENV_GET_CPU(env);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         id = cpu_index(cpu);
         ret = cpu_write_elf64_note(fd_write_vmcore, cpu, id, s);
         if (ret < 0) {
@@ -290,7 +288,7 @@ static int write_elf64_notes(DumpState *s)
         }
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         ret = cpu_write_elf64_qemunote(fd_write_vmcore, cpu, s);
         if (ret < 0) {
             dump_error(s, "dump: failed to write CPU status.\n");
@@ -327,13 +325,11 @@ static int write_elf32_note(DumpState *s)
 
 static int write_elf32_notes(DumpState *s)
 {
-    CPUArchState *env;
     CPUState *cpu;
     int ret;
     int id;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = ENV_GET_CPU(env);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         id = cpu_index(cpu);
         ret = cpu_write_elf32_note(fd_write_vmcore, cpu, id, s);
         if (ret < 0) {
@@ -342,7 +338,7 @@ static int write_elf32_notes(DumpState *s)
         }
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         ret = cpu_write_elf32_qemunote(fd_write_vmcore, cpu, s);
         if (ret < 0) {
             dump_error(s, "dump: failed to write CPU status.\n");
@@ -705,7 +701,7 @@ static ram_addr_t get_start_block(DumpState *s)
 static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
                      int64_t begin, int64_t length, Error **errp)
 {
-    CPUArchState *env;
+    CPUState *cpu;
     int nr_cpus;
     Error *err = NULL;
     int ret;
@@ -738,7 +734,7 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
      */
     cpu_synchronize_all_states();
     nr_cpus = 0;
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         nr_cpus++;
     }
 
diff --git a/exec.c b/exec.c
index e14a815..191eb4e 100644
--- a/exec.c
+++ b/exec.c
@@ -70,7 +70,7 @@ static MemoryRegion io_mem_unassigned, io_mem_subpage_ram;
 
 #endif
 
-CPUArchState *first_cpu;
+CPUState *first_cpu;
 /* current CPU in the current thread. It is only valid inside
    cpu_exec() */
 DEFINE_TLS(CPUState *,cpu_single_cpu);
@@ -264,27 +264,26 @@ static const VMStateDescription vmstate_cpu_common = {
 
 CPUState *qemu_get_cpu(int index)
 {
-    CPUArchState *env = first_cpu;
-    CPUState *cpu = NULL;
+    CPUState *cpu = first_cpu;
 
-    while (env) {
-        cpu = ENV_GET_CPU(env);
+    while (cpu) {
         if (cpu->cpu_index == index) {
             break;
         }
-        env = env->next_cpu;
+        cpu = cpu->next_cpu;
     }
 
-    return env ? cpu : NULL;
+    return cpu;
 }
 
 void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data)
 {
-    CPUArchState *env = first_cpu;
+    CPUState *cpu;
 
-    while (env) {
-        func(ENV_GET_CPU(env), data);
-        env = env->next_cpu;
+    cpu = first_cpu;
+    while (cpu) {
+        func(cpu, data);
+        cpu = cpu->next_cpu;
     }
 }
 
@@ -292,17 +291,17 @@ void cpu_exec_init(CPUArchState *env)
 {
     CPUState *cpu = ENV_GET_CPU(env);
     CPUClass *cc = CPU_GET_CLASS(cpu);
-    CPUArchState **penv;
+    CPUState **pcpu;
     int cpu_index;
 
 #if defined(CONFIG_USER_ONLY)
     cpu_list_lock();
 #endif
-    env->next_cpu = NULL;
-    penv = &first_cpu;
+    cpu->next_cpu = NULL;
+    pcpu = &first_cpu;
     cpu_index = 0;
-    while (*penv != NULL) {
-        penv = &(*penv)->next_cpu;
+    while (*pcpu != NULL) {
+        pcpu = &(*pcpu)->next_cpu;
         cpu_index++;
     }
     cpu->cpu_index = cpu_index;
@@ -312,7 +311,7 @@ void cpu_exec_init(CPUArchState *env)
 #ifndef CONFIG_USER_ONLY
     cpu->thread_id = qemu_get_thread_id();
 #endif
-    *penv = env;
+    *pcpu = cpu;
 #if defined(CONFIG_USER_ONLY)
     cpu_list_unlock();
 #endif
@@ -551,7 +550,7 @@ void cpu_abort(CPUArchState *env, const char *fmt, ...)
 CPUArchState *cpu_copy(CPUArchState *env)
 {
     CPUArchState *new_env = cpu_init(env->cpu_model_str);
-    CPUArchState *next_cpu = new_env->next_cpu;
+    CPUState *next_cpu = ENV_GET_CPU(new_env)->next_cpu;
 #if defined(TARGET_HAS_ICE)
     CPUBreakpoint *bp;
     CPUWatchpoint *wp;
@@ -560,7 +559,7 @@ CPUArchState *cpu_copy(CPUArchState *env)
     memcpy(new_env, env, sizeof(CPUArchState));
 
     /* Preserve chaining. */
-    new_env->next_cpu = next_cpu;
+    ENV_GET_CPU(new_env)->next_cpu = next_cpu;
 
     /* Clone all break/watchpoints.
        Note: Once we support ptrace with hw-debug register access, make sure
@@ -1707,12 +1706,14 @@ static void core_begin(MemoryListener *listener)
 
 static void tcg_commit(MemoryListener *listener)
 {
-    CPUArchState *env;
+    CPUState *cpu;
 
     /* since each CPU stores ram addresses in its TLB cache, we must
        reset the modified entries */
     /* XXX: slow ! */
-    for(env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         tlb_flush(env, 1);
     }
 }
diff --git a/gdbstub.c b/gdbstub.c
index 9e7f7a1..5793bcd 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1839,6 +1839,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
         /* Generate the XML description for this CPU.  */
         if (!target_xml[0]) {
             GDBRegisterState *r;
+            CPUArchState *env = first_cpu->env_ptr;
 
             snprintf(target_xml, sizeof(target_xml),
                      "<?xml version=\"1.0\"?>"
@@ -1847,7 +1848,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
                      "<xi:include href=\"%s\"/>",
                      GDB_CORE_XML);
 
-            for (r = first_cpu->gdb_regs; r; r = r->next) {
+            for (r = env->gdb_regs; r; r = r->next) {
                 pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
                 pstrcat(target_xml, sizeof(target_xml), r->xml);
                 pstrcat(target_xml, sizeof(target_xml), "\"/>");
@@ -1949,6 +1950,7 @@ static const int xlat_gdb_type[] = {
 
 static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
 {
+    CPUState *cpu;
     CPUArchState *env;
     int err = 0;
 
@@ -1958,7 +1960,8 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
     switch (type) {
     case GDB_BREAKPOINT_SW:
     case GDB_BREAKPOINT_HW:
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            env = cpu->env_ptr;
             err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
             if (err)
                 break;
@@ -1968,7 +1971,8 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
     case GDB_WATCHPOINT_WRITE:
     case GDB_WATCHPOINT_READ:
     case GDB_WATCHPOINT_ACCESS:
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            env = cpu->env_ptr;
             err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
                                         NULL);
             if (err)
@@ -1983,6 +1987,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
 
 static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
 {
+    CPUState *cpu;
     CPUArchState *env;
     int err = 0;
 
@@ -1992,7 +1997,8 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     switch (type) {
     case GDB_BREAKPOINT_SW:
     case GDB_BREAKPOINT_HW:
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            env = cpu->env_ptr;
             err = cpu_breakpoint_remove(env, addr, BP_GDB);
             if (err)
                 break;
@@ -2002,7 +2008,8 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     case GDB_WATCHPOINT_WRITE:
     case GDB_WATCHPOINT_READ:
     case GDB_WATCHPOINT_ACCESS:
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            env = cpu->env_ptr;
             err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
             if (err)
                 break;
@@ -2016,6 +2023,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
 
 static void gdb_breakpoint_remove_all(void)
 {
+    CPUState *cpu;
     CPUArchState *env;
 
     if (kvm_enabled()) {
@@ -2023,7 +2031,8 @@ static void gdb_breakpoint_remove_all(void)
         return;
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        env = cpu->env_ptr;
         cpu_breakpoint_remove_all(env, BP_GDB);
 #ifndef CONFIG_USER_ONLY
         cpu_watchpoint_remove_all(env, BP_GDB);
@@ -2390,7 +2399,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet(s, "QC1");
             break;
         } else if (strcmp(p,"fThreadInfo") == 0) {
-            s->query_cpu = first_cpu;
+            s->query_cpu = first_cpu->env_ptr;
             goto report_cpuinfo;
         } else if (strcmp(p,"sThreadInfo") == 0) {
         report_cpuinfo:
@@ -2398,7 +2407,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
                 snprintf(buf, sizeof(buf), "m%x",
                          cpu_index(ENV_GET_CPU(s->query_cpu)));
                 put_packet(s, buf);
-                s->query_cpu = s->query_cpu->next_cpu;
+                s->query_cpu = ENV_GET_CPU(s->query_cpu)->next_cpu->env_ptr;
             } else
                 put_packet(s, "l");
             break;
@@ -2865,8 +2874,8 @@ static void gdb_accept(void)
     socket_set_nodelay(fd);
 
     s = g_malloc0(sizeof(GDBState));
-    s->c_cpu = first_cpu;
-    s->g_cpu = first_cpu;
+    s->c_cpu = first_cpu->env_ptr;
+    s->g_cpu = first_cpu->env_ptr;
     s->fd = fd;
     gdb_has_xml = 0;
 
@@ -3050,8 +3059,8 @@ int gdbserver_start(const char *device)
         mon_chr = s->mon_chr;
         memset(s, 0, sizeof(GDBState));
     }
-    s->c_cpu = first_cpu;
-    s->g_cpu = first_cpu;
+    s->c_cpu = first_cpu->env_ptr;
+    s->g_cpu = first_cpu->env_ptr;
     s->chr = chr;
     s->state = chr ? RS_IDLE : RS_INACTIVE;
     s->mon_chr = mon_chr;
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index f451529..ad13d3f 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -329,7 +329,7 @@ static void do_cpu_reset(void *opaque)
             env->regs[15] = info->entry & 0xfffffffe;
             env->thumb = info->entry & 1;
         } else {
-            if (env == first_cpu) {
+            if (CPU(cpu) == first_cpu) {
                 env->regs[15] = info->loader_start;
                 if (!info->dtb_filename) {
                     if (old_param) {
@@ -347,7 +347,7 @@ static void do_cpu_reset(void *opaque)
 
 void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
 {
-    CPUARMState *env = &cpu->env;
+    CPUState *cs = CPU(cpu);
     int kernel_size;
     int initrd_size;
     int n;
@@ -472,9 +472,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
     }
     info->is_linux = is_linux;
 
-    for (; env; env = env->next_cpu) {
-        cpu = arm_env_get_cpu(env);
-        env->boot_info = info;
+    for (; cs; cs = cs->next_cpu) {
+        cpu = ARM_CPU(cs);
+        cpu->env.boot_info = info;
         qemu_register_reset(do_cpu_reset, cpu);
     }
 }
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
index 74f110b..7c90b2d 100644
--- a/hw/arm/exynos4_boards.c
+++ b/hw/arm/exynos4_boards.c
@@ -131,7 +131,7 @@ static void nuri_init(QEMUMachineInitArgs *args)
 {
     exynos4_boards_init_common(args, EXYNOS4_BOARD_NURI);
 
-    arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
+    arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo);
 }
 
 static void smdkc210_init(QEMUMachineInitArgs *args)
@@ -141,7 +141,7 @@ static void smdkc210_init(QEMUMachineInitArgs *args)
 
     lan9215_init(SMDK_LAN9118_BASE_ADDR,
             qemu_irq_invert(s->irq_table[exynos4210_get_irq(37, 1)]));
-    arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
+    arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo);
 }
 
 static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS] = {
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 4405dbd..1d28842 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -321,7 +321,7 @@ static void highbank_init(QEMUMachineInitArgs *args)
     highbank_binfo.loader_start = 0;
     highbank_binfo.write_secondary_boot = hb_write_secondary;
     highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary;
-    arm_load_kernel(arm_env_get_cpu(first_cpu), &highbank_binfo);
+    arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo);
 }
 
 static QEMUMachine highbank_machine = {
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index d6f47bf..05dc3f3 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -329,7 +329,7 @@ static void realview_init(QEMUMachineInitArgs *args,
     realview_binfo.nb_cpus = smp_cpus;
     realview_binfo.board_id = realview_board_id[board_type];
     realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0);
-    arm_load_kernel(arm_env_get_cpu(first_cpu), &realview_binfo);
+    arm_load_kernel(ARM_CPU(first_cpu), &realview_binfo);
 }
 
 static void realview_eb_init(QEMUMachineInitArgs *args)
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index a077c62..c8f2890 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -519,7 +519,7 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard,
     vexpress_binfo.smp_loader_start = map[VE_SRAM];
     vexpress_binfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30;
     vexpress_binfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr;
-    arm_load_kernel(arm_env_get_cpu(first_cpu), &vexpress_binfo);
+    arm_load_kernel(ARM_CPU(first_cpu), &vexpress_binfo);
 }
 
 static void vexpress_a9_init(QEMUMachineInitArgs *args)
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 4602a6f..f73eeed 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -226,7 +226,7 @@ static void zynq_init(QEMUMachineInitArgs *args)
     zynq_binfo.nb_cpus = 1;
     zynq_binfo.board_id = 0xd32;
     zynq_binfo.loader_start = 0;
-    arm_load_kernel(arm_env_get_cpu(first_cpu), &zynq_binfo);
+    arm_load_kernel(ARM_CPU(first_cpu), &zynq_binfo);
 }
 
 static QEMUMachine zynq_machine = {
diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 87d4d0f..eba275a 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -65,7 +65,7 @@ static void kvmclock_vm_state_change(void *opaque, int running,
                                      RunState state)
 {
     KVMClockState *s = opaque;
-    CPUArchState *penv = first_cpu;
+    CPUState *cpu = first_cpu;
     int cap_clock_ctrl = kvm_check_extension(kvm_state, KVM_CAP_KVMCLOCK_CTRL);
     int ret;
 
@@ -75,8 +75,8 @@ static void kvmclock_vm_state_change(void *opaque, int running,
         if (!cap_clock_ctrl) {
             return;
         }
-        for (penv = first_cpu; penv != NULL; penv = penv->next_cpu) {
-            ret = kvm_vcpu_ioctl(ENV_GET_CPU(penv), KVM_KVMCLOCK_CTRL, 0);
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            ret = kvm_vcpu_ioctl(cpu, KVM_KVMCLOCK_CTRL, 0);
             if (ret) {
                 if (ret != -EINVAL) {
                     fprintf(stderr, "%s: %s\n", __func__, strerror(-ret));
@@ -128,9 +128,11 @@ static const TypeInfo kvmclock_info = {
 /* Note: Must be called after VCPU initialization. */
 void kvmclock_create(void)
 {
+    X86CPU *cpu = X86_CPU(first_cpu);
+
     if (kvm_enabled() &&
-        first_cpu->features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
-                                         (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
+        cpu->env.features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
+                                       (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
         sysbus_create_simple("kvmclock", -1, NULL);
     }
 }
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 9aac9de..5538071 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -490,13 +490,15 @@ static void vapic_enable_tpr_reporting(bool enable)
     VAPICEnableTPRReporting info = {
         .enable = enable,
     };
+    CPUState *cs;
     X86CPU *cpu;
     CPUX86State *env;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = x86_env_get_cpu(env);
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+        cpu = X86_CPU(cs);
+        env = &cpu->env;
         info.apic = env->apic_state;
-        run_on_cpu(CPU(cpu), vapic_do_enable_tpr_reporting, &info);
+        run_on_cpu(cs, vapic_do_enable_tpr_reporting, &info);
     }
 }
 
@@ -718,8 +720,9 @@ static int vapic_init(SysBusDevice *dev)
 static void do_vapic_enable(void *data)
 {
     VAPICROMState *s = data;
+    X86CPU *cpu = X86_CPU(first_cpu);
 
-    vapic_enable(s, first_cpu);
+    vapic_enable(s, &cpu->env);
 }
 
 static int vapic_post_load(void *opaque, int version_id)
@@ -742,7 +745,7 @@ static int vapic_post_load(void *opaque, int version_id)
     }
     if (s->state == VAPIC_ACTIVE) {
         if (smp_cpus == 1) {
-            run_on_cpu(ENV_GET_CPU(first_cpu), do_vapic_enable, s);
+            run_on_cpu(first_cpu, do_vapic_enable, s);
         } else {
             zero = g_malloc0(s->rom_state.vapic_size);
             cpu_physical_memory_rw(s->vapic_paddr, zero,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c43be54..38722a1 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -160,8 +160,9 @@ void cpu_smm_register(cpu_set_smm_t callback, void *arg)
 
 void cpu_smm_update(CPUX86State *env)
 {
-    if (smm_set && smm_arg && env == first_cpu)
+    if (smm_set && smm_arg && CPU(x86_env_get_cpu(env)) == first_cpu) {
         smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
+    }
 }
 
 
@@ -185,18 +186,21 @@ int cpu_get_pic_interrupt(CPUX86State *env)
 
 static void pic_irq_request(void *opaque, int irq, int level)
 {
-    CPUX86State *env = first_cpu;
+    CPUState *cs = first_cpu;
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
 
     DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq);
     if (env->apic_state) {
-        while (env) {
+        while (cs) {
+            cpu = X86_CPU(cs);
+            env = &cpu->env;
             if (apic_accept_pic_intr(env->apic_state)) {
                 apic_deliver_pic_intr(env->apic_state, level);
             }
-            env = env->next_cpu;
+            cs = cs->next_cpu;
         }
     } else {
-        CPUState *cs = CPU(x86_env_get_cpu(env));
         if (level) {
             cpu_interrupt(cs, CPU_INTERRUPT_HARD);
         } else {
@@ -1205,8 +1209,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
         }
     }
 
-    a20_line = qemu_allocate_irqs(handle_a20_line_change,
-                                  x86_env_get_cpu(first_cpu), 2);
+    a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2);
     i8042 = isa_create_simple(isa_bus, "i8042");
     i8042_setup_a20_line(i8042, &a20_line[0]);
     if (!no_vmport) {
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 97362f2..f3bf240 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -213,8 +213,7 @@ static void pc_init1(MemoryRegion *system_memory,
     if (pci_enabled && acpi_enabled) {
         i2c_bus *smbus;
 
-        smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt,
-                                     x86_env_get_cpu(first_cpu), 1);
+        smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
         /* TODO: Populate SPD eeprom data.  */
         smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
                               gsi[9], *smi_irq,
diff --git a/hw/intc/sh_intc.c b/hw/intc/sh_intc.c
index 050bfb6..f1138e3 100644
--- a/hw/intc/sh_intc.c
+++ b/hw/intc/sh_intc.c
@@ -42,16 +42,15 @@ void sh_intc_toggle_source(struct intc_source *source,
         pending_changed = 1;
 
     if (pending_changed) {
-        CPUState *cpu = CPU(sh_env_get_cpu(first_cpu));
         if (source->pending) {
             source->parent->pending++;
             if (source->parent->pending == 1) {
-                cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
+                cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD);
             }
         } else {
             source->parent->pending--;
             if (source->parent->pending == 0) {
-                cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
+                cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD);
             }
 	}
     }
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 667e882..69e1f50 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -380,7 +380,7 @@ static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
 
     /* SMI_EN = PMBASE + 30. SMI control and enable register */
     if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) {
-        cpu_interrupt(CPU(x86_env_get_cpu(first_cpu)), CPU_INTERRUPT_SMI);
+        cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
     }
 }
 
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 4fc611c..adea146 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -844,7 +844,8 @@ void mips_malta_init(QEMUMachineInitArgs *args)
         cpu_mips_clock_init(env);
         qemu_register_reset(main_cpu_reset, cpu);
     }
-    env = first_cpu;
+    cpu = MIPS_CPU(first_cpu);
+    env = &cpu->env;
 
     /* allocate RAM */
     if (ram_size > (256 << 20)) {
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index fb57b42..554f244 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -440,15 +440,14 @@ void ppce500_irq_init(CPUPPCState *env)
 /* Enable or Disable the E500 EPR capability */
 void ppce500_set_mpic_proxy(bool enabled)
 {
-    CPUPPCState *env;
+    CPUState *cs;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        PowerPCCPU *cpu = ppc_env_get_cpu(env);
-        CPUState *cs = CPU(cpu);
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
 
-        env->mpic_proxy = enabled;
+        cpu->env.mpic_proxy = enabled;
         if (kvm_enabled()) {
-            kvmppc_set_mpic_proxy(POWERPC_CPU(cs), enabled);
+            kvmppc_set_mpic_proxy(cpu, enabled);
         }
     }
 }
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 16e3132..45625ca 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -594,8 +594,9 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
     /* PCI -> ISA bridge */
     pci = pci_create_simple(pci_bus, PCI_DEVFN(1, 0), "i82378");
     cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
+    cpu = POWERPC_CPU(first_cpu);
     qdev_connect_gpio_out(&pci->qdev, 0,
-                          first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
+                          cpu->env.irq_inputs[PPC6xx_INPUT_INT]);
     qdev_connect_gpio_out(&pci->qdev, 1, *cpu_exit_irq);
     sysbus_connect_irq(&pcihost->busdev, 0, qdev_get_gpio_in(&pci->qdev, 9));
     sysbus_connect_irq(&pcihost->busdev, 1, qdev_get_gpio_in(&pci->qdev, 11));
@@ -640,7 +641,8 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
     }
     isa_create_simple(isa_bus, "i8042");
 
-    sysctrl->reset_irq = first_cpu->irq_inputs[PPC6xx_INPUT_HRESET];
+    cpu = POWERPC_CPU(first_cpu);
+    sysctrl->reset_irq = cpu->env.irq_inputs[PPC6xx_INPUT_HRESET];
     /* System control ports */
     register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);
     register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 218ea23..4fce87a 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -131,7 +131,6 @@ int spapr_allocate_irq_block(int num, bool lsi)
 static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
 {
     int ret = 0, offset;
-    CPUPPCState *env;
     CPUState *cpu;
     char cpu_model[32];
     int smt = kvmppc_smt_threads();
@@ -139,8 +138,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
 
     assert(spapr->cpu_model);
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = CPU(ppc_env_get_cpu(env));
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         uint32_t associativity[] = {cpu_to_be32(0x5),
                                     cpu_to_be32(0x0),
                                     cpu_to_be32(0x0),
@@ -231,7 +229,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
                                    uint32_t epow_irq)
 {
     void *fdt;
-    CPUPPCState *env;
+    CPUState *cs;
     uint32_t start_prop = cpu_to_be32(initrd_base);
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
     char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
@@ -304,10 +302,11 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
     /* This is needed during FDT finalization */
     spapr->cpu_model = g_strdup(modelname);
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        CPUState *cpu = CPU(ppc_env_get_cpu(env));
-        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
-        int index = cpu->cpu_index;
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+        CPUPPCState *env = &cpu->env;
+        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
+        int index = cs->cpu_index;
         uint32_t servers_prop[smp_threads];
         uint32_t gservers_prop[smp_threads * 2];
         char *nodename;
@@ -632,7 +631,7 @@ static void spapr_reset_htab(sPAPREnvironment *spapr)
 
 static void ppc_spapr_reset(void)
 {
-    CPUState *first_cpu_cpu;
+    PowerPCCPU *first_ppc_cpu;
 
     /* Reset the hash table & recalc the RMA */
     spapr_reset_htab(spapr);
@@ -644,11 +643,11 @@ static void ppc_spapr_reset(void)
                        spapr->rtas_size);
 
     /* Set up the entry state */
-    first_cpu_cpu = ENV_GET_CPU(first_cpu);
-    first_cpu->gpr[3] = spapr->fdt_addr;
-    first_cpu->gpr[5] = 0;
-    first_cpu_cpu->halted = 0;
-    first_cpu->nip = spapr->entry_point;
+    first_ppc_cpu = POWERPC_CPU(first_cpu);
+    first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
+    first_ppc_cpu->env.gpr[5] = 0;
+    first_cpu->halted = 0;
+    first_ppc_cpu->env.nip = spapr->entry_point;
 
 }
 
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 6760851..6499cd0 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -356,7 +356,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
 
 void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
-extern CPUArchState *first_cpu;
 
 /* Flags for use in ENV->INTERRUPT_PENDING.
 
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index c4ac929..39094b3 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -181,7 +181,6 @@ typedef struct CPUWatchpoint {
     sigjmp_buf jmp_env;                                                 \
     int exception_index;                                                \
                                                                         \
-    CPUArchState *next_cpu; /* next CPU sharing TB cache */                 \
     /* user data */                                                     \
     void *opaque;                                                       \
                                                                         \
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 0e2e76c..2a64af2 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -114,6 +114,7 @@ struct kvm_run;
  *           CPU and return to its top level loop.
  * @env_ptr: Pointer to subclass-specific CPUArchState field.
  * @current_tb: Currently executing TB.
+ * @next_cpu: Next CPU sharing TB cache.
  * @kvm_fd: vCPU file descriptor for KVM.
  *
  * State of one CPU core or thread.
@@ -146,6 +147,7 @@ struct CPUState {
 
     void *env_ptr; /* CPUArchState */
     struct TranslationBlock *current_tb;
+    CPUState *next_cpu;
 
     int kvm_fd;
     bool kvm_vcpu_dirty;
@@ -157,6 +159,8 @@ struct CPUState {
     uint32_t halted; /* used by alpha, cris, ppc TCG */
 };
 
+extern CPUState *first_cpu;
+
 DECLARE_TLS(CPUState *, cpu_single_cpu);
 #define cpu_single_cpu tls_var(cpu_single_cpu)
 
diff --git a/kvm-all.c b/kvm-all.c
index b3ba6aa..6b9e343 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1896,7 +1896,7 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
 {
     CPUState *current_cpu = ENV_GET_CPU(current_env);
     struct kvm_sw_breakpoint *bp;
-    CPUArchState *env;
+    CPUState *cpu;
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
@@ -1928,7 +1928,9 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
         }
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         err = kvm_update_guest_debug(env, 0);
         if (err) {
             return err;
@@ -1942,7 +1944,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
 {
     CPUState *current_cpu = ENV_GET_CPU(current_env);
     struct kvm_sw_breakpoint *bp;
-    CPUArchState *env;
+    CPUState *cpu;
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
@@ -1970,7 +1972,9 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
         }
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         err = kvm_update_guest_debug(env, 0);
         if (err) {
             return err;
@@ -1983,14 +1987,12 @@ void kvm_remove_all_breakpoints(CPUState *current_cpu)
 {
     struct kvm_sw_breakpoint *bp, *next;
     KVMState *s = current_cpu->kvm_state;
-    CPUArchState *env;
     CPUState *cpu;
 
     QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
         if (kvm_arch_remove_sw_breakpoint(current_cpu, bp) != 0) {
             /* Try harder to find a CPU that currently sees the breakpoint. */
-            for (env = first_cpu; env != NULL; env = env->next_cpu) {
-                cpu = ENV_GET_CPU(env);
+            for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
                 if (kvm_arch_remove_sw_breakpoint(cpu, bp) == 0) {
                     break;
                 }
@@ -2001,7 +2003,9 @@ void kvm_remove_all_breakpoints(CPUState *current_cpu)
     }
     kvm_arch_remove_all_hw_breakpoints();
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         kvm_update_guest_debug(env, 0);
     }
 }
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ddef23e..d517450 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2628,7 +2628,7 @@ static int fill_note_info(struct elf_note_info *info,
                           long signr, const CPUArchState *env)
 {
 #define NUMNOTES 3
-    CPUArchState *cpu = NULL;
+    CPUState *cpu = NULL;
     TaskState *ts = (TaskState *)env->opaque;
     int i;
 
@@ -2667,9 +2667,10 @@ static int fill_note_info(struct elf_note_info *info,
     /* read and fill status of all threads */
     cpu_list_lock();
     for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
-        if (cpu == thread_env)
+        if (cpu == ENV_GET_CPU(thread_env)) {
             continue;
-        fill_thread_info(info, cpu);
+        }
+        fill_thread_info(info, (CPUArchState *)cpu->env_ptr);
     }
     cpu_list_unlock();
 
diff --git a/linux-user/main.c b/linux-user/main.c
index 95e17cf..3e60877 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -120,8 +120,8 @@ void fork_end(int child)
     if (child) {
         /* Child processes created by fork() only have a single thread.
            Discard information about the parent threads.  */
-        first_cpu = thread_env;
-        thread_env->next_cpu = NULL;
+        first_cpu = ENV_GET_CPU(thread_env);
+        first_cpu->next_cpu = NULL;
         pending_cpus = 0;
         pthread_mutex_init(&exclusive_lock, NULL);
         pthread_mutex_init(&cpu_list_mutex, NULL);
@@ -148,7 +148,6 @@ static inline void exclusive_idle(void)
    Must only be called from outside cpu_arm_exec.   */
 static inline void start_exclusive(void)
 {
-    CPUArchState *other;
     CPUState *other_cpu;
 
     pthread_mutex_lock(&exclusive_lock);
@@ -156,8 +155,7 @@ static inline void start_exclusive(void)
 
     pending_cpus = 1;
     /* Make all other cpus stop executing.  */
-    for (other = first_cpu; other; other = other->next_cpu) {
-        other_cpu = ENV_GET_CPU(other);
+    for (other_cpu = first_cpu; other_cpu; other_cpu = other_cpu->next_cpu) {
         if (other_cpu->running) {
             pending_cpus++;
             cpu_exit(other_cpu);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index cdd0c28..340666f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5030,6 +5030,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     abi_long arg5, abi_long arg6, abi_long arg7,
                     abi_long arg8)
 {
+#ifdef CONFIG_USE_NPTL
+    CPUState *cpu = ENV_GET_CPU(cpu_env);
+#endif
     abi_long ret;
     struct stat st;
     struct statfs stfs;
@@ -5052,13 +5055,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
          be disabling signals.  */
       if (first_cpu->next_cpu) {
           TaskState *ts;
-          CPUArchState **lastp;
-          CPUArchState *p;
+          CPUState **lastp;
+          CPUState *p;
 
           cpu_list_lock();
           lastp = &first_cpu;
           p = first_cpu;
-          while (p && p != (CPUArchState *)cpu_env) {
+          while (p && p != cpu) {
               lastp = &p->next_cpu;
               p = p->next_cpu;
           }
diff --git a/memory_mapping.c b/memory_mapping.c
index 5634f81..515a984 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -165,13 +165,13 @@ void memory_mapping_list_init(MemoryMappingList *list)
     QTAILQ_INIT(&list->head);
 }
 
-static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
+static CPUState *find_paging_enabled_cpu(CPUState *start_cpu)
 {
-    CPUArchState *env;
+    CPUState *cpu;
 
-    for (env = start_cpu; env != NULL; env = env->next_cpu) {
-        if (cpu_paging_enabled(ENV_GET_CPU(env))) {
-            return env;
+    for (cpu = start_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        if (cpu_paging_enabled(cpu)) {
+            return cpu;
         }
     }
 
@@ -180,15 +180,15 @@ static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
 
 void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp)
 {
-    CPUArchState *env, *first_paging_enabled_cpu;
+    CPUState *cpu, *first_paging_enabled_cpu;
     RAMBlock *block;
     ram_addr_t offset, length;
 
     first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu);
     if (first_paging_enabled_cpu) {
-        for (env = first_paging_enabled_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_paging_enabled_cpu; cpu != NULL; cpu = cpu->next_cpu) {
             Error *err = NULL;
-            cpu_get_memory_mapping(ENV_GET_CPU(env), list, &err);
+            cpu_get_memory_mapping(cpu, list, &err);
             if (err) {
                 error_propagate(errp, err);
                 return;
diff --git a/monitor.c b/monitor.c
index 9be515c..2ba7876 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1806,14 +1806,12 @@ static void do_info_mtree(Monitor *mon, const QDict *qdict)
 static void do_info_numa(Monitor *mon, const QDict *qdict)
 {
     int i;
-    CPUArchState *env;
     CPUState *cpu;
 
     monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
     for (i = 0; i < nb_numa_nodes; i++) {
         monitor_printf(mon, "node %d cpus:", i);
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
-            cpu = ENV_GET_CPU(env);
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
             if (cpu->numa_node == i) {
                 monitor_printf(mon, " %d", cpu->cpu_index);
             }
diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
index 83898cd..d133228 100644
--- a/target-i386/arch_dump.c
+++ b/target-i386/arch_dump.c
@@ -185,7 +185,8 @@ int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
     X86CPU *cpu = X86_CPU(cs);
     int ret;
 #ifdef TARGET_X86_64
-    bool lma = !!(first_cpu->hflags & HF_LMA_MASK);
+    X86CPU *first_x86_cpu = X86_CPU(first_cpu);
+    bool lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);
 
     if (lma) {
         ret = x86_64_write_elf64_note(f, &cpu->env, cpuid, opaque);
@@ -394,7 +395,9 @@ int cpu_get_dump_info(ArchDumpInfo *info)
     RAMBlock *block;
 
 #ifdef TARGET_X86_64
-    lma = !!(first_cpu->hflags & HF_LMA_MASK);
+    X86CPU *first_x86_cpu = X86_CPU(first_cpu);
+
+    lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);
 #endif
 
     if (lma) {
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 5e5abe3..d6f43d7 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1188,6 +1188,7 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
                         uint64_t status, uint64_t mcg_status, uint64_t addr,
                         uint64_t misc, int flags)
 {
+    CPUState *cs = CPU(cpu);
     CPUX86State *cenv = &cpu->env;
     MCEInjectionParams params = {
         .mon = mon,
@@ -1200,7 +1201,6 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
         .flags = flags,
     };
     unsigned bank_num = cenv->mcg_cap & 0xff;
-    CPUX86State *env;
 
     if (!cenv->mcg_cap) {
         monitor_printf(mon, "MCE injection not supported\n");
@@ -1220,19 +1220,22 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
         return;
     }
 
-    run_on_cpu(CPU(cpu), do_inject_x86_mce, &params);
+    run_on_cpu(cs, do_inject_x86_mce, &params);
     if (flags & MCE_INJECT_BROADCAST) {
+        CPUState *other_cs;
+
         params.bank = 1;
         params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
         params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
         params.addr = 0;
         params.misc = 0;
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
-            if (cenv == env) {
+        for (other_cs = first_cpu; other_cs != NULL;
+             other_cs = other_cs->next_cpu) {
+            if (other_cs == cs) {
                 continue;
             }
-            params.cpu = x86_env_get_cpu(env);
-            run_on_cpu(CPU(cpu), do_inject_x86_mce, &params);
+            params.cpu = X86_CPU(other_cs);
+            run_on_cpu(other_cs, do_inject_x86_mce, &params);
         }
     }
 }
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 39f4fbb..cc3dcec 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -345,20 +345,22 @@ int kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
 
 int kvm_arch_on_sigbus(int code, void *addr)
 {
-    if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
+    X86CPU *cpu = X86_CPU(first_cpu);
+
+    if ((cpu->env.mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
         ram_addr_t ram_addr;
         hwaddr paddr;
 
         /* Hope we are lucky for AO MCE */
         if (qemu_ram_addr_from_host(addr, &ram_addr) ||
-            !kvm_physical_memory_addr_from_host(CPU(first_cpu)->kvm_state,
+            !kvm_physical_memory_addr_from_host(first_cpu->kvm_state,
                                                 addr, &paddr)) {
             fprintf(stderr, "Hardware memory error for memory used by "
                     "QEMU itself instead of guest system!: %p\n", addr);
             return 0;
         }
         kvm_hwpoison_page_add(ram_addr);
-        kvm_mce_inject(x86_env_get_cpu(first_cpu), paddr, code);
+        kvm_mce_inject(X86_CPU(first_cpu), paddr, code);
     } else {
         if (code == BUS_MCEERR_AO) {
             return 0;
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index e345f9a..957926c 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -610,7 +610,7 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
     cpu = x86_env_get_cpu(env);
     cs = CPU(cpu);
     /* XXX: not complete but not completely erroneous */
-    if (cs->cpu_index != 0 || env->next_cpu != NULL) {
+    if (cs->cpu_index != 0 || cs->next_cpu != NULL) {
         /* more than one CPU: do not sleep because another CPU may
            wake this one */
     } else {
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index f6838ec..5cf1c3f 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1696,39 +1696,38 @@ target_ulong helper_emt(void)
 
 target_ulong helper_dvpe(CPUMIPSState *env)
 {
-    CPUMIPSState *other_cpu_env = first_cpu;
+    CPUState *other_cs = first_cpu;
     target_ulong prev = env->mvp->CP0_MVPControl;
 
     do {
+        MIPSCPU *other_cpu = MIPS_CPU(other_cs);
         /* Turn off all VPEs except the one executing the dvpe.  */
-        if (other_cpu_env != env) {
-            MIPSCPU *other_cpu = mips_env_get_cpu(other_cpu_env);
-
-            other_cpu_env->mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
+        if (&other_cpu->env != env) {
+            other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
             mips_vpe_sleep(other_cpu);
         }
-        other_cpu_env = other_cpu_env->next_cpu;
-    } while (other_cpu_env);
+        other_cs = other_cs->next_cpu;
+    } while (other_cs);
     return prev;
 }
 
 target_ulong helper_evpe(CPUMIPSState *env)
 {
-    CPUMIPSState *other_cpu_env = first_cpu;
+    CPUState *other_cs = first_cpu;
     target_ulong prev = env->mvp->CP0_MVPControl;
 
     do {
-        MIPSCPU *other_cpu = mips_env_get_cpu(other_cpu_env);
+        MIPSCPU *other_cpu = MIPS_CPU(other_cs);
 
-        if (other_cpu_env != env
+        if (&other_cpu->env != env
             /* If the VPE is WFI, don't disturb its sleep.  */
             && !mips_vpe_is_wfi(other_cpu)) {
             /* Enable the VPE.  */
-            other_cpu_env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
+            other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
             mips_vpe_wake(other_cpu); /* And wake it up.  */
         }
-        other_cpu_env = other_cpu_env->next_cpu;
-    } while (other_cpu_env);
+        other_cs = other_cs->next_cpu;
+    } while (other_cs);
     return prev;
 }
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 4a0fc6d..e9fcad8 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -986,16 +986,19 @@ void helper_msgsnd(target_ulong rb)
 {
     int irq = dbell2irq(rb);
     int pir = rb & DBELL_PIRTAG_MASK;
-    CPUPPCState *cenv;
+    CPUState *cs;
 
     if (irq < 0) {
         return;
     }
 
-    for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+        CPUPPCState *cenv = &cpu->env;
+
         if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
             cenv->pending_interrupts |= 1 << irq;
-            cpu_interrupt(CPU(ppc_env_get_cpu(cenv)), CPU_INTERRUPT_HARD);
+            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
         }
     }
 }
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 2bbc3b8..416c41e 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1574,7 +1574,7 @@ uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift)
 
     /* Find the largest hardware supported page size that's less than
      * or equal to the (logical) backing page size of guest RAM */
-    kvm_get_smmu_info(ppc_env_get_cpu(first_cpu), &info);
+    kvm_get_smmu_info(POWERPC_CPU(first_cpu), &info);
     rampagesize = getrampagesize();
     best_page_shift = 0;
 
diff --git a/translate-all.c b/translate-all.c
index 4177293..64cf855 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -681,7 +681,7 @@ static void page_flush_tb(void)
 /* XXX: tb_flush is currently not thread safe */
 void tb_flush(CPUArchState *env1)
 {
-    CPUArchState *env;
+    CPUState *cpu;
 
 #if defined(DEBUG_FLUSH)
     printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
@@ -696,7 +696,9 @@ void tb_flush(CPUArchState *env1)
     }
     tcg_ctx.tb_ctx.nb_tbs = 0;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         memset(env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *));
     }
 
@@ -821,7 +823,7 @@ static inline void tb_reset_jump(TranslationBlock *tb, int n)
 /* invalidate one TB */
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
 {
-    CPUArchState *env;
+    CPUState *cpu;
     PageDesc *p;
     unsigned int h, n1;
     tb_page_addr_t phys_pc;
@@ -848,7 +850,9 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
 
     /* 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) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         if (env->tb_jmp_cache[h] == tb) {
             env->tb_jmp_cache[h] = NULL;
         }
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 21/29] cpu: Make first_cpu and next_cpu CPUState
@ 2013-06-16 15:57   ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Anthony Liguori, Riku Voipio, Igor Mitsyanko,
	Mark Langsdorf, Evgeny Voevodin, Marcelo Tosatti, Alexander Graf,
	Gleb Natapov, Luiz Capitulino, Peter Crosthwaite,
	Andreas Färber, open list:PowerPC, Paul Brook, David Gibson,
	open list:Overall, Edgar E. Iglesias, Maksim Kozlov,
	Andreas Färber, Aurelien Jarno, Dmitry Solodkiy

Move first_cpu to qom/cpu.h.

gdbstub needs to use CPUState::env_ptr for now.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c                    | 126 ++++++++++++++++++++++++----------------------
 cputlb.c                  |   4 +-
 dump.c                    |  16 +++---
 exec.c                    |  43 ++++++++--------
 gdbstub.c                 |  33 +++++++-----
 hw/arm/boot.c             |  10 ++--
 hw/arm/exynos4_boards.c   |   4 +-
 hw/arm/highbank.c         |   2 +-
 hw/arm/realview.c         |   2 +-
 hw/arm/vexpress.c         |   2 +-
 hw/arm/xilinx_zynq.c      |   2 +-
 hw/i386/kvm/clock.c       |  12 +++--
 hw/i386/kvmvapic.c        |  13 +++--
 hw/i386/pc.c              |  17 ++++---
 hw/i386/pc_piix.c         |   3 +-
 hw/intc/sh_intc.c         |   5 +-
 hw/isa/lpc_ich9.c         |   2 +-
 hw/mips/mips_malta.c      |   3 +-
 hw/ppc/ppc.c              |  11 ++--
 hw/ppc/prep.c             |   6 ++-
 hw/ppc/spapr.c            |  27 +++++-----
 include/exec/cpu-all.h    |   1 -
 include/exec/cpu-defs.h   |   1 -
 include/qom/cpu.h         |   4 ++
 kvm-all.c                 |  20 +++++---
 linux-user/elfload.c      |   7 +--
 linux-user/main.c         |   8 ++-
 linux-user/syscall.c      |   9 ++--
 memory_mapping.c          |  16 +++---
 monitor.c                 |   4 +-
 target-i386/arch_dump.c   |   7 ++-
 target-i386/helper.c      |  15 +++---
 target-i386/kvm.c         |   8 +--
 target-i386/misc_helper.c |   2 +-
 target-mips/op_helper.c   |  25 +++++----
 target-ppc/excp_helper.c  |   9 ++--
 target-ppc/kvm.c          |   2 +-
 translate-all.c           |  12 +++--
 38 files changed, 267 insertions(+), 226 deletions(-)

diff --git a/cpus.c b/cpus.c
index 808503b..ec38644 100644
--- a/cpus.c
+++ b/cpus.c
@@ -60,7 +60,7 @@
 
 #endif /* CONFIG_LINUX */
 
-static CPUArchState *next_cpu;
+static CPUState *next_cpu;
 
 static bool cpu_thread_is_idle(CPUState *cpu)
 {
@@ -79,10 +79,10 @@ static bool cpu_thread_is_idle(CPUState *cpu)
 
 static bool all_cpu_threads_idle(void)
 {
-    CPUArchState *env;
+    CPUState *cpu;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        if (!cpu_thread_is_idle(ENV_GET_CPU(env))) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        if (!cpu_thread_is_idle(cpu)) {
             return false;
         }
     }
@@ -388,15 +388,13 @@ void configure_icount(const char *option)
 void hw_error(const char *fmt, ...)
 {
     va_list ap;
-    CPUArchState *env;
     CPUState *cpu;
 
     va_start(ap, fmt);
     fprintf(stderr, "qemu: hardware error: ");
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = ENV_GET_CPU(env);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
         cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU);
     }
@@ -406,28 +404,28 @@ void hw_error(const char *fmt, ...)
 
 void cpu_synchronize_all_states(void)
 {
-    CPUArchState *env;
+    CPUState *cpu;
 
-    for (env = first_cpu; env; env = env->next_cpu) {
-        cpu_synchronize_state(ENV_GET_CPU(env));
+    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
+        cpu_synchronize_state(cpu);
     }
 }
 
 void cpu_synchronize_all_post_reset(void)
 {
-    CPUArchState *cpu;
+    CPUState *cpu;
 
     for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
-        cpu_synchronize_post_reset(ENV_GET_CPU(cpu));
+        cpu_synchronize_post_reset(cpu);
     }
 }
 
 void cpu_synchronize_all_post_init(void)
 {
-    CPUArchState *cpu;
+    CPUState *cpu;
 
     for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
-        cpu_synchronize_post_init(ENV_GET_CPU(cpu));
+        cpu_synchronize_post_init(cpu);
     }
 }
 
@@ -698,7 +696,7 @@ static void qemu_wait_io_event_common(CPUState *cpu)
 
 static void qemu_tcg_wait_io_event(void)
 {
-    CPUArchState *env;
+    CPUState *cpu;
 
     while (all_cpu_threads_idle()) {
        /* Start accounting real time to the virtual clock if the CPUs
@@ -711,8 +709,8 @@ static void qemu_tcg_wait_io_event(void)
         qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex);
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        qemu_wait_io_event_common(ENV_GET_CPU(env));
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        qemu_wait_io_event_common(cpu);
     }
 }
 
@@ -814,7 +812,6 @@ static void tcg_signal_cpu_creation(CPUState *cpu, void *data)
 static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
     CPUState *cpu = arg;
-    CPUArchState *env;
 
     qemu_tcg_init_cpu_signals();
     qemu_thread_get_self(cpu->thread);
@@ -824,12 +821,12 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
     qemu_cond_signal(&qemu_cpu_cond);
 
     /* wait for initial kick-off after machine start */
-    while (ENV_GET_CPU(first_cpu)->stopped) {
+    while (first_cpu->stopped) {
         qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
 
         /* process any pending work */
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
-            qemu_wait_io_event_common(ENV_GET_CPU(env));
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            qemu_wait_io_event_common(cpu);
         }
     }
 
@@ -923,7 +920,7 @@ void qemu_mutex_lock_iothread(void)
     } else {
         iothread_requesting_mutex = true;
         if (qemu_mutex_trylock(&qemu_global_mutex)) {
-            qemu_cpu_kick_thread(ENV_GET_CPU(first_cpu));
+            qemu_cpu_kick_thread(first_cpu);
             qemu_mutex_lock(&qemu_global_mutex);
         }
         iothread_requesting_mutex = false;
@@ -938,14 +935,13 @@ void qemu_mutex_unlock_iothread(void)
 
 static int all_vcpus_paused(void)
 {
-    CPUArchState *penv = first_cpu;
+    CPUState *cpu = first_cpu;
 
-    while (penv) {
-        CPUState *pcpu = ENV_GET_CPU(penv);
-        if (!pcpu->stopped) {
+    while (cpu) {
+        if (!cpu->stopped) {
             return 0;
         }
-        penv = penv->next_cpu;
+        cpu = cpu->next_cpu;
     }
 
     return 1;
@@ -953,25 +949,23 @@ static int all_vcpus_paused(void)
 
 void pause_all_vcpus(void)
 {
-    CPUArchState *penv = first_cpu;
+    CPUState *cpu = first_cpu;
 
     qemu_clock_enable(vm_clock, false);
-    while (penv) {
-        CPUState *pcpu = ENV_GET_CPU(penv);
-        pcpu->stop = true;
-        qemu_cpu_kick(pcpu);
-        penv = penv->next_cpu;
+    while (cpu) {
+        cpu->stop = true;
+        qemu_cpu_kick(cpu);
+        cpu = cpu->next_cpu;
     }
 
     if (qemu_in_vcpu_thread()) {
         cpu_stop_current();
         if (!kvm_enabled()) {
-            penv = first_cpu;
-            while (penv) {
-                CPUState *pcpu = ENV_GET_CPU(penv);
-                pcpu->stop = false;
-                pcpu->stopped = true;
-                penv = penv->next_cpu;
+            cpu = first_cpu;
+            while (cpu) {
+                cpu->stop = false;
+                cpu->stopped = true;
+                cpu = cpu->next_cpu;
             }
             return;
         }
@@ -979,10 +973,10 @@ void pause_all_vcpus(void)
 
     while (!all_vcpus_paused()) {
         qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
-        penv = first_cpu;
-        while (penv) {
-            qemu_cpu_kick(ENV_GET_CPU(penv));
-            penv = penv->next_cpu;
+        cpu = first_cpu;
+        while (cpu) {
+            qemu_cpu_kick(cpu);
+            cpu = cpu->next_cpu;
         }
     }
 }
@@ -996,13 +990,12 @@ void cpu_resume(CPUState *cpu)
 
 void resume_all_vcpus(void)
 {
-    CPUArchState *penv = first_cpu;
+    CPUState *cpu = first_cpu;
 
     qemu_clock_enable(vm_clock, true);
-    while (penv) {
-        CPUState *pcpu = ENV_GET_CPU(penv);
-        cpu_resume(pcpu);
-        penv = penv->next_cpu;
+    while (cpu) {
+        cpu_resume(cpu);
+        cpu = cpu->next_cpu;
     }
 }
 
@@ -1151,8 +1144,8 @@ static void tcg_exec_all(void)
         next_cpu = first_cpu;
     }
     for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
-        CPUArchState *env = next_cpu;
-        CPUState *cpu = ENV_GET_CPU(env);
+        CPUState *cpu = next_cpu;
+        CPUArchState *env = cpu->env_ptr;
 
         qemu_clock_enable(vm_clock,
                           (env->singlestep_enabled & SSTEP_NOTIMER) == 0);
@@ -1172,12 +1165,10 @@ static void tcg_exec_all(void)
 
 void set_numa_modes(void)
 {
-    CPUArchState *env;
     CPUState *cpu;
     int i;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = ENV_GET_CPU(env);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         for (i = 0; i < nb_numa_nodes; i++) {
             if (test_bit(cpu->cpu_index, node_cpumask[i])) {
                 cpu->numa_node = i;
@@ -1197,18 +1188,30 @@ void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
 CpuInfoList *qmp_query_cpus(Error **errp)
 {
     CpuInfoList *head = NULL, *cur_item = NULL;
-    CPUArchState *env;
+    CPUState *cpu;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        CPUState *cpu = ENV_GET_CPU(env);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         CpuInfoList *info;
+#if defined(TARGET_I386)
+        X86CPU *x86_cpu = X86_CPU(cpu);
+        CPUX86State *env = &x86_cpu->env;
+#elif defined(TARGET_PPC)
+        PowerPCCPU *ppc_cpu = POWERPC_CPU(cpu);
+        CPUPPCState *env = &ppc_cpu->env;
+#elif defined(TARGET_SPARC)
+        SPARCCPU *sparc_cpu = SPARC_CPU(cpu);
+        CPUSPARCState *env = &sparc_cpu->env;
+#elif defined(TARGET_MIPS)
+        MIPSCPU *mips_cpu = MIPS_CPU(cpu);
+        CPUMIPSState *env = &mips_cpu->env;
+#endif
 
         cpu_synchronize_state(cpu);
 
         info = g_malloc0(sizeof(*info));
         info->value = g_malloc0(sizeof(*info->value));
         info->value->CPU = cpu->cpu_index;
-        info->value->current = (env == first_cpu);
+        info->value->current = (cpu == first_cpu);
         info->value->halted = cpu->halted;
         info->value->thread_id = cpu->thread_id;
 #if defined(TARGET_I386)
@@ -1316,11 +1319,14 @@ exit:
 void qmp_inject_nmi(Error **errp)
 {
 #if defined(TARGET_I386)
-    CPUArchState *env;
+    CPUState *cs;
+
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+        X86CPU *cpu = X86_CPU(cs);
+        CPUX86State *env = &cpu->env;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
         if (!env->apic_state) {
-            cpu_interrupt(CPU(x86_env_get_cpu(env)), CPU_INTERRUPT_NMI);
+            cpu_interrupt(cs, CPU_INTERRUPT_NMI);
         } else {
             apic_deliver_nmi(env->apic_state);
         }
diff --git a/cputlb.c b/cputlb.c
index 232c488..74b98ec 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -175,11 +175,13 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
 
 void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length)
 {
+    CPUState *cpu;
     CPUArchState *env;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         int mmu_idx;
 
+        env = cpu->env_ptr;
         for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
             unsigned int i;
 
diff --git a/dump.c b/dump.c
index 44a1339..e414515 100644
--- a/dump.c
+++ b/dump.c
@@ -275,13 +275,11 @@ static inline int cpu_index(CPUState *cpu)
 
 static int write_elf64_notes(DumpState *s)
 {
-    CPUArchState *env;
     CPUState *cpu;
     int ret;
     int id;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = ENV_GET_CPU(env);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         id = cpu_index(cpu);
         ret = cpu_write_elf64_note(fd_write_vmcore, cpu, id, s);
         if (ret < 0) {
@@ -290,7 +288,7 @@ static int write_elf64_notes(DumpState *s)
         }
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         ret = cpu_write_elf64_qemunote(fd_write_vmcore, cpu, s);
         if (ret < 0) {
             dump_error(s, "dump: failed to write CPU status.\n");
@@ -327,13 +325,11 @@ static int write_elf32_note(DumpState *s)
 
 static int write_elf32_notes(DumpState *s)
 {
-    CPUArchState *env;
     CPUState *cpu;
     int ret;
     int id;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = ENV_GET_CPU(env);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         id = cpu_index(cpu);
         ret = cpu_write_elf32_note(fd_write_vmcore, cpu, id, s);
         if (ret < 0) {
@@ -342,7 +338,7 @@ static int write_elf32_notes(DumpState *s)
         }
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         ret = cpu_write_elf32_qemunote(fd_write_vmcore, cpu, s);
         if (ret < 0) {
             dump_error(s, "dump: failed to write CPU status.\n");
@@ -705,7 +701,7 @@ static ram_addr_t get_start_block(DumpState *s)
 static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
                      int64_t begin, int64_t length, Error **errp)
 {
-    CPUArchState *env;
+    CPUState *cpu;
     int nr_cpus;
     Error *err = NULL;
     int ret;
@@ -738,7 +734,7 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
      */
     cpu_synchronize_all_states();
     nr_cpus = 0;
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         nr_cpus++;
     }
 
diff --git a/exec.c b/exec.c
index e14a815..191eb4e 100644
--- a/exec.c
+++ b/exec.c
@@ -70,7 +70,7 @@ static MemoryRegion io_mem_unassigned, io_mem_subpage_ram;
 
 #endif
 
-CPUArchState *first_cpu;
+CPUState *first_cpu;
 /* current CPU in the current thread. It is only valid inside
    cpu_exec() */
 DEFINE_TLS(CPUState *,cpu_single_cpu);
@@ -264,27 +264,26 @@ static const VMStateDescription vmstate_cpu_common = {
 
 CPUState *qemu_get_cpu(int index)
 {
-    CPUArchState *env = first_cpu;
-    CPUState *cpu = NULL;
+    CPUState *cpu = first_cpu;
 
-    while (env) {
-        cpu = ENV_GET_CPU(env);
+    while (cpu) {
         if (cpu->cpu_index == index) {
             break;
         }
-        env = env->next_cpu;
+        cpu = cpu->next_cpu;
     }
 
-    return env ? cpu : NULL;
+    return cpu;
 }
 
 void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data)
 {
-    CPUArchState *env = first_cpu;
+    CPUState *cpu;
 
-    while (env) {
-        func(ENV_GET_CPU(env), data);
-        env = env->next_cpu;
+    cpu = first_cpu;
+    while (cpu) {
+        func(cpu, data);
+        cpu = cpu->next_cpu;
     }
 }
 
@@ -292,17 +291,17 @@ void cpu_exec_init(CPUArchState *env)
 {
     CPUState *cpu = ENV_GET_CPU(env);
     CPUClass *cc = CPU_GET_CLASS(cpu);
-    CPUArchState **penv;
+    CPUState **pcpu;
     int cpu_index;
 
 #if defined(CONFIG_USER_ONLY)
     cpu_list_lock();
 #endif
-    env->next_cpu = NULL;
-    penv = &first_cpu;
+    cpu->next_cpu = NULL;
+    pcpu = &first_cpu;
     cpu_index = 0;
-    while (*penv != NULL) {
-        penv = &(*penv)->next_cpu;
+    while (*pcpu != NULL) {
+        pcpu = &(*pcpu)->next_cpu;
         cpu_index++;
     }
     cpu->cpu_index = cpu_index;
@@ -312,7 +311,7 @@ void cpu_exec_init(CPUArchState *env)
 #ifndef CONFIG_USER_ONLY
     cpu->thread_id = qemu_get_thread_id();
 #endif
-    *penv = env;
+    *pcpu = cpu;
 #if defined(CONFIG_USER_ONLY)
     cpu_list_unlock();
 #endif
@@ -551,7 +550,7 @@ void cpu_abort(CPUArchState *env, const char *fmt, ...)
 CPUArchState *cpu_copy(CPUArchState *env)
 {
     CPUArchState *new_env = cpu_init(env->cpu_model_str);
-    CPUArchState *next_cpu = new_env->next_cpu;
+    CPUState *next_cpu = ENV_GET_CPU(new_env)->next_cpu;
 #if defined(TARGET_HAS_ICE)
     CPUBreakpoint *bp;
     CPUWatchpoint *wp;
@@ -560,7 +559,7 @@ CPUArchState *cpu_copy(CPUArchState *env)
     memcpy(new_env, env, sizeof(CPUArchState));
 
     /* Preserve chaining. */
-    new_env->next_cpu = next_cpu;
+    ENV_GET_CPU(new_env)->next_cpu = next_cpu;
 
     /* Clone all break/watchpoints.
        Note: Once we support ptrace with hw-debug register access, make sure
@@ -1707,12 +1706,14 @@ static void core_begin(MemoryListener *listener)
 
 static void tcg_commit(MemoryListener *listener)
 {
-    CPUArchState *env;
+    CPUState *cpu;
 
     /* since each CPU stores ram addresses in its TLB cache, we must
        reset the modified entries */
     /* XXX: slow ! */
-    for(env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         tlb_flush(env, 1);
     }
 }
diff --git a/gdbstub.c b/gdbstub.c
index 9e7f7a1..5793bcd 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1839,6 +1839,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
         /* Generate the XML description for this CPU.  */
         if (!target_xml[0]) {
             GDBRegisterState *r;
+            CPUArchState *env = first_cpu->env_ptr;
 
             snprintf(target_xml, sizeof(target_xml),
                      "<?xml version=\"1.0\"?>"
@@ -1847,7 +1848,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
                      "<xi:include href=\"%s\"/>",
                      GDB_CORE_XML);
 
-            for (r = first_cpu->gdb_regs; r; r = r->next) {
+            for (r = env->gdb_regs; r; r = r->next) {
                 pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
                 pstrcat(target_xml, sizeof(target_xml), r->xml);
                 pstrcat(target_xml, sizeof(target_xml), "\"/>");
@@ -1949,6 +1950,7 @@ static const int xlat_gdb_type[] = {
 
 static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
 {
+    CPUState *cpu;
     CPUArchState *env;
     int err = 0;
 
@@ -1958,7 +1960,8 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
     switch (type) {
     case GDB_BREAKPOINT_SW:
     case GDB_BREAKPOINT_HW:
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            env = cpu->env_ptr;
             err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
             if (err)
                 break;
@@ -1968,7 +1971,8 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
     case GDB_WATCHPOINT_WRITE:
     case GDB_WATCHPOINT_READ:
     case GDB_WATCHPOINT_ACCESS:
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            env = cpu->env_ptr;
             err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
                                         NULL);
             if (err)
@@ -1983,6 +1987,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
 
 static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
 {
+    CPUState *cpu;
     CPUArchState *env;
     int err = 0;
 
@@ -1992,7 +1997,8 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     switch (type) {
     case GDB_BREAKPOINT_SW:
     case GDB_BREAKPOINT_HW:
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            env = cpu->env_ptr;
             err = cpu_breakpoint_remove(env, addr, BP_GDB);
             if (err)
                 break;
@@ -2002,7 +2008,8 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     case GDB_WATCHPOINT_WRITE:
     case GDB_WATCHPOINT_READ:
     case GDB_WATCHPOINT_ACCESS:
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            env = cpu->env_ptr;
             err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
             if (err)
                 break;
@@ -2016,6 +2023,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
 
 static void gdb_breakpoint_remove_all(void)
 {
+    CPUState *cpu;
     CPUArchState *env;
 
     if (kvm_enabled()) {
@@ -2023,7 +2031,8 @@ static void gdb_breakpoint_remove_all(void)
         return;
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        env = cpu->env_ptr;
         cpu_breakpoint_remove_all(env, BP_GDB);
 #ifndef CONFIG_USER_ONLY
         cpu_watchpoint_remove_all(env, BP_GDB);
@@ -2390,7 +2399,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet(s, "QC1");
             break;
         } else if (strcmp(p,"fThreadInfo") == 0) {
-            s->query_cpu = first_cpu;
+            s->query_cpu = first_cpu->env_ptr;
             goto report_cpuinfo;
         } else if (strcmp(p,"sThreadInfo") == 0) {
         report_cpuinfo:
@@ -2398,7 +2407,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
                 snprintf(buf, sizeof(buf), "m%x",
                          cpu_index(ENV_GET_CPU(s->query_cpu)));
                 put_packet(s, buf);
-                s->query_cpu = s->query_cpu->next_cpu;
+                s->query_cpu = ENV_GET_CPU(s->query_cpu)->next_cpu->env_ptr;
             } else
                 put_packet(s, "l");
             break;
@@ -2865,8 +2874,8 @@ static void gdb_accept(void)
     socket_set_nodelay(fd);
 
     s = g_malloc0(sizeof(GDBState));
-    s->c_cpu = first_cpu;
-    s->g_cpu = first_cpu;
+    s->c_cpu = first_cpu->env_ptr;
+    s->g_cpu = first_cpu->env_ptr;
     s->fd = fd;
     gdb_has_xml = 0;
 
@@ -3050,8 +3059,8 @@ int gdbserver_start(const char *device)
         mon_chr = s->mon_chr;
         memset(s, 0, sizeof(GDBState));
     }
-    s->c_cpu = first_cpu;
-    s->g_cpu = first_cpu;
+    s->c_cpu = first_cpu->env_ptr;
+    s->g_cpu = first_cpu->env_ptr;
     s->chr = chr;
     s->state = chr ? RS_IDLE : RS_INACTIVE;
     s->mon_chr = mon_chr;
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index f451529..ad13d3f 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -329,7 +329,7 @@ static void do_cpu_reset(void *opaque)
             env->regs[15] = info->entry & 0xfffffffe;
             env->thumb = info->entry & 1;
         } else {
-            if (env == first_cpu) {
+            if (CPU(cpu) == first_cpu) {
                 env->regs[15] = info->loader_start;
                 if (!info->dtb_filename) {
                     if (old_param) {
@@ -347,7 +347,7 @@ static void do_cpu_reset(void *opaque)
 
 void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
 {
-    CPUARMState *env = &cpu->env;
+    CPUState *cs = CPU(cpu);
     int kernel_size;
     int initrd_size;
     int n;
@@ -472,9 +472,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
     }
     info->is_linux = is_linux;
 
-    for (; env; env = env->next_cpu) {
-        cpu = arm_env_get_cpu(env);
-        env->boot_info = info;
+    for (; cs; cs = cs->next_cpu) {
+        cpu = ARM_CPU(cs);
+        cpu->env.boot_info = info;
         qemu_register_reset(do_cpu_reset, cpu);
     }
 }
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
index 74f110b..7c90b2d 100644
--- a/hw/arm/exynos4_boards.c
+++ b/hw/arm/exynos4_boards.c
@@ -131,7 +131,7 @@ static void nuri_init(QEMUMachineInitArgs *args)
 {
     exynos4_boards_init_common(args, EXYNOS4_BOARD_NURI);
 
-    arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
+    arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo);
 }
 
 static void smdkc210_init(QEMUMachineInitArgs *args)
@@ -141,7 +141,7 @@ static void smdkc210_init(QEMUMachineInitArgs *args)
 
     lan9215_init(SMDK_LAN9118_BASE_ADDR,
             qemu_irq_invert(s->irq_table[exynos4210_get_irq(37, 1)]));
-    arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
+    arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo);
 }
 
 static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS] = {
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 4405dbd..1d28842 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -321,7 +321,7 @@ static void highbank_init(QEMUMachineInitArgs *args)
     highbank_binfo.loader_start = 0;
     highbank_binfo.write_secondary_boot = hb_write_secondary;
     highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary;
-    arm_load_kernel(arm_env_get_cpu(first_cpu), &highbank_binfo);
+    arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo);
 }
 
 static QEMUMachine highbank_machine = {
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index d6f47bf..05dc3f3 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -329,7 +329,7 @@ static void realview_init(QEMUMachineInitArgs *args,
     realview_binfo.nb_cpus = smp_cpus;
     realview_binfo.board_id = realview_board_id[board_type];
     realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0);
-    arm_load_kernel(arm_env_get_cpu(first_cpu), &realview_binfo);
+    arm_load_kernel(ARM_CPU(first_cpu), &realview_binfo);
 }
 
 static void realview_eb_init(QEMUMachineInitArgs *args)
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index a077c62..c8f2890 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -519,7 +519,7 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard,
     vexpress_binfo.smp_loader_start = map[VE_SRAM];
     vexpress_binfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30;
     vexpress_binfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr;
-    arm_load_kernel(arm_env_get_cpu(first_cpu), &vexpress_binfo);
+    arm_load_kernel(ARM_CPU(first_cpu), &vexpress_binfo);
 }
 
 static void vexpress_a9_init(QEMUMachineInitArgs *args)
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 4602a6f..f73eeed 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -226,7 +226,7 @@ static void zynq_init(QEMUMachineInitArgs *args)
     zynq_binfo.nb_cpus = 1;
     zynq_binfo.board_id = 0xd32;
     zynq_binfo.loader_start = 0;
-    arm_load_kernel(arm_env_get_cpu(first_cpu), &zynq_binfo);
+    arm_load_kernel(ARM_CPU(first_cpu), &zynq_binfo);
 }
 
 static QEMUMachine zynq_machine = {
diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 87d4d0f..eba275a 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -65,7 +65,7 @@ static void kvmclock_vm_state_change(void *opaque, int running,
                                      RunState state)
 {
     KVMClockState *s = opaque;
-    CPUArchState *penv = first_cpu;
+    CPUState *cpu = first_cpu;
     int cap_clock_ctrl = kvm_check_extension(kvm_state, KVM_CAP_KVMCLOCK_CTRL);
     int ret;
 
@@ -75,8 +75,8 @@ static void kvmclock_vm_state_change(void *opaque, int running,
         if (!cap_clock_ctrl) {
             return;
         }
-        for (penv = first_cpu; penv != NULL; penv = penv->next_cpu) {
-            ret = kvm_vcpu_ioctl(ENV_GET_CPU(penv), KVM_KVMCLOCK_CTRL, 0);
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            ret = kvm_vcpu_ioctl(cpu, KVM_KVMCLOCK_CTRL, 0);
             if (ret) {
                 if (ret != -EINVAL) {
                     fprintf(stderr, "%s: %s\n", __func__, strerror(-ret));
@@ -128,9 +128,11 @@ static const TypeInfo kvmclock_info = {
 /* Note: Must be called after VCPU initialization. */
 void kvmclock_create(void)
 {
+    X86CPU *cpu = X86_CPU(first_cpu);
+
     if (kvm_enabled() &&
-        first_cpu->features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
-                                         (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
+        cpu->env.features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
+                                       (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
         sysbus_create_simple("kvmclock", -1, NULL);
     }
 }
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 9aac9de..5538071 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -490,13 +490,15 @@ static void vapic_enable_tpr_reporting(bool enable)
     VAPICEnableTPRReporting info = {
         .enable = enable,
     };
+    CPUState *cs;
     X86CPU *cpu;
     CPUX86State *env;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = x86_env_get_cpu(env);
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+        cpu = X86_CPU(cs);
+        env = &cpu->env;
         info.apic = env->apic_state;
-        run_on_cpu(CPU(cpu), vapic_do_enable_tpr_reporting, &info);
+        run_on_cpu(cs, vapic_do_enable_tpr_reporting, &info);
     }
 }
 
@@ -718,8 +720,9 @@ static int vapic_init(SysBusDevice *dev)
 static void do_vapic_enable(void *data)
 {
     VAPICROMState *s = data;
+    X86CPU *cpu = X86_CPU(first_cpu);
 
-    vapic_enable(s, first_cpu);
+    vapic_enable(s, &cpu->env);
 }
 
 static int vapic_post_load(void *opaque, int version_id)
@@ -742,7 +745,7 @@ static int vapic_post_load(void *opaque, int version_id)
     }
     if (s->state == VAPIC_ACTIVE) {
         if (smp_cpus == 1) {
-            run_on_cpu(ENV_GET_CPU(first_cpu), do_vapic_enable, s);
+            run_on_cpu(first_cpu, do_vapic_enable, s);
         } else {
             zero = g_malloc0(s->rom_state.vapic_size);
             cpu_physical_memory_rw(s->vapic_paddr, zero,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c43be54..38722a1 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -160,8 +160,9 @@ void cpu_smm_register(cpu_set_smm_t callback, void *arg)
 
 void cpu_smm_update(CPUX86State *env)
 {
-    if (smm_set && smm_arg && env == first_cpu)
+    if (smm_set && smm_arg && CPU(x86_env_get_cpu(env)) == first_cpu) {
         smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
+    }
 }
 
 
@@ -185,18 +186,21 @@ int cpu_get_pic_interrupt(CPUX86State *env)
 
 static void pic_irq_request(void *opaque, int irq, int level)
 {
-    CPUX86State *env = first_cpu;
+    CPUState *cs = first_cpu;
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
 
     DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq);
     if (env->apic_state) {
-        while (env) {
+        while (cs) {
+            cpu = X86_CPU(cs);
+            env = &cpu->env;
             if (apic_accept_pic_intr(env->apic_state)) {
                 apic_deliver_pic_intr(env->apic_state, level);
             }
-            env = env->next_cpu;
+            cs = cs->next_cpu;
         }
     } else {
-        CPUState *cs = CPU(x86_env_get_cpu(env));
         if (level) {
             cpu_interrupt(cs, CPU_INTERRUPT_HARD);
         } else {
@@ -1205,8 +1209,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
         }
     }
 
-    a20_line = qemu_allocate_irqs(handle_a20_line_change,
-                                  x86_env_get_cpu(first_cpu), 2);
+    a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2);
     i8042 = isa_create_simple(isa_bus, "i8042");
     i8042_setup_a20_line(i8042, &a20_line[0]);
     if (!no_vmport) {
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 97362f2..f3bf240 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -213,8 +213,7 @@ static void pc_init1(MemoryRegion *system_memory,
     if (pci_enabled && acpi_enabled) {
         i2c_bus *smbus;
 
-        smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt,
-                                     x86_env_get_cpu(first_cpu), 1);
+        smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
         /* TODO: Populate SPD eeprom data.  */
         smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
                               gsi[9], *smi_irq,
diff --git a/hw/intc/sh_intc.c b/hw/intc/sh_intc.c
index 050bfb6..f1138e3 100644
--- a/hw/intc/sh_intc.c
+++ b/hw/intc/sh_intc.c
@@ -42,16 +42,15 @@ void sh_intc_toggle_source(struct intc_source *source,
         pending_changed = 1;
 
     if (pending_changed) {
-        CPUState *cpu = CPU(sh_env_get_cpu(first_cpu));
         if (source->pending) {
             source->parent->pending++;
             if (source->parent->pending == 1) {
-                cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
+                cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD);
             }
         } else {
             source->parent->pending--;
             if (source->parent->pending == 0) {
-                cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
+                cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD);
             }
 	}
     }
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 667e882..69e1f50 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -380,7 +380,7 @@ static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
 
     /* SMI_EN = PMBASE + 30. SMI control and enable register */
     if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) {
-        cpu_interrupt(CPU(x86_env_get_cpu(first_cpu)), CPU_INTERRUPT_SMI);
+        cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
     }
 }
 
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 4fc611c..adea146 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -844,7 +844,8 @@ void mips_malta_init(QEMUMachineInitArgs *args)
         cpu_mips_clock_init(env);
         qemu_register_reset(main_cpu_reset, cpu);
     }
-    env = first_cpu;
+    cpu = MIPS_CPU(first_cpu);
+    env = &cpu->env;
 
     /* allocate RAM */
     if (ram_size > (256 << 20)) {
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index fb57b42..554f244 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -440,15 +440,14 @@ void ppce500_irq_init(CPUPPCState *env)
 /* Enable or Disable the E500 EPR capability */
 void ppce500_set_mpic_proxy(bool enabled)
 {
-    CPUPPCState *env;
+    CPUState *cs;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        PowerPCCPU *cpu = ppc_env_get_cpu(env);
-        CPUState *cs = CPU(cpu);
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
 
-        env->mpic_proxy = enabled;
+        cpu->env.mpic_proxy = enabled;
         if (kvm_enabled()) {
-            kvmppc_set_mpic_proxy(POWERPC_CPU(cs), enabled);
+            kvmppc_set_mpic_proxy(cpu, enabled);
         }
     }
 }
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 16e3132..45625ca 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -594,8 +594,9 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
     /* PCI -> ISA bridge */
     pci = pci_create_simple(pci_bus, PCI_DEVFN(1, 0), "i82378");
     cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
+    cpu = POWERPC_CPU(first_cpu);
     qdev_connect_gpio_out(&pci->qdev, 0,
-                          first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
+                          cpu->env.irq_inputs[PPC6xx_INPUT_INT]);
     qdev_connect_gpio_out(&pci->qdev, 1, *cpu_exit_irq);
     sysbus_connect_irq(&pcihost->busdev, 0, qdev_get_gpio_in(&pci->qdev, 9));
     sysbus_connect_irq(&pcihost->busdev, 1, qdev_get_gpio_in(&pci->qdev, 11));
@@ -640,7 +641,8 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
     }
     isa_create_simple(isa_bus, "i8042");
 
-    sysctrl->reset_irq = first_cpu->irq_inputs[PPC6xx_INPUT_HRESET];
+    cpu = POWERPC_CPU(first_cpu);
+    sysctrl->reset_irq = cpu->env.irq_inputs[PPC6xx_INPUT_HRESET];
     /* System control ports */
     register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);
     register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 218ea23..4fce87a 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -131,7 +131,6 @@ int spapr_allocate_irq_block(int num, bool lsi)
 static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
 {
     int ret = 0, offset;
-    CPUPPCState *env;
     CPUState *cpu;
     char cpu_model[32];
     int smt = kvmppc_smt_threads();
@@ -139,8 +138,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
 
     assert(spapr->cpu_model);
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cpu = CPU(ppc_env_get_cpu(env));
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         uint32_t associativity[] = {cpu_to_be32(0x5),
                                     cpu_to_be32(0x0),
                                     cpu_to_be32(0x0),
@@ -231,7 +229,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
                                    uint32_t epow_irq)
 {
     void *fdt;
-    CPUPPCState *env;
+    CPUState *cs;
     uint32_t start_prop = cpu_to_be32(initrd_base);
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
     char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
@@ -304,10 +302,11 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
     /* This is needed during FDT finalization */
     spapr->cpu_model = g_strdup(modelname);
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        CPUState *cpu = CPU(ppc_env_get_cpu(env));
-        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
-        int index = cpu->cpu_index;
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+        CPUPPCState *env = &cpu->env;
+        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
+        int index = cs->cpu_index;
         uint32_t servers_prop[smp_threads];
         uint32_t gservers_prop[smp_threads * 2];
         char *nodename;
@@ -632,7 +631,7 @@ static void spapr_reset_htab(sPAPREnvironment *spapr)
 
 static void ppc_spapr_reset(void)
 {
-    CPUState *first_cpu_cpu;
+    PowerPCCPU *first_ppc_cpu;
 
     /* Reset the hash table & recalc the RMA */
     spapr_reset_htab(spapr);
@@ -644,11 +643,11 @@ static void ppc_spapr_reset(void)
                        spapr->rtas_size);
 
     /* Set up the entry state */
-    first_cpu_cpu = ENV_GET_CPU(first_cpu);
-    first_cpu->gpr[3] = spapr->fdt_addr;
-    first_cpu->gpr[5] = 0;
-    first_cpu_cpu->halted = 0;
-    first_cpu->nip = spapr->entry_point;
+    first_ppc_cpu = POWERPC_CPU(first_cpu);
+    first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
+    first_ppc_cpu->env.gpr[5] = 0;
+    first_cpu->halted = 0;
+    first_ppc_cpu->env.nip = spapr->entry_point;
 
 }
 
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 6760851..6499cd0 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -356,7 +356,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
 
 void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
-extern CPUArchState *first_cpu;
 
 /* Flags for use in ENV->INTERRUPT_PENDING.
 
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index c4ac929..39094b3 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -181,7 +181,6 @@ typedef struct CPUWatchpoint {
     sigjmp_buf jmp_env;                                                 \
     int exception_index;                                                \
                                                                         \
-    CPUArchState *next_cpu; /* next CPU sharing TB cache */                 \
     /* user data */                                                     \
     void *opaque;                                                       \
                                                                         \
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 0e2e76c..2a64af2 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -114,6 +114,7 @@ struct kvm_run;
  *           CPU and return to its top level loop.
  * @env_ptr: Pointer to subclass-specific CPUArchState field.
  * @current_tb: Currently executing TB.
+ * @next_cpu: Next CPU sharing TB cache.
  * @kvm_fd: vCPU file descriptor for KVM.
  *
  * State of one CPU core or thread.
@@ -146,6 +147,7 @@ struct CPUState {
 
     void *env_ptr; /* CPUArchState */
     struct TranslationBlock *current_tb;
+    CPUState *next_cpu;
 
     int kvm_fd;
     bool kvm_vcpu_dirty;
@@ -157,6 +159,8 @@ struct CPUState {
     uint32_t halted; /* used by alpha, cris, ppc TCG */
 };
 
+extern CPUState *first_cpu;
+
 DECLARE_TLS(CPUState *, cpu_single_cpu);
 #define cpu_single_cpu tls_var(cpu_single_cpu)
 
diff --git a/kvm-all.c b/kvm-all.c
index b3ba6aa..6b9e343 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1896,7 +1896,7 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
 {
     CPUState *current_cpu = ENV_GET_CPU(current_env);
     struct kvm_sw_breakpoint *bp;
-    CPUArchState *env;
+    CPUState *cpu;
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
@@ -1928,7 +1928,9 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
         }
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         err = kvm_update_guest_debug(env, 0);
         if (err) {
             return err;
@@ -1942,7 +1944,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
 {
     CPUState *current_cpu = ENV_GET_CPU(current_env);
     struct kvm_sw_breakpoint *bp;
-    CPUArchState *env;
+    CPUState *cpu;
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
@@ -1970,7 +1972,9 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
         }
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         err = kvm_update_guest_debug(env, 0);
         if (err) {
             return err;
@@ -1983,14 +1987,12 @@ void kvm_remove_all_breakpoints(CPUState *current_cpu)
 {
     struct kvm_sw_breakpoint *bp, *next;
     KVMState *s = current_cpu->kvm_state;
-    CPUArchState *env;
     CPUState *cpu;
 
     QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
         if (kvm_arch_remove_sw_breakpoint(current_cpu, bp) != 0) {
             /* Try harder to find a CPU that currently sees the breakpoint. */
-            for (env = first_cpu; env != NULL; env = env->next_cpu) {
-                cpu = ENV_GET_CPU(env);
+            for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
                 if (kvm_arch_remove_sw_breakpoint(cpu, bp) == 0) {
                     break;
                 }
@@ -2001,7 +2003,9 @@ void kvm_remove_all_breakpoints(CPUState *current_cpu)
     }
     kvm_arch_remove_all_hw_breakpoints();
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         kvm_update_guest_debug(env, 0);
     }
 }
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ddef23e..d517450 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2628,7 +2628,7 @@ static int fill_note_info(struct elf_note_info *info,
                           long signr, const CPUArchState *env)
 {
 #define NUMNOTES 3
-    CPUArchState *cpu = NULL;
+    CPUState *cpu = NULL;
     TaskState *ts = (TaskState *)env->opaque;
     int i;
 
@@ -2667,9 +2667,10 @@ static int fill_note_info(struct elf_note_info *info,
     /* read and fill status of all threads */
     cpu_list_lock();
     for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
-        if (cpu == thread_env)
+        if (cpu == ENV_GET_CPU(thread_env)) {
             continue;
-        fill_thread_info(info, cpu);
+        }
+        fill_thread_info(info, (CPUArchState *)cpu->env_ptr);
     }
     cpu_list_unlock();
 
diff --git a/linux-user/main.c b/linux-user/main.c
index 95e17cf..3e60877 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -120,8 +120,8 @@ void fork_end(int child)
     if (child) {
         /* Child processes created by fork() only have a single thread.
            Discard information about the parent threads.  */
-        first_cpu = thread_env;
-        thread_env->next_cpu = NULL;
+        first_cpu = ENV_GET_CPU(thread_env);
+        first_cpu->next_cpu = NULL;
         pending_cpus = 0;
         pthread_mutex_init(&exclusive_lock, NULL);
         pthread_mutex_init(&cpu_list_mutex, NULL);
@@ -148,7 +148,6 @@ static inline void exclusive_idle(void)
    Must only be called from outside cpu_arm_exec.   */
 static inline void start_exclusive(void)
 {
-    CPUArchState *other;
     CPUState *other_cpu;
 
     pthread_mutex_lock(&exclusive_lock);
@@ -156,8 +155,7 @@ static inline void start_exclusive(void)
 
     pending_cpus = 1;
     /* Make all other cpus stop executing.  */
-    for (other = first_cpu; other; other = other->next_cpu) {
-        other_cpu = ENV_GET_CPU(other);
+    for (other_cpu = first_cpu; other_cpu; other_cpu = other_cpu->next_cpu) {
         if (other_cpu->running) {
             pending_cpus++;
             cpu_exit(other_cpu);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index cdd0c28..340666f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5030,6 +5030,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     abi_long arg5, abi_long arg6, abi_long arg7,
                     abi_long arg8)
 {
+#ifdef CONFIG_USE_NPTL
+    CPUState *cpu = ENV_GET_CPU(cpu_env);
+#endif
     abi_long ret;
     struct stat st;
     struct statfs stfs;
@@ -5052,13 +5055,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
          be disabling signals.  */
       if (first_cpu->next_cpu) {
           TaskState *ts;
-          CPUArchState **lastp;
-          CPUArchState *p;
+          CPUState **lastp;
+          CPUState *p;
 
           cpu_list_lock();
           lastp = &first_cpu;
           p = first_cpu;
-          while (p && p != (CPUArchState *)cpu_env) {
+          while (p && p != cpu) {
               lastp = &p->next_cpu;
               p = p->next_cpu;
           }
diff --git a/memory_mapping.c b/memory_mapping.c
index 5634f81..515a984 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -165,13 +165,13 @@ void memory_mapping_list_init(MemoryMappingList *list)
     QTAILQ_INIT(&list->head);
 }
 
-static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
+static CPUState *find_paging_enabled_cpu(CPUState *start_cpu)
 {
-    CPUArchState *env;
+    CPUState *cpu;
 
-    for (env = start_cpu; env != NULL; env = env->next_cpu) {
-        if (cpu_paging_enabled(ENV_GET_CPU(env))) {
-            return env;
+    for (cpu = start_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        if (cpu_paging_enabled(cpu)) {
+            return cpu;
         }
     }
 
@@ -180,15 +180,15 @@ static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
 
 void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp)
 {
-    CPUArchState *env, *first_paging_enabled_cpu;
+    CPUState *cpu, *first_paging_enabled_cpu;
     RAMBlock *block;
     ram_addr_t offset, length;
 
     first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu);
     if (first_paging_enabled_cpu) {
-        for (env = first_paging_enabled_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_paging_enabled_cpu; cpu != NULL; cpu = cpu->next_cpu) {
             Error *err = NULL;
-            cpu_get_memory_mapping(ENV_GET_CPU(env), list, &err);
+            cpu_get_memory_mapping(cpu, list, &err);
             if (err) {
                 error_propagate(errp, err);
                 return;
diff --git a/monitor.c b/monitor.c
index 9be515c..2ba7876 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1806,14 +1806,12 @@ static void do_info_mtree(Monitor *mon, const QDict *qdict)
 static void do_info_numa(Monitor *mon, const QDict *qdict)
 {
     int i;
-    CPUArchState *env;
     CPUState *cpu;
 
     monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
     for (i = 0; i < nb_numa_nodes; i++) {
         monitor_printf(mon, "node %d cpus:", i);
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
-            cpu = ENV_GET_CPU(env);
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
             if (cpu->numa_node == i) {
                 monitor_printf(mon, " %d", cpu->cpu_index);
             }
diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
index 83898cd..d133228 100644
--- a/target-i386/arch_dump.c
+++ b/target-i386/arch_dump.c
@@ -185,7 +185,8 @@ int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
     X86CPU *cpu = X86_CPU(cs);
     int ret;
 #ifdef TARGET_X86_64
-    bool lma = !!(first_cpu->hflags & HF_LMA_MASK);
+    X86CPU *first_x86_cpu = X86_CPU(first_cpu);
+    bool lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);
 
     if (lma) {
         ret = x86_64_write_elf64_note(f, &cpu->env, cpuid, opaque);
@@ -394,7 +395,9 @@ int cpu_get_dump_info(ArchDumpInfo *info)
     RAMBlock *block;
 
 #ifdef TARGET_X86_64
-    lma = !!(first_cpu->hflags & HF_LMA_MASK);
+    X86CPU *first_x86_cpu = X86_CPU(first_cpu);
+
+    lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);
 #endif
 
     if (lma) {
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 5e5abe3..d6f43d7 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1188,6 +1188,7 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
                         uint64_t status, uint64_t mcg_status, uint64_t addr,
                         uint64_t misc, int flags)
 {
+    CPUState *cs = CPU(cpu);
     CPUX86State *cenv = &cpu->env;
     MCEInjectionParams params = {
         .mon = mon,
@@ -1200,7 +1201,6 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
         .flags = flags,
     };
     unsigned bank_num = cenv->mcg_cap & 0xff;
-    CPUX86State *env;
 
     if (!cenv->mcg_cap) {
         monitor_printf(mon, "MCE injection not supported\n");
@@ -1220,19 +1220,22 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
         return;
     }
 
-    run_on_cpu(CPU(cpu), do_inject_x86_mce, &params);
+    run_on_cpu(cs, do_inject_x86_mce, &params);
     if (flags & MCE_INJECT_BROADCAST) {
+        CPUState *other_cs;
+
         params.bank = 1;
         params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
         params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
         params.addr = 0;
         params.misc = 0;
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
-            if (cenv == env) {
+        for (other_cs = first_cpu; other_cs != NULL;
+             other_cs = other_cs->next_cpu) {
+            if (other_cs == cs) {
                 continue;
             }
-            params.cpu = x86_env_get_cpu(env);
-            run_on_cpu(CPU(cpu), do_inject_x86_mce, &params);
+            params.cpu = X86_CPU(other_cs);
+            run_on_cpu(other_cs, do_inject_x86_mce, &params);
         }
     }
 }
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 39f4fbb..cc3dcec 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -345,20 +345,22 @@ int kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
 
 int kvm_arch_on_sigbus(int code, void *addr)
 {
-    if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
+    X86CPU *cpu = X86_CPU(first_cpu);
+
+    if ((cpu->env.mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
         ram_addr_t ram_addr;
         hwaddr paddr;
 
         /* Hope we are lucky for AO MCE */
         if (qemu_ram_addr_from_host(addr, &ram_addr) ||
-            !kvm_physical_memory_addr_from_host(CPU(first_cpu)->kvm_state,
+            !kvm_physical_memory_addr_from_host(first_cpu->kvm_state,
                                                 addr, &paddr)) {
             fprintf(stderr, "Hardware memory error for memory used by "
                     "QEMU itself instead of guest system!: %p\n", addr);
             return 0;
         }
         kvm_hwpoison_page_add(ram_addr);
-        kvm_mce_inject(x86_env_get_cpu(first_cpu), paddr, code);
+        kvm_mce_inject(X86_CPU(first_cpu), paddr, code);
     } else {
         if (code == BUS_MCEERR_AO) {
             return 0;
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index e345f9a..957926c 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -610,7 +610,7 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
     cpu = x86_env_get_cpu(env);
     cs = CPU(cpu);
     /* XXX: not complete but not completely erroneous */
-    if (cs->cpu_index != 0 || env->next_cpu != NULL) {
+    if (cs->cpu_index != 0 || cs->next_cpu != NULL) {
         /* more than one CPU: do not sleep because another CPU may
            wake this one */
     } else {
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index f6838ec..5cf1c3f 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1696,39 +1696,38 @@ target_ulong helper_emt(void)
 
 target_ulong helper_dvpe(CPUMIPSState *env)
 {
-    CPUMIPSState *other_cpu_env = first_cpu;
+    CPUState *other_cs = first_cpu;
     target_ulong prev = env->mvp->CP0_MVPControl;
 
     do {
+        MIPSCPU *other_cpu = MIPS_CPU(other_cs);
         /* Turn off all VPEs except the one executing the dvpe.  */
-        if (other_cpu_env != env) {
-            MIPSCPU *other_cpu = mips_env_get_cpu(other_cpu_env);
-
-            other_cpu_env->mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
+        if (&other_cpu->env != env) {
+            other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
             mips_vpe_sleep(other_cpu);
         }
-        other_cpu_env = other_cpu_env->next_cpu;
-    } while (other_cpu_env);
+        other_cs = other_cs->next_cpu;
+    } while (other_cs);
     return prev;
 }
 
 target_ulong helper_evpe(CPUMIPSState *env)
 {
-    CPUMIPSState *other_cpu_env = first_cpu;
+    CPUState *other_cs = first_cpu;
     target_ulong prev = env->mvp->CP0_MVPControl;
 
     do {
-        MIPSCPU *other_cpu = mips_env_get_cpu(other_cpu_env);
+        MIPSCPU *other_cpu = MIPS_CPU(other_cs);
 
-        if (other_cpu_env != env
+        if (&other_cpu->env != env
             /* If the VPE is WFI, don't disturb its sleep.  */
             && !mips_vpe_is_wfi(other_cpu)) {
             /* Enable the VPE.  */
-            other_cpu_env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
+            other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
             mips_vpe_wake(other_cpu); /* And wake it up.  */
         }
-        other_cpu_env = other_cpu_env->next_cpu;
-    } while (other_cpu_env);
+        other_cs = other_cs->next_cpu;
+    } while (other_cs);
     return prev;
 }
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 4a0fc6d..e9fcad8 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -986,16 +986,19 @@ void helper_msgsnd(target_ulong rb)
 {
     int irq = dbell2irq(rb);
     int pir = rb & DBELL_PIRTAG_MASK;
-    CPUPPCState *cenv;
+    CPUState *cs;
 
     if (irq < 0) {
         return;
     }
 
-    for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+        CPUPPCState *cenv = &cpu->env;
+
         if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
             cenv->pending_interrupts |= 1 << irq;
-            cpu_interrupt(CPU(ppc_env_get_cpu(cenv)), CPU_INTERRUPT_HARD);
+            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
         }
     }
 }
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 2bbc3b8..416c41e 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1574,7 +1574,7 @@ uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift)
 
     /* Find the largest hardware supported page size that's less than
      * or equal to the (logical) backing page size of guest RAM */
-    kvm_get_smmu_info(ppc_env_get_cpu(first_cpu), &info);
+    kvm_get_smmu_info(POWERPC_CPU(first_cpu), &info);
     rampagesize = getrampagesize();
     best_page_shift = 0;
 
diff --git a/translate-all.c b/translate-all.c
index 4177293..64cf855 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -681,7 +681,7 @@ static void page_flush_tb(void)
 /* XXX: tb_flush is currently not thread safe */
 void tb_flush(CPUArchState *env1)
 {
-    CPUArchState *env;
+    CPUState *cpu;
 
 #if defined(DEBUG_FLUSH)
     printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
@@ -696,7 +696,9 @@ void tb_flush(CPUArchState *env1)
     }
     tcg_ctx.tb_ctx.nb_tbs = 0;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         memset(env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *));
     }
 
@@ -821,7 +823,7 @@ static inline void tb_reset_jump(TranslationBlock *tb, int n)
 /* invalidate one TB */
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
 {
-    CPUArchState *env;
+    CPUState *cpu;
     PageDesc *p;
     unsigned int h, n1;
     tb_page_addr_t phys_pc;
@@ -848,7 +850,9 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
 
     /* 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) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         if (env->tb_jmp_cache[h] == tb) {
             env->tb_jmp_cache[h] = NULL;
         }
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 22/29] linux-user: Change thread_env to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (20 preceding siblings ...)
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 23/29] bsd-user: " Andreas Färber
                   ` (7 subsequent siblings)
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio, Andreas Färber

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 linux-user/elfload.c   | 16 +++++++++-------
 linux-user/linuxload.c |  3 ++-
 linux-user/main.c      | 10 +++++-----
 linux-user/qemu.h      |  2 +-
 linux-user/signal.c    | 12 +++++++-----
 linux-user/syscall.c   |  6 +++---
 6 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index d517450..7ce2eab 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -125,7 +125,7 @@ typedef abi_int         target_pid_t;
 static const char *get_elf_platform(void)
 {
     static char elf_platform[] = "i386";
-    int family = (thread_env->cpuid_version >> 8) & 0xff;
+    int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL);
     if (family > 6)
         family = 6;
     if (family >= 3)
@@ -137,7 +137,9 @@ static const char *get_elf_platform(void)
 
 static uint32_t get_elf_hwcap(void)
 {
-    return thread_env->features[FEAT_1_EDX];
+    X86CPU *cpu = X86_CPU(thread_cpu);
+
+    return cpu->env.features[FEAT_1_EDX];
 }
 
 #ifdef TARGET_X86_64
@@ -404,7 +406,7 @@ static int validate_guest_space(unsigned long guest_base,
 
 static uint32_t get_elf_hwcap(void)
 {
-    CPUARMState *e = thread_env;
+    ARMCPU *cpu = ARM_CPU(thread_cpu);
     uint32_t hwcaps = 0;
 
     hwcaps |= ARM_HWCAP_ARM_SWP;
@@ -415,7 +417,7 @@ static uint32_t get_elf_hwcap(void)
 
     /* probe for the extra features */
 #define GET_FEATURE(feat, hwcap) \
-    do {if (arm_feature(e, feat)) { hwcaps |= hwcap; } } while (0)
+    do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
     GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP);
     GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
     GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
@@ -619,13 +621,13 @@ enum {
 
 static uint32_t get_elf_hwcap(void)
 {
-    CPUPPCState *e = thread_env;
+    PowerPCCPU *cpu = POWERPC_CPU(thread_cpu);
     uint32_t features = 0;
 
     /* We don't have to be terribly complete here; the high points are
        Altivec/FP/SPE support.  Anything else is just a bonus.  */
 #define GET_FEATURE(flag, feature)                                      \
-    do {if (e->insns_flags & flag) features |= feature; } while(0)
+    do { if (cpu->env.insns_flags & flag) { features |= feature; } } while (0)
     GET_FEATURE(PPC_64B, QEMU_PPC_FEATURE_64);
     GET_FEATURE(PPC_FLOAT, QEMU_PPC_FEATURE_HAS_FPU);
     GET_FEATURE(PPC_ALTIVEC, QEMU_PPC_FEATURE_HAS_ALTIVEC);
@@ -2667,7 +2669,7 @@ static int fill_note_info(struct elf_note_info *info,
     /* read and fill status of all threads */
     cpu_list_lock();
     for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
-        if (cpu == ENV_GET_CPU(thread_env)) {
+        if (cpu == thread_cpu) {
             continue;
         }
         fill_thread_info(info, (CPUArchState *)cpu->env_ptr);
diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c
index 381ab89..5cd6d91 100644
--- a/linux-user/linuxload.c
+++ b/linux-user/linuxload.c
@@ -89,7 +89,8 @@ static int prepare_binprm(struct linux_binprm *bprm)
 abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
                               abi_ulong stringp, int push_ptr)
 {
-    TaskState *ts = (TaskState *)thread_env->opaque;
+    CPUArchState *env = thread_cpu->env_ptr;
+    TaskState *ts = (TaskState *)env->opaque;
     int n = sizeof(abi_ulong);
     abi_ulong envp;
     abi_ulong argv;
diff --git a/linux-user/main.c b/linux-user/main.c
index 3e60877..9fc64fe 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -120,7 +120,7 @@ void fork_end(int child)
     if (child) {
         /* Child processes created by fork() only have a single thread.
            Discard information about the parent threads.  */
-        first_cpu = ENV_GET_CPU(thread_env);
+        first_cpu = thread_cpu;
         first_cpu->next_cpu = NULL;
         pending_cpus = 0;
         pthread_mutex_init(&exclusive_lock, NULL);
@@ -128,7 +128,7 @@ void fork_end(int child)
         pthread_cond_init(&exclusive_cond, NULL);
         pthread_cond_init(&exclusive_resume, NULL);
         pthread_mutex_init(&tcg_ctx.tb_ctx.tb_lock, NULL);
-        gdbserver_fork(thread_env);
+        gdbserver_fork((CPUArchState *)thread_cpu->env_ptr);
     } else {
         pthread_mutex_unlock(&exclusive_lock);
         pthread_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
@@ -232,7 +232,7 @@ void fork_start(void)
 void fork_end(int child)
 {
     if (child) {
-        gdbserver_fork(thread_env);
+        gdbserver_fork((CPUArchState *)thread_cpu->env_ptr);
     }
 }
 
@@ -3150,7 +3150,7 @@ void cpu_loop(CPUS390XState *env)
 
 #endif /* TARGET_S390X */
 
-THREAD CPUArchState *thread_env;
+THREAD CPUState *thread_cpu;
 
 void task_settid(TaskState *ts)
 {
@@ -3640,7 +3640,7 @@ int main(int argc, char **argv, char **envp)
     cpu_reset(ENV_GET_CPU(env));
 #endif
 
-    thread_env = env;
+    thread_cpu = ENV_GET_CPU(env);
 
     if (getenv("QEMU_STRACE")) {
         do_strace = 1;
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index b10e957..d7f27ea 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -197,7 +197,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     abi_long arg5, abi_long arg6, abi_long arg7,
                     abi_long arg8);
 void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
-extern THREAD CPUArchState *thread_env;
+extern THREAD CPUState *thread_cpu;
 void cpu_loop(CPUArchState *env);
 char *target_strerror(int err);
 int get_osversion(void);
diff --git a/linux-user/signal.c b/linux-user/signal.c
index c4e20dc..42d8911 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -388,17 +388,18 @@ static inline void free_sigqueue(CPUArchState *env, struct sigqueue *q)
 /* abort execution with signal */
 static void QEMU_NORETURN force_sig(int target_sig)
 {
-    TaskState *ts = (TaskState *)thread_env->opaque;
+    CPUArchState *env = thread_cpu->env_ptr;
+    TaskState *ts = (TaskState *)env->opaque;
     int host_sig, core_dumped = 0;
     struct sigaction act;
     host_sig = target_to_host_signal(target_sig);
-    gdb_signalled(thread_env, target_sig);
+    gdb_signalled(env, target_sig);
 
     /* dump core if supported by target binary format */
     if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
         stop_all_tasks();
         core_dumped =
-            ((*ts->bprm->core_dump)(target_sig, thread_env) == 0);
+            ((*ts->bprm->core_dump)(target_sig, env) == 0);
     }
     if (core_dumped) {
         /* we already dumped the core of target process, we don't want
@@ -503,6 +504,7 @@ int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
 static void host_signal_handler(int host_signum, siginfo_t *info,
                                 void *puc)
 {
+    CPUArchState *env = thread_cpu->env_ptr;
     int sig;
     target_siginfo_t tinfo;
 
@@ -522,9 +524,9 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
     fprintf(stderr, "qemu: got signal %d\n", sig);
 #endif
     host_to_target_siginfo_noswap(&tinfo, info);
-    if (queue_signal(thread_env, sig, &tinfo) == 1) {
+    if (queue_signal(env, sig, &tinfo) == 1) {
         /* interrupt the virtual CPU as soon as possible */
-        cpu_exit(ENV_GET_CPU(thread_env));
+        cpu_exit(thread_cpu);
     }
 }
 
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 340666f..a3bafcc 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4171,8 +4171,8 @@ static void *clone_func(void *arg)
 
     env = info->env;
     cpu = ENV_GET_CPU(env);
-    thread_env = env;
-    ts = (TaskState *)thread_env->opaque;
+    thread_cpu = cpu;
+    ts = (TaskState *)env->opaque;
     info->tid = gettid();
     cpu->host_tid = info->tid;
     task_settid(ts);
@@ -5078,7 +5078,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
               sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
                         NULL, NULL, 0);
           }
-          thread_env = NULL;
+          thread_cpu = NULL;
           object_unref(OBJECT(ENV_GET_CPU(cpu_env)));
           g_free(ts);
           pthread_exit(NULL);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 23/29] bsd-user: Change thread_env to CPUState
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (21 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 22/29] linux-user: Change thread_env to CPUState Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 24/29] cpu: Drop qemu_for_each_cpu() Andreas Färber
                   ` (6 subsequent siblings)
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Andreas Färber

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 bsd-user/elfload.c | 6 ++++--
 bsd-user/main.c    | 6 +++---
 bsd-user/qemu.h    | 2 +-
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 5e20510..93fd9e4 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -98,7 +98,7 @@ enum {
 static const char *get_elf_platform(void)
 {
     static char elf_platform[] = "i386";
-    int family = (thread_env->cpuid_version >> 8) & 0xff;
+    int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL);
     if (family > 6)
         family = 6;
     if (family >= 3)
@@ -110,7 +110,9 @@ static const char *get_elf_platform(void)
 
 static uint32_t get_elf_hwcap(void)
 {
-    return thread_env->features[FEAT_1_EDX];
+    X86CPU *cpu = X86_CPU(thread_cpu);
+
+    return cpu->env.features[FEAT_1_EDX];
 }
 
 #ifdef TARGET_X86_64
diff --git a/bsd-user/main.c b/bsd-user/main.c
index b13803e..c2401cc 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -92,7 +92,7 @@ void fork_start(void)
 void fork_end(int child)
 {
     if (child) {
-        gdbserver_fork(thread_env);
+        gdbserver_fork((CPUArchState *)thread_cpu->env_ptr);
     }
 }
 
@@ -713,7 +713,7 @@ static void usage(void)
     exit(1);
 }
 
-THREAD CPUArchState *thread_env;
+THREAD CPUState *thread_cpu;
 
 /* Assumes contents are already zeroed.  */
 void init_task_state(TaskState *ts)
@@ -915,7 +915,7 @@ int main(int argc, char **argv)
 #if defined(TARGET_SPARC) || defined(TARGET_PPC)
     cpu_reset(ENV_GET_CPU(env));
 #endif
-    thread_env = env;
+    thread_cpu = ENV_GET_CPU(env);
 
     if (getenv("QEMU_STRACE")) {
         do_strace = 1;
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index a826086..325f564 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -139,7 +139,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
                             abi_long arg2, abi_long arg3, abi_long arg4,
                             abi_long arg5, abi_long arg6);
 void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
-extern THREAD CPUArchState *thread_env;
+extern THREAD CPUState *thread_cpu;
 void cpu_loop(CPUArchState *env);
 char *target_strerror(int err);
 int get_osversion(void);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 24/29] cpu: Drop qemu_for_each_cpu()
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (22 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 23/29] bsd-user: " Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-16 20:26   ` Michael S. Tsirkin
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 25/29] cpu: Move CPU_INTERRUPT_* to qom/cpu.h Andreas Färber
                   ` (5 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber, Michael S. Tsirkin

Revert commit d6b9e0d60cc511eca210834428bb74508cff3d33 (cpu: Add
qemu_for_each_cpu()) and its usage in favor of open-coding CPU loops,
now that they are based on CPUState.

Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c            | 11 ++++-------
 exec.c            | 11 -----------
 hw/acpi/piix4.c   | 20 +++++++++-----------
 include/qom/cpu.h |  9 ---------
 qom/cpu.c         | 30 +++++++++---------------------
 5 files changed, 22 insertions(+), 59 deletions(-)

diff --git a/cpus.c b/cpus.c
index ec38644..691c435 100644
--- a/cpus.c
+++ b/cpus.c
@@ -803,12 +803,6 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
 
 static void tcg_exec_all(void);
 
-static void tcg_signal_cpu_creation(CPUState *cpu, void *data)
-{
-    cpu->thread_id = qemu_get_thread_id();
-    cpu->created = true;
-}
-
 static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
     CPUState *cpu = arg;
@@ -817,7 +811,10 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
     qemu_thread_get_self(cpu->thread);
 
     qemu_mutex_lock(&qemu_global_mutex);
-    qemu_for_each_cpu(tcg_signal_cpu_creation, NULL);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        cpu->thread_id = qemu_get_thread_id();
+        cpu->created = true;
+    }
     qemu_cond_signal(&qemu_cpu_cond);
 
     /* wait for initial kick-off after machine start */
diff --git a/exec.c b/exec.c
index 191eb4e..5f3aba1 100644
--- a/exec.c
+++ b/exec.c
@@ -276,17 +276,6 @@ CPUState *qemu_get_cpu(int index)
     return cpu;
 }
 
-void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data)
-{
-    CPUState *cpu;
-
-    cpu = first_cpu;
-    while (cpu) {
-        func(cpu, data);
-        cpu = cpu->next_cpu;
-    }
-}
-
 void cpu_exec_init(CPUArchState *env)
 {
     CPUState *cpu = ENV_GET_CPU(env);
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 756df3b..3234452 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -654,22 +654,14 @@ static void piix4_cpu_added_req(Notifier *n, void *opaque)
     piix4_cpu_hotplug_req(s, CPU(opaque), PLUG);
 }
 
-static void piix4_init_cpu_status(CPUState *cpu, void *data)
-{
-    CPUStatus *g = (CPUStatus *)data;
-    CPUClass *k = CPU_GET_CLASS(cpu);
-    int64_t id = k->get_arch_id(cpu);
-
-    g_assert((id / 8) < PIIX4_PROC_LEN);
-    g->sts[id / 8] |= (1 << (id % 8));
-}
-
 static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
                                 PCIHotplugState state);
 
 static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
                                            PCIBus *bus, PIIX4PMState *s)
 {
+    CPUState *cpu;
+
     memory_region_init_io(&s->io_gpe, &piix4_gpe_ops, s, "apci-gpe0",
                           GPE_LEN);
     memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe);
@@ -680,7 +672,13 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
                                 &s->io_pci);
     pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev);
 
-    qemu_for_each_cpu(piix4_init_cpu_status, &s->gpe_cpu);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUClass *cc = CPU_GET_CLASS(cpu);
+        int64_t id = cc->get_arch_id(cpu);
+
+        g_assert((id / 8) < PIIX4_PROC_LEN);
+        s->gpe_cpu.sts[id / 8] |= (1 << (id % 8));
+    }
     memory_region_init_io(&s->io_cpu, &cpu_hotplug_ops, s, "apci-cpu-hotplug",
                           PIIX4_PROC_LEN);
     memory_region_add_subregion(parent, PIIX4_PROC_BASE, &s->io_cpu);
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 2a64af2..467896c 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -356,15 +356,6 @@ bool cpu_is_stopped(CPUState *cpu);
 void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data);
 
 /**
- * qemu_for_each_cpu:
- * @func: The function to be executed.
- * @data: Data to pass to the function.
- *
- * Executes @func for each CPU.
- */
-void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data);
-
-/**
  * qemu_get_cpu:
  * @index: The CPUState@cpu_index value of the CPU to obtain.
  *
diff --git a/qom/cpu.c b/qom/cpu.c
index ee8f632..94fa2b8 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -24,30 +24,18 @@
 #include "qemu/notify.h"
 #include "sysemu/sysemu.h"
 
-typedef struct CPUExistsArgs {
-    int64_t id;
-    bool found;
-} CPUExistsArgs;
-
-static void cpu_exist_cb(CPUState *cpu, void *data)
-{
-    CPUClass *klass = CPU_GET_CLASS(cpu);
-    CPUExistsArgs *arg = data;
-
-    if (klass->get_arch_id(cpu) == arg->id) {
-        arg->found = true;
-    }
-}
-
 bool cpu_exists(int64_t id)
 {
-    CPUExistsArgs data = {
-        .id = id,
-        .found = false,
-    };
+    CPUState *cpu;
+
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUClass *cc = CPU_GET_CLASS(cpu);
 
-    qemu_for_each_cpu(cpu_exist_cb, &data);
-    return data.found;
+        if (cc->get_arch_id(cpu) == id) {
+            return true;
+        }
+    }
+    return false;
 }
 
 bool cpu_paging_enabled(const CPUState *cpu)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 25/29] cpu: Move CPU_INTERRUPT_* to qom/cpu.h
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (23 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 24/29] cpu: Drop qemu_for_each_cpu() Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-17 20:59   ` Richard Henderson
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 26/29] intc/sh_intc: Build sh_intc only once Andreas Färber
                   ` (4 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Turn them into an enum. Un-poison them but make CPU_INTERRUPT_TGT_* only
available to CONFIG_SOFTMMU and CONFIG_USER_ONLY, i.e., not to devices.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 include/exec/cpu-all.h | 50 -------------------------------------------
 include/exec/poison.h  | 13 ------------
 include/qom/cpu.h      | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+), 63 deletions(-)

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 6499cd0..5d7d8a6 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -357,56 +357,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
 void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 
-/* Flags for use in ENV->INTERRUPT_PENDING.
-
-   The numbers assigned here are non-sequential in order to preserve
-   binary compatibility with the vmstate dump.  Bit 0 (0x0001) was
-   previously used for CPU_INTERRUPT_EXIT, and is cleared when loading
-   the vmstate dump.  */
-
-/* External hardware interrupt pending.  This is typically used for
-   interrupts from devices.  */
-#define CPU_INTERRUPT_HARD        0x0002
-
-/* Exit the current TB.  This is typically used when some system-level device
-   makes some change to the memory mapping.  E.g. the a20 line change.  */
-#define CPU_INTERRUPT_EXITTB      0x0004
-
-/* Halt the CPU.  */
-#define CPU_INTERRUPT_HALT        0x0020
-
-/* Debug event pending.  */
-#define CPU_INTERRUPT_DEBUG       0x0080
-
-/* Several target-specific external hardware interrupts.  Each target/cpu.h
-   should define proper names based on these defines.  */
-#define CPU_INTERRUPT_TGT_EXT_0   0x0008
-#define CPU_INTERRUPT_TGT_EXT_1   0x0010
-#define CPU_INTERRUPT_TGT_EXT_2   0x0040
-#define CPU_INTERRUPT_TGT_EXT_3   0x0200
-#define CPU_INTERRUPT_TGT_EXT_4   0x1000
-
-/* Several target-specific internal interrupts.  These differ from the
-   preceding target-specific interrupts in that they are intended to
-   originate from within the cpu itself, typically in response to some
-   instruction being executed.  These, therefore, are not masked while
-   single-stepping within the debugger.  */
-#define CPU_INTERRUPT_TGT_INT_0   0x0100
-#define CPU_INTERRUPT_TGT_INT_1   0x0400
-#define CPU_INTERRUPT_TGT_INT_2   0x0800
-#define CPU_INTERRUPT_TGT_INT_3   0x2000
-
-/* First unused bit: 0x4000.  */
-
-/* The set of all bits that should be masked when single-stepping.  */
-#define CPU_INTERRUPT_SSTEP_MASK \
-    (CPU_INTERRUPT_HARD          \
-     | CPU_INTERRUPT_TGT_EXT_0   \
-     | CPU_INTERRUPT_TGT_EXT_1   \
-     | CPU_INTERRUPT_TGT_EXT_2   \
-     | CPU_INTERRUPT_TGT_EXT_3   \
-     | CPU_INTERRUPT_TGT_EXT_4)
-
 /* Breakpoint/watchpoint flags */
 #define BP_MEM_READ           0x01
 #define BP_MEM_WRITE          0x02
diff --git a/include/exec/poison.h b/include/exec/poison.h
index 2341a75..00caabe 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -46,18 +46,5 @@
 #pragma GCC poison stl_phys
 #pragma GCC poison stq_phys
 
-#pragma GCC poison CPU_INTERRUPT_HARD
-#pragma GCC poison CPU_INTERRUPT_EXITTB
-#pragma GCC poison CPU_INTERRUPT_HALT
-#pragma GCC poison CPU_INTERRUPT_DEBUG
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_0
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_1
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_2
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_3
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_4
-#pragma GCC poison CPU_INTERRUPT_TGT_INT_0
-#pragma GCC poison CPU_INTERRUPT_TGT_INT_1
-#pragma GCC poison CPU_INTERRUPT_TGT_INT_2
-
 #endif
 #endif
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 467896c..ca917d8 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -375,6 +375,63 @@ CPUState *qemu_get_cpu(int index);
  */
 bool cpu_exists(int64_t id);
 
+/**
+ * CPUInterruptFlags:
+ * @CPU_INTERRUPT_HARD: External hardware interrupt pending.
+ * This is typically used for interrupts from devices.
+ * @CPU_INTERRUPT_EXITTB: Exit the current TB.
+ * This is typically used when some system-level device makes some change
+ * to the memory mapping.  E.g., the a20 line change.
+ * @CPU_INTERRUPT_HALT: Halt the CPU.
+ * @CPU_INTERRUPT_DEBUG: Debug event pending.
+ * @CPU_INTERRUPT_SSTEP_MASK: The set of all bits that should be masked
+ * when single-stepping.
+ *
+ * Flags for #CPUState.interrupt_pending.
+ *
+ * The numbers assigned here are non-sequential in order to preserve
+ * binary compatibility with the vmstate dump.  Bit 0 (0x0001) was
+ * previously used for CPU_INTERRUPT_EXIT, and is cleared when loading
+ * the vmstate dump.
+ */
+enum CPUInterruptFlags {
+    CPU_INTERRUPT_HARD      = 0x0002,
+    CPU_INTERRUPT_EXITTB    = 0x0004,
+    CPU_INTERRUPT_HALT      = 0x0020,
+    CPU_INTERRUPT_DEBUG     = 0x0080,
+
+#if defined(CONFIG_SOFTMMU) || defined(CONFIG_USER_ONLY)
+    /* Several target-specific external hardware interrupts.
+     * Each target/cpu.h should define proper names based on them.
+     */
+    CPU_INTERRUPT_TGT_EXT_0 = 0x0008,
+    CPU_INTERRUPT_TGT_EXT_1 = 0x0010,
+    CPU_INTERRUPT_TGT_EXT_2 = 0x0040,
+    CPU_INTERRUPT_TGT_EXT_3 = 0x0200,
+    CPU_INTERRUPT_TGT_EXT_4 = 0x1000,
+
+    /* Several target-specific internal interrupts.  These differ from the
+     * preceding target-specific interrupts in that they are intended to
+     * originate from within the cpu itself, typically in response to some
+     * instruction being executed.  These, therefore, are not masked while
+     * single-stepping within the debugger.
+     */
+    CPU_INTERRUPT_TGT_INT_0 = 0x0100,
+    CPU_INTERRUPT_TGT_INT_1 = 0x0400,
+    CPU_INTERRUPT_TGT_INT_2 = 0x0800,
+    CPU_INTERRUPT_TGT_INT_3 = 0x2000,
+
+    /* First unused bit: 0x4000. */
+
+    CPU_INTERRUPT_SSTEP_MASK = CPU_INTERRUPT_HARD |
+                               CPU_INTERRUPT_TGT_EXT_0 |
+                               CPU_INTERRUPT_TGT_EXT_1 |
+                               CPU_INTERRUPT_TGT_EXT_2 |
+                               CPU_INTERRUPT_TGT_EXT_3 |
+                               CPU_INTERRUPT_TGT_EXT_4,
+#endif
+};
+
 #ifndef CONFIG_USER_ONLY
 
 typedef void (*CPUInterruptHandler)(CPUState *, int);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 26/29] intc/sh_intc: Build sh_intc only once
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (24 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 25/29] cpu: Move CPU_INTERRUPT_* to qom/cpu.h Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-17 21:08   ` Richard Henderson
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 27/29] intc/arm_gic: Build arm_gic " Andreas Färber
                   ` (3 subsequent siblings)
  29 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Since converting first_cpu to CPUState and making CPU_INTERRUPT_HARD
available through qom/cpu.h, it no longer depends on CPUSH4State.

This allows sharing across sh4 and sh4eb.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/intc/Makefile.objs | 2 +-
 hw/intc/sh_intc.c     | 1 +
 include/hw/sh4/sh.h   | 2 ++
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 3e68d2e..9e92a0b 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -10,6 +10,7 @@ common-obj-$(CONFIG_REALVIEW) += realview_gic.o
 common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
 common-obj-$(CONFIG_IOAPIC) += ioapic_common.o
 common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o
+common-obj-$(CONFIG_SH4) += sh_intc.o
 
 obj-$(CONFIG_APIC) += apic.o apic_common.o
 obj-$(CONFIG_ARM_GIC) += arm_gic.o
@@ -20,4 +21,3 @@ obj-$(CONFIG_GRLIB) += grlib_irqmp.o
 obj-$(CONFIG_IOAPIC) += ioapic.o
 obj-$(CONFIG_OMAP) += omap_intc.o
 obj-$(CONFIG_OPENPIC) += openpic.o
-obj-$(CONFIG_SH4) += sh_intc.o
diff --git a/hw/intc/sh_intc.c b/hw/intc/sh_intc.c
index f1138e3..b8d9ff0 100644
--- a/hw/intc/sh_intc.c
+++ b/hw/intc/sh_intc.c
@@ -11,6 +11,7 @@
 #include "hw/sh4/sh_intc.h"
 #include "hw/hw.h"
 #include "hw/sh4/sh.h"
+#include "qom/cpu.h"
 
 //#define DEBUG_INTC
 //#define DEBUG_INTC_SOURCES
diff --git a/include/hw/sh4/sh.h b/include/hw/sh4/sh.h
index e61de9a..4ebafcc 100644
--- a/include/hw/sh4/sh.h
+++ b/include/hw/sh4/sh.h
@@ -11,7 +11,9 @@
 struct SH7750State;
 struct MemoryRegion;
 
+#ifdef CONFIG_SOFTMMU
 struct SH7750State *sh7750_init(SuperHCPU *cpu, struct MemoryRegion *sysmem);
+#endif
 
 typedef struct {
     /* The callback will be triggered if any of the designated lines change */
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 27/29] intc/arm_gic: Build arm_gic only once
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (25 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 26/29] intc/sh_intc: Build sh_intc only once Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 28/29] intc/openpic: Build openpic " Andreas Färber
                   ` (2 subsequent siblings)
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Since cpu_single_cpu is CPUState it no longer needs CPUArchState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/intc/Makefile.objs | 2 +-
 hw/intc/arm_gic.c     | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 9e92a0b..f75fb27 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -10,10 +10,10 @@ common-obj-$(CONFIG_REALVIEW) += realview_gic.o
 common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
 common-obj-$(CONFIG_IOAPIC) += ioapic_common.o
 common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o
+common-obj-$(CONFIG_ARM_GIC) += arm_gic.o
 common-obj-$(CONFIG_SH4) += sh_intc.o
 
 obj-$(CONFIG_APIC) += apic.o apic_common.o
-obj-$(CONFIG_ARM_GIC) += arm_gic.o
 obj-$(CONFIG_ARM_GIC_KVM) += arm_gic_kvm.o
 obj-$(CONFIG_STELLARIS) += armv7m_nvic.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_gic.o exynos4210_combiner.o
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 79fd4a9..4153ff4 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -20,6 +20,7 @@
 
 #include "hw/sysbus.h"
 #include "gic_internal.h"
+#include "qom/cpu.h"
 
 //#define DEBUG_GIC
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 28/29] intc/openpic: Build openpic only once
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (26 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 27/29] intc/arm_gic: Build arm_gic " Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 29/29] timer/arm_mptimer: Build arm_mptimer " Andreas Färber
  2013-06-26 14:20 ` [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel
  Cc: Scott Wood, open list:PowerPC, Andreas Färber, Alexander Graf

Since cpu_single_cpu is CPUState it no longer depends on CPUPPCState.

Move ppce500_set_mpic_proxy() to a new hw/ppc/ppc_e500.h because
hw/ppc/ppc.h is too heavily using CPUPPCState and PowerPCCPU.

Cc: Scott Wood <scottwood@freescale.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/intc/Makefile.objs     | 2 +-
 hw/intc/openpic.c         | 2 +-
 hw/ppc/ppc.c              | 1 +
 include/hw/ppc/ppc.h      | 2 --
 include/hw/ppc/ppc_e500.h | 6 ++++++
 5 files changed, 9 insertions(+), 4 deletions(-)
 create mode 100644 include/hw/ppc/ppc_e500.h

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index f75fb27..dd67132 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -12,6 +12,7 @@ common-obj-$(CONFIG_IOAPIC) += ioapic_common.o
 common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o
 common-obj-$(CONFIG_ARM_GIC) += arm_gic.o
 common-obj-$(CONFIG_SH4) += sh_intc.o
+common-obj-$(CONFIG_OPENPIC) += openpic.o
 
 obj-$(CONFIG_APIC) += apic.o apic_common.o
 obj-$(CONFIG_ARM_GIC_KVM) += arm_gic_kvm.o
@@ -20,4 +21,3 @@ obj-$(CONFIG_EXYNOS4) += exynos4210_gic.o exynos4210_combiner.o
 obj-$(CONFIG_GRLIB) += grlib_irqmp.o
 obj-$(CONFIG_IOAPIC) += ioapic.o
 obj-$(CONFIG_OMAP) += omap_intc.o
-obj-$(CONFIG_OPENPIC) += openpic.o
diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c
index 6f152e0..3788064 100644
--- a/hw/intc/openpic.c
+++ b/hw/intc/openpic.c
@@ -37,10 +37,10 @@
 #include "hw/ppc/mac.h"
 #include "hw/pci/pci.h"
 #include "hw/ppc/openpic.h"
+#include "hw/ppc/ppc_e500.h"
 #include "hw/sysbus.h"
 #include "hw/pci/msi.h"
 #include "qemu/bitops.h"
-#include "hw/ppc/ppc.h"
 
 //#define DEBUG_OPENPIC
 
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 554f244..e1c095c 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -23,6 +23,7 @@
  */
 #include "hw/hw.h"
 #include "hw/ppc/ppc.h"
+#include "hw/ppc/ppc_e500.h"
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
 #include "hw/timer/m48t59.h"
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index acaf0d6..cc2d78e 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -73,8 +73,6 @@ void ppc6xx_irq_init (CPUPPCState *env);
 void ppc970_irq_init (CPUPPCState *env);
 void ppcPOWER7_irq_init (CPUPPCState *env);
 
-void ppce500_set_mpic_proxy(bool enabled);
-
 /* PPC machines for OpenBIOS */
 enum {
     ARCH_PREP = 0,
diff --git a/include/hw/ppc/ppc_e500.h b/include/hw/ppc/ppc_e500.h
new file mode 100644
index 0000000..b66c0e3
--- /dev/null
+++ b/include/hw/ppc/ppc_e500.h
@@ -0,0 +1,6 @@
+#ifndef HW_PPC_E500_H
+#define HW_PPC_E500_H
+
+void ppce500_set_mpic_proxy(bool enabled);
+
+#endif
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* [Qemu-devel] [PATCH qom-cpu v2 29/29] timer/arm_mptimer: Build arm_mptimer only once
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (27 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 28/29] intc/openpic: Build openpic " Andreas Färber
@ 2013-06-16 15:57 ` Andreas Färber
  2013-06-26 14:20 ` [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 15:57 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Since cpu_single_cpu is CPUState it no longer depends on CPUArchState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/timer/Makefile.objs | 2 +-
 hw/timer/arm_mptimer.c | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 32b5c1a..eca5905 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -1,4 +1,5 @@
 common-obj-$(CONFIG_ARM_TIMER) += arm_timer.o
+common-obj-$(CONFIG_ARM_MPTIMER) += arm_mptimer.o
 common-obj-$(CONFIG_CADENCE) += cadence_ttc.o
 common-obj-$(CONFIG_DS1338) += ds1338.o
 common-obj-$(CONFIG_HPET) += hpet.o
@@ -25,5 +26,4 @@ obj-$(CONFIG_PXA2XX) += pxa2xx_timer.o
 obj-$(CONFIG_SH4) += sh_timer.o
 obj-$(CONFIG_TUSB6010) += tusb6010.o
 
-obj-$(CONFIG_ARM_MPTIMER) += arm_mptimer.o
 obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
index 1aa300b..1d93cc3 100644
--- a/hw/timer/arm_mptimer.c
+++ b/hw/timer/arm_mptimer.c
@@ -21,6 +21,7 @@
 
 #include "hw/sysbus.h"
 #include "qemu/timer.h"
+#include "qom/cpu.h"
 
 /* This device implements the per-cpu private timer and watchdog block
  * which is used in both the ARM11MPCore and Cortex-A9MP.
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 24/29] cpu: Drop qemu_for_each_cpu()
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 24/29] cpu: Drop qemu_for_each_cpu() Andreas Färber
@ 2013-06-16 20:26   ` Michael S. Tsirkin
  2013-06-16 20:30     ` Peter Maydell
  2013-06-16 20:41     ` Andreas Färber
  0 siblings, 2 replies; 98+ messages in thread
From: Michael S. Tsirkin @ 2013-06-16 20:26 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On Sun, Jun 16, 2013 at 05:57:44PM +0200, Andreas Färber wrote:
> Revert commit d6b9e0d60cc511eca210834428bb74508cff3d33 (cpu: Add
> qemu_for_each_cpu()) and its usage in favor of open-coding CPU loops,
> now that they are based on CPUState.
> 
> Suggested-by: Markus Armbruster <armbru@redhat.com>
> Signed-off-by: Andreas Färber <afaerber@suse.de>

Open-coding is kind of nasty though.

How about
#define qemu_for_each_cpu(cpu) \
    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu)

> ---
>  cpus.c            | 11 ++++-------
>  exec.c            | 11 -----------
>  hw/acpi/piix4.c   | 20 +++++++++-----------
>  include/qom/cpu.h |  9 ---------
>  qom/cpu.c         | 30 +++++++++---------------------
>  5 files changed, 22 insertions(+), 59 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index ec38644..691c435 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -803,12 +803,6 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
>  
>  static void tcg_exec_all(void);
>  
> -static void tcg_signal_cpu_creation(CPUState *cpu, void *data)
> -{
> -    cpu->thread_id = qemu_get_thread_id();
> -    cpu->created = true;
> -}
> -
>  static void *qemu_tcg_cpu_thread_fn(void *arg)
>  {
>      CPUState *cpu = arg;
> @@ -817,7 +811,10 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
>      qemu_thread_get_self(cpu->thread);
>  
>      qemu_mutex_lock(&qemu_global_mutex);
> -    qemu_for_each_cpu(tcg_signal_cpu_creation, NULL);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        cpu->thread_id = qemu_get_thread_id();
> +        cpu->created = true;
> +    }
>      qemu_cond_signal(&qemu_cpu_cond);
>  
>      /* wait for initial kick-off after machine start */
> diff --git a/exec.c b/exec.c
> index 191eb4e..5f3aba1 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -276,17 +276,6 @@ CPUState *qemu_get_cpu(int index)
>      return cpu;
>  }
>  
> -void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data)
> -{
> -    CPUState *cpu;
> -
> -    cpu = first_cpu;
> -    while (cpu) {
> -        func(cpu, data);
> -        cpu = cpu->next_cpu;
> -    }
> -}
> -
>  void cpu_exec_init(CPUArchState *env)
>  {
>      CPUState *cpu = ENV_GET_CPU(env);
> diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> index 756df3b..3234452 100644
> --- a/hw/acpi/piix4.c
> +++ b/hw/acpi/piix4.c
> @@ -654,22 +654,14 @@ static void piix4_cpu_added_req(Notifier *n, void *opaque)
>      piix4_cpu_hotplug_req(s, CPU(opaque), PLUG);
>  }
>  
> -static void piix4_init_cpu_status(CPUState *cpu, void *data)
> -{
> -    CPUStatus *g = (CPUStatus *)data;
> -    CPUClass *k = CPU_GET_CLASS(cpu);
> -    int64_t id = k->get_arch_id(cpu);
> -
> -    g_assert((id / 8) < PIIX4_PROC_LEN);
> -    g->sts[id / 8] |= (1 << (id % 8));
> -}
> -
>  static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
>                                  PCIHotplugState state);
>  
>  static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
>                                             PCIBus *bus, PIIX4PMState *s)
>  {
> +    CPUState *cpu;
> +
>      memory_region_init_io(&s->io_gpe, &piix4_gpe_ops, s, "apci-gpe0",
>                            GPE_LEN);
>      memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe);
> @@ -680,7 +672,13 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
>                                  &s->io_pci);
>      pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev);
>  
> -    qemu_for_each_cpu(piix4_init_cpu_status, &s->gpe_cpu);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUClass *cc = CPU_GET_CLASS(cpu);
> +        int64_t id = cc->get_arch_id(cpu);
> +
> +        g_assert((id / 8) < PIIX4_PROC_LEN);
> +        s->gpe_cpu.sts[id / 8] |= (1 << (id % 8));
> +    }
>      memory_region_init_io(&s->io_cpu, &cpu_hotplug_ops, s, "apci-cpu-hotplug",
>                            PIIX4_PROC_LEN);
>      memory_region_add_subregion(parent, PIIX4_PROC_BASE, &s->io_cpu);
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 2a64af2..467896c 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -356,15 +356,6 @@ bool cpu_is_stopped(CPUState *cpu);
>  void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data);
>  
>  /**
> - * qemu_for_each_cpu:
> - * @func: The function to be executed.
> - * @data: Data to pass to the function.
> - *
> - * Executes @func for each CPU.
> - */
> -void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data);
> -
> -/**
>   * qemu_get_cpu:
>   * @index: The CPUState@cpu_index value of the CPU to obtain.
>   *
> diff --git a/qom/cpu.c b/qom/cpu.c
> index ee8f632..94fa2b8 100644
> --- a/qom/cpu.c
> +++ b/qom/cpu.c
> @@ -24,30 +24,18 @@
>  #include "qemu/notify.h"
>  #include "sysemu/sysemu.h"
>  
> -typedef struct CPUExistsArgs {
> -    int64_t id;
> -    bool found;
> -} CPUExistsArgs;
> -
> -static void cpu_exist_cb(CPUState *cpu, void *data)
> -{
> -    CPUClass *klass = CPU_GET_CLASS(cpu);
> -    CPUExistsArgs *arg = data;
> -
> -    if (klass->get_arch_id(cpu) == arg->id) {
> -        arg->found = true;
> -    }
> -}
> -
>  bool cpu_exists(int64_t id)
>  {
> -    CPUExistsArgs data = {
> -        .id = id,
> -        .found = false,
> -    };
> +    CPUState *cpu;
> +
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUClass *cc = CPU_GET_CLASS(cpu);
>  
> -    qemu_for_each_cpu(cpu_exist_cb, &data);
> -    return data.found;
> +        if (cc->get_arch_id(cpu) == id) {
> +            return true;
> +        }
> +    }
> +    return false;
>  }
>  
>  bool cpu_paging_enabled(const CPUState *cpu)
> -- 
> 1.8.1.4

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 24/29] cpu: Drop qemu_for_each_cpu()
  2013-06-16 20:26   ` Michael S. Tsirkin
@ 2013-06-16 20:30     ` Peter Maydell
  2013-06-16 20:36       ` Michael S. Tsirkin
  2013-06-16 20:41     ` Andreas Färber
  1 sibling, 1 reply; 98+ messages in thread
From: Peter Maydell @ 2013-06-16 20:30 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: Andreas Färber, qemu-devel

On 16 June 2013 21:26, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Sun, Jun 16, 2013 at 05:57:44PM +0200, Andreas Färber wrote:
>> Revert commit d6b9e0d60cc511eca210834428bb74508cff3d33 (cpu: Add
>> qemu_for_each_cpu()) and its usage in favor of open-coding CPU loops,
>> now that they are based on CPUState.
>>
>> Suggested-by: Markus Armbruster <armbru@redhat.com>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>
> Open-coding is kind of nasty though.
>
> How about
> #define qemu_for_each_cpu(cpu) \
>     for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu)

Personally for an iteration that simple I would prefer
the opencoded version -- it's more immediately
obvious what it's doing and that it's not doing anything
weird.

Precedent isn't everything, but a quick grep for 'foreach'
and 'for_each' suggests that we generally use the callback-fn
style rather than iterator macros.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 24/29] cpu: Drop qemu_for_each_cpu()
  2013-06-16 20:30     ` Peter Maydell
@ 2013-06-16 20:36       ` Michael S. Tsirkin
  0 siblings, 0 replies; 98+ messages in thread
From: Michael S. Tsirkin @ 2013-06-16 20:36 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Andreas Färber, qemu-devel

On Sun, Jun 16, 2013 at 09:30:29PM +0100, Peter Maydell wrote:
> On 16 June 2013 21:26, Michael S. Tsirkin <mst@redhat.com> wrote:
> > On Sun, Jun 16, 2013 at 05:57:44PM +0200, Andreas Färber wrote:
> >> Revert commit d6b9e0d60cc511eca210834428bb74508cff3d33 (cpu: Add
> >> qemu_for_each_cpu()) and its usage in favor of open-coding CPU loops,
> >> now that they are based on CPUState.
> >>
> >> Suggested-by: Markus Armbruster <armbru@redhat.com>
> >> Signed-off-by: Andreas Färber <afaerber@suse.de>
> >
> > Open-coding is kind of nasty though.
> >
> > How about
> > #define qemu_for_each_cpu(cpu) \
> >     for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu)
> 
> Personally for an iteration that simple I would prefer
> the opencoded version -- it's more immediately
> obvious what it's doing and that it's not doing anything
> weird.

Only if you have memorized how is the list of CPUs put together.
You probably did, most other readers probably didn't,
and have to waste time looking it up.

> Precedent isn't everything, but a quick grep for 'foreach'
> and 'for_each' suggests that we generally use the callback-fn
> style rather than iterator macros.
> 
> thanks
> -- PMM

Callback is fine too.

-- 
MST

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 24/29] cpu: Drop qemu_for_each_cpu()
  2013-06-16 20:26   ` Michael S. Tsirkin
  2013-06-16 20:30     ` Peter Maydell
@ 2013-06-16 20:41     ` Andreas Färber
  1 sibling, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-16 20:41 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: Peter Maydell, qemu-devel, Markus Armbruster

Am 16.06.2013 22:26, schrieb Michael S. Tsirkin:
> On Sun, Jun 16, 2013 at 05:57:44PM +0200, Andreas Färber wrote:
>> Revert commit d6b9e0d60cc511eca210834428bb74508cff3d33 (cpu: Add
>> qemu_for_each_cpu()) and its usage in favor of open-coding CPU loops,
>> now that they are based on CPUState.
>>
>> Suggested-by: Markus Armbruster <armbru@redhat.com>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
> 
> Open-coding is kind of nasty though.
> 
> How about
> #define qemu_for_each_cpu(cpu) \
>     for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu)

I've been investigating QTAILQ_FOREACH(), but I'd rather do things in
two steps - CPUState type (21/29) in this series and then further macro
wizardry. I'd be fine to defer this patch and replace it with the final
helper of our choice.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu Andreas Färber
@ 2013-06-16 20:49   ` Blue Swirl
  2013-06-18 16:52     ` Andreas Färber
  2013-06-17 20:40   ` Richard Henderson
  2013-07-15 14:56   ` Paolo Bonzini
  2 siblings, 1 reply; 98+ messages in thread
From: Blue Swirl @ 2013-06-16 20:49 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Anthony Liguori, qemu-devel, Alexander Graf,
	Andreas Färber, Hervé Poussineau, Paul Brook,
	Scott Wood, open list:mpc8544ds, Aurelien Jarno,
	Richard Henderson

On Sun, Jun 16, 2013 at 3:57 PM, Andreas Färber <afaerber@suse.de> wrote:
> Move it to qom/cpu.h.

While renaming, perhaps a more descriptive name could be used instead
of 'cpu_single_cpu', something like cpu_loop_current_cpu?

>
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpu-exec.c              | 13 +++++++------
>  cpus.c                  | 29 ++++++++++++++---------------
>  exec.c                  | 12 +++++++-----
>  hw/alpha/typhoon.c      | 16 ++++------------
>  hw/arm/pxa2xx.c         |  3 +--
>  hw/i386/kvmvapic.c      |  6 ++++--
>  hw/i386/pc.c            | 11 ++++++-----
>  hw/intc/arm_gic.c       |  3 +--
>  hw/intc/armv7m_nvic.c   | 11 ++++++++---
>  hw/intc/openpic.c       |  5 +----
>  hw/mips/mips_fulong2e.c |  6 +++---
>  hw/mips/mips_jazz.c     |  6 +++---
>  hw/mips/mips_malta.c    |  6 +++---
>  hw/misc/vmport.c        | 26 ++++++++++++++++----------
>  hw/ppc/mpc8544_guts.c   |  3 ++-
>  hw/ppc/prep.c           |  6 +++---
>  hw/sparc/sun4m.c        |  5 ++---
>  hw/timer/arm_mptimer.c  |  2 --
>  include/exec/cpu-all.h  |  3 ---
>  include/qom/cpu.h       |  4 ++++
>  memory.c                | 10 ++++------
>  translate-all.c         | 20 ++++++++++++--------
>  user-exec.c             |  9 +++++----
>  23 files changed, 110 insertions(+), 105 deletions(-)
>
> diff --git a/cpu-exec.c b/cpu-exec.c
> index ec46380..1858c2e 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -213,12 +213,12 @@ int cpu_exec(CPUArchState *env)
>          cpu->halted = 0;
>      }
>
> -    cpu_single_env = env;
> +    cpu_single_cpu = cpu;
>
> -    /* As long as cpu_single_env is null, up to the assignment just above,
> +    /* As long as cpu_single_cpu is null, up to the assignment just above,
>       * requests by other threads to exit the execution loop are expected to
>       * be issued using the exit_request global. We must make sure that our
> -     * evaluation of the global value is performed past the cpu_single_env
> +     * evaluation of the global value is performed past the cpu_single_cpu
>       * value transition point, which requires a memory barrier as well as
>       * an instruction scheduling constraint on modern architectures.  */
>      smp_mb();
> @@ -673,7 +673,8 @@ int cpu_exec(CPUArchState *env)
>          } else {
>              /* Reload env after longjmp - the compiler may have smashed all
>               * local variables as longjmp is marked 'noreturn'. */
> -            env = cpu_single_env;
> +            cpu = cpu_single_cpu;
> +            env = cpu->env_ptr;
>          }
>      } /* for(;;) */
>
> @@ -707,7 +708,7 @@ int cpu_exec(CPUArchState *env)
>  #error unsupported target CPU
>  #endif
>
> -    /* fail safe : never use cpu_single_env outside cpu_exec() */
> -    cpu_single_env = NULL;
> +    /* fail safe : never use cpu_single_cpu outside cpu_exec() */
> +    cpu_single_cpu = NULL;
>      return ret;
>  }
> diff --git a/cpus.c b/cpus.c
> index 775d998..808503b 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -118,10 +118,11 @@ TimersState timers_state;
>  int64_t cpu_get_icount(void)
>  {
>      int64_t icount;
> -    CPUArchState *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>
>      icount = qemu_icount;
> -    if (env) {
> +    if (cpu) {
> +        CPUArchState *env = cpu->env_ptr;
>          if (!can_do_io(env)) {
>              fprintf(stderr, "Bad clock read\n");
>          }
> @@ -468,8 +469,8 @@ static void cpu_handle_guest_debug(CPUState *cpu)
>
>  static void cpu_signal(int sig)
>  {
> -    if (cpu_single_env) {
> -        cpu_exit(ENV_GET_CPU(cpu_single_env));
> +    if (cpu_single_cpu) {
> +        cpu_exit(cpu_single_cpu);
>      }
>      exit_request = 1;
>  }
> @@ -660,10 +661,10 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)
>
>      qemu_cpu_kick(cpu);
>      while (!wi.done) {
> -        CPUArchState *self_env = cpu_single_env;
> +        CPUState *self_cpu = cpu_single_cpu;
>
>          qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex);
> -        cpu_single_env = self_env;
> +        cpu_single_cpu = self_cpu;
>      }
>  }
>
> @@ -733,7 +734,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
>      qemu_mutex_lock(&qemu_global_mutex);
>      qemu_thread_get_self(cpu->thread);
>      cpu->thread_id = qemu_get_thread_id();
> -    cpu_single_env = cpu->env_ptr;
> +    cpu_single_cpu = cpu;
>
>      r = kvm_init_vcpu(cpu);
>      if (r < 0) {
> @@ -781,9 +782,9 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
>      cpu->created = true;
>      qemu_cond_signal(&qemu_cpu_cond);
>
> -    cpu_single_env = cpu->env_ptr;
> +    cpu_single_cpu = cpu;
>      while (1) {
> -        cpu_single_env = NULL;
> +        cpu_single_cpu = NULL;
>          qemu_mutex_unlock_iothread();
>          do {
>              int sig;
> @@ -794,7 +795,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
>              exit(1);
>          }
>          qemu_mutex_lock_iothread();
> -        cpu_single_env = cpu->env_ptr;
> +        cpu_single_cpu = cpu;
>          qemu_wait_io_event_common(cpu);
>      }
>
> @@ -894,8 +895,7 @@ void qemu_cpu_kick(CPUState *cpu)
>  void qemu_cpu_kick_self(void)
>  {
>  #ifndef _WIN32
> -    assert(cpu_single_env);
> -    CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
> +    assert(cpu_single_cpu);
>
>      if (!cpu_single_cpu->thread_kicked) {
>          qemu_cpu_kick_thread(cpu_single_cpu);
> @@ -913,7 +913,7 @@ bool qemu_cpu_is_self(CPUState *cpu)
>
>  static bool qemu_in_vcpu_thread(void)
>  {
> -    return cpu_single_env && qemu_cpu_is_self(ENV_GET_CPU(cpu_single_env));
> +    return cpu_single_cpu && qemu_cpu_is_self(cpu_single_cpu);
>  }
>
>  void qemu_mutex_lock_iothread(void)
> @@ -1069,8 +1069,7 @@ void qemu_init_vcpu(CPUState *cpu)
>
>  void cpu_stop_current(void)
>  {
> -    if (cpu_single_env) {
> -        CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
> +    if (cpu_single_cpu) {
>          cpu_single_cpu->stop = false;
>          cpu_single_cpu->stopped = true;
>          cpu_exit(cpu_single_cpu);
> diff --git a/exec.c b/exec.c
> index 2b99bb9..e14a815 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -73,7 +73,7 @@ static MemoryRegion io_mem_unassigned, io_mem_subpage_ram;
>  CPUArchState *first_cpu;
>  /* current CPU in the current thread. It is only valid inside
>     cpu_exec() */
> -DEFINE_TLS(CPUArchState *,cpu_single_env);
> +DEFINE_TLS(CPUState *,cpu_single_cpu);
>  /* 0 = Do not count executed instructions.
>     1 = Precise instruction counting.
>     2 = Adaptive rate instruction counting.  */
> @@ -1420,8 +1420,10 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
>      cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
>      /* we remove the notdirty callback only if the code has been
>         flushed */
> -    if (dirty_flags == 0xff)
> -        tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
> +    if (dirty_flags == 0xff) {
> +        CPUArchState *env = cpu_single_cpu->env_ptr;
> +        tlb_set_dirty(env, env->mem_io_vaddr);
> +    }
>  }
>
>  static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
> @@ -1439,7 +1441,7 @@ static const MemoryRegionOps notdirty_mem_ops = {
>  /* Generate a debug exception if a watchpoint has been hit.  */
>  static void check_watchpoint(int offset, int len_mask, int flags)
>  {
> -    CPUArchState *env = cpu_single_env;
> +    CPUArchState *env = cpu_single_cpu->env_ptr;
>      target_ulong pc, cs_base;
>      target_ulong vaddr;
>      CPUWatchpoint *wp;
> @@ -1912,7 +1914,7 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
>          if (is_write) {
>              if (!memory_access_is_direct(section->mr, is_write)) {
>                  l = memory_access_size(l, addr1);
> -                /* XXX: could force cpu_single_env to NULL to avoid
> +                /* XXX: could force cpu_single_cpu to NULL to avoid
>                     potential bugs */
>                  if (l == 4) {
>                      /* 32 bit write access */
> diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
> index 207dcad..f0b1f6f 100644
> --- a/hw/alpha/typhoon.c
> +++ b/hw/alpha/typhoon.c
> @@ -72,9 +72,8 @@ static void cpu_irq_change(AlphaCPU *cpu, uint64_t req)
>
>  static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
>  {
> -    CPUAlphaState *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>      TyphoonState *s = opaque;
> -    CPUState *cpu;
>      uint64_t ret = 0;
>
>      if (addr & 4) {
> @@ -95,7 +94,6 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
>
>      case 0x0080:
>          /* MISC: Miscellaneous Register.  */
> -        cpu = ENV_GET_CPU(env);
>          ret = s->cchip.misc | (cpu->cpu_index & 3);
>          break;
>
> @@ -197,8 +195,7 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
>          break;
>
>      default:
> -        cpu = CPU(alpha_env_get_cpu(cpu_single_env));
> -        cpu_unassigned_access(cpu, addr, false, false, 0, size);
> +        cpu_unassigned_access(cpu_single_cpu, addr, false, false, 0, size);
>          return -1;
>      }
>
> @@ -215,7 +212,6 @@ static uint64_t dchip_read(void *opaque, hwaddr addr, unsigned size)
>  static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
>  {
>      TyphoonState *s = opaque;
> -    CPUState *cs;
>      uint64_t ret = 0;
>
>      if (addr & 4) {
> @@ -302,8 +298,7 @@ static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
>          break;
>
>      default:
> -        cs = CPU(alpha_env_get_cpu(cpu_single_env));
> -        cpu_unassigned_access(cs, addr, false, false, 0, size);
> +        cpu_unassigned_access(cpu_single_cpu, addr, false, false, 0, size);
>          return -1;
>      }
>
> @@ -315,7 +310,6 @@ static void cchip_write(void *opaque, hwaddr addr,
>                          uint64_t v32, unsigned size)
>  {
>      TyphoonState *s = opaque;
> -    CPUState *cpu_single_cpu = CPU(alpha_env_get_cpu(cpu_single_env));
>      uint64_t val, oldval, newval;
>
>      if (addr & 4) {
> @@ -480,7 +474,6 @@ static void pchip_write(void *opaque, hwaddr addr,
>                          uint64_t v32, unsigned size)
>  {
>      TyphoonState *s = opaque;
> -    CPUState *cs;
>      uint64_t val, oldval;
>
>      if (addr & 4) {
> @@ -582,8 +575,7 @@ static void pchip_write(void *opaque, hwaddr addr,
>          break;
>
>      default:
> -        cs = CPU(alpha_env_get_cpu(cpu_single_env));
> -        cpu_unassigned_access(cs, addr, true, false, 0, size);
> +        cpu_unassigned_access(cpu_single_cpu, addr, true, false, 0, size);
>          return;
>      }
>  }
> diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
> index 24b03a0..d023167 100644
> --- a/hw/arm/pxa2xx.c
> +++ b/hw/arm/pxa2xx.c
> @@ -301,8 +301,7 @@ static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
>  #endif
>
>          /* Suspend */
> -        cpu_interrupt(CPU(arm_env_get_cpu(cpu_single_env)),
> -                      CPU_INTERRUPT_HALT);
> +        cpu_interrupt(cpu_single_cpu, CPU_INTERRUPT_HALT);
>
>          goto message;
>
> diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
> index f93629f..9aac9de 100644
> --- a/hw/i386/kvmvapic.c
> +++ b/hw/i386/kvmvapic.c
> @@ -623,11 +623,13 @@ static int vapic_prepare(VAPICROMState *s)
>  static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
>                          unsigned int size)
>  {
> -    CPUX86State *env = cpu_single_env;
> +    CPUState *cs = cpu_single_cpu;
> +    X86CPU *cpu = X86_CPU(cs);
> +    CPUX86State *env = &cpu->env;
>      hwaddr rom_paddr;
>      VAPICROMState *s = opaque;
>
> -    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
> +    cpu_synchronize_state(cs);
>
>      /*
>       * The VAPIC supports two PIO-based hypercalls, both via port 0x7E.
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index d7e8507..c43be54 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -887,8 +887,9 @@ void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd)
>
>  DeviceState *cpu_get_current_apic(void)
>  {
> -    if (cpu_single_env) {
> -        return cpu_single_env->apic_state;
> +    if (cpu_single_cpu) {
> +        X86CPU *cpu = X86_CPU(cpu_single_cpu);
> +        return cpu->env.apic_state;
>      } else {
>          return NULL;
>      }
> @@ -1107,10 +1108,10 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
>
>  static void cpu_request_exit(void *opaque, int irq, int level)
>  {
> -    CPUX86State *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>
> -    if (env && level) {
> -        cpu_exit(CPU(x86_env_get_cpu(env)));
> +    if (cpu && level) {
> +        cpu_exit(cpu);
>      }
>  }
>
> diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
> index bae6572..79fd4a9 100644
> --- a/hw/intc/arm_gic.c
> +++ b/hw/intc/arm_gic.c
> @@ -39,8 +39,7 @@ static const uint8_t gic_id[] = {
>  static inline int gic_get_current_cpu(GICState *s)
>  {
>      if (s->num_cpu > 1) {
> -        CPUState *cpu = ENV_GET_CPU(cpu_single_env);
> -        return cpu->cpu_index;
> +        return cpu_single_cpu->cpu_index;
>      }
>      return 0;
>  }
> diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
> index 25fa43c..53576c8 100644
> --- a/hw/intc/armv7m_nvic.c
> +++ b/hw/intc/armv7m_nvic.c
> @@ -140,6 +140,7 @@ void armv7m_nvic_complete_irq(void *opaque, int irq)
>
>  static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
>  {
> +    ARMCPU *cpu;
>      uint32_t val;
>      int irq;
>
> @@ -171,7 +172,8 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
>      case 0x1c: /* SysTick Calibration Value.  */
>          return 10000;
>      case 0xd00: /* CPUID Base.  */
> -        return cpu_single_env->cp15.c0_cpuid;
> +        cpu = ARM_CPU(cpu_single_cpu);
> +        return cpu->env.cp15.c0_cpuid;
>      case 0xd04: /* Interrupt Control State.  */
>          /* VECTACTIVE */
>          val = s->gic.running_irq[0];
> @@ -206,7 +208,8 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
>              val |= (1 << 31);
>          return val;
>      case 0xd08: /* Vector Table Offset.  */
> -        return cpu_single_env->v7m.vecbase;
> +        cpu = ARM_CPU(cpu_single_cpu);
> +        return cpu->env.v7m.vecbase;
>      case 0xd0c: /* Application Interrupt/Reset Control.  */
>          return 0xfa05000;
>      case 0xd10: /* System Control.  */
> @@ -279,6 +282,7 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
>
>  static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)
>  {
> +    ARMCPU *cpu;
>      uint32_t oldval;
>      switch (offset) {
>      case 0x10: /* SysTick Control and Status.  */
> @@ -331,7 +335,8 @@ static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)
>          }
>          break;
>      case 0xd08: /* Vector Table Offset.  */
> -        cpu_single_env->v7m.vecbase = value & 0xffffff80;
> +        cpu = ARM_CPU(cpu_single_cpu);
> +        cpu->env.v7m.vecbase = value & 0xffffff80;
>          break;
>      case 0xd0c: /* Application Interrupt/Reset Control.  */
>          if ((value >> 16) == 0x05fa) {
> diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c
> index c788714..6f152e0 100644
> --- a/hw/intc/openpic.c
> +++ b/hw/intc/openpic.c
> @@ -184,13 +184,10 @@ static int output_to_inttgt(int output)
>
>  static int get_current_cpu(void)
>  {
> -    CPUState *cpu_single_cpu;
> -
> -    if (!cpu_single_env) {
> +    if (!cpu_single_cpu) {
>          return -1;
>      }
>
> -    cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
>      return cpu_single_cpu->cpu_index;
>  }
>
> diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
> index 00c9071..59ee1b4 100644
> --- a/hw/mips/mips_fulong2e.c
> +++ b/hw/mips/mips_fulong2e.c
> @@ -250,10 +250,10 @@ static void network_init (void)
>
>  static void cpu_request_exit(void *opaque, int irq, int level)
>  {
> -    CPUMIPSState *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>
> -    if (env && level) {
> -        cpu_exit(CPU(mips_env_get_cpu(env)));
> +    if (cpu && level) {
> +        cpu_exit(cpu);
>      }
>  }
>
> diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
> index 2ad0c0b..2ffae59 100644
> --- a/hw/mips/mips_jazz.c
> +++ b/hw/mips/mips_jazz.c
> @@ -99,10 +99,10 @@ static const MemoryRegionOps dma_dummy_ops = {
>
>  static void cpu_request_exit(void *opaque, int irq, int level)
>  {
> -    CPUMIPSState *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>
> -    if (env && level) {
> -        cpu_exit(CPU(mips_env_get_cpu(env)));
> +    if (cpu && level) {
> +        cpu_exit(cpu);
>      }
>  }
>
> diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
> index 8a4459d..4fc611c 100644
> --- a/hw/mips/mips_malta.c
> +++ b/hw/mips/mips_malta.c
> @@ -770,10 +770,10 @@ static void main_cpu_reset(void *opaque)
>
>  static void cpu_request_exit(void *opaque, int irq, int level)
>  {
> -    CPUMIPSState *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>
> -    if (env && level) {
> -        cpu_exit(CPU(mips_env_get_cpu(env)));
> +    if (cpu && level) {
> +        cpu_exit(cpu);
>      }
>  }
>
> diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c
> index 8363dfd..deb2232 100644
> --- a/hw/misc/vmport.c
> +++ b/hw/misc/vmport.c
> @@ -62,11 +62,13 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
>                                     unsigned size)
>  {
>      VMPortState *s = opaque;
> -    CPUX86State *env = cpu_single_env;
> +    CPUState *cs = cpu_single_cpu;
> +    X86CPU *cpu = X86_CPU(cs);
> +    CPUX86State *env = &cpu->env;
>      unsigned char command;
>      uint32_t eax;
>
> -    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
> +    cpu_synchronize_state(cs);
>
>      eax = env->regs[R_EAX];
>      if (eax != VMPORT_MAGIC)
> @@ -89,29 +91,32 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
>  static void vmport_ioport_write(void *opaque, hwaddr addr,
>                                  uint64_t val, unsigned size)
>  {
> -    CPUX86State *env = cpu_single_env;
> +    X86CPU *cpu = X86_CPU(cpu_single_cpu);
>
> -    env->regs[R_EAX] = vmport_ioport_read(opaque, addr, 4);
> +    cpu->env.regs[R_EAX] = vmport_ioport_read(opaque, addr, 4);
>  }
>
>  static uint32_t vmport_cmd_get_version(void *opaque, uint32_t addr)
>  {
> -    CPUX86State *env = cpu_single_env;
> -    env->regs[R_EBX] = VMPORT_MAGIC;
> +    X86CPU *cpu = X86_CPU(cpu_single_cpu);
> +
> +    cpu->env.regs[R_EBX] = VMPORT_MAGIC;
>      return 6;
>  }
>
>  static uint32_t vmport_cmd_ram_size(void *opaque, uint32_t addr)
>  {
> -    CPUX86State *env = cpu_single_env;
> -    env->regs[R_EBX] = 0x1177;
> +    X86CPU *cpu = X86_CPU(cpu_single_cpu);
> +
> +    cpu->env.regs[R_EBX] = 0x1177;
>      return ram_size;
>  }
>
>  /* vmmouse helpers */
>  void vmmouse_get_data(uint32_t *data)
>  {
> -    CPUX86State *env = cpu_single_env;
> +    X86CPU *cpu = X86_CPU(cpu_single_cpu);
> +    CPUX86State *env = &cpu->env;
>
>      data[0] = env->regs[R_EAX]; data[1] = env->regs[R_EBX];
>      data[2] = env->regs[R_ECX]; data[3] = env->regs[R_EDX];
> @@ -120,7 +125,8 @@ void vmmouse_get_data(uint32_t *data)
>
>  void vmmouse_set_data(const uint32_t *data)
>  {
> -    CPUX86State *env = cpu_single_env;
> +    X86CPU *cpu = X86_CPU(cpu_single_cpu);
> +    CPUX86State *env = &cpu->env;
>
>      env->regs[R_EAX] = data[0]; env->regs[R_EBX] = data[1];
>      env->regs[R_ECX] = data[2]; env->regs[R_EDX] = data[3];
> diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c
> index 193beab..89f950f 100644
> --- a/hw/ppc/mpc8544_guts.c
> +++ b/hw/ppc/mpc8544_guts.c
> @@ -62,7 +62,8 @@ static uint64_t mpc8544_guts_read(void *opaque, hwaddr addr,
>                                    unsigned size)
>  {
>      uint32_t value = 0;
> -    CPUPPCState *env = cpu_single_env;
> +    PowerPCCPU *cpu = POWERPC_CPU(cpu_single_cpu);
> +    CPUPPCState *env = &cpu->env;
>
>      addr &= MPC8544_GUTS_MMIO_SIZE - 1;
>      switch (addr) {
> diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
> index 90828f2..16e3132 100644
> --- a/hw/ppc/prep.c
> +++ b/hw/ppc/prep.c
> @@ -417,10 +417,10 @@ static const MemoryRegionOps PPC_prep_io_ops = {
>
>  static void cpu_request_exit(void *opaque, int irq, int level)
>  {
> -    CPUPPCState *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>
> -    if (env && level) {
> -        cpu_exit(CPU(ppc_env_get_cpu(env)));
> +    if (cpu && level) {
> +        cpu_exit(cpu);
>      }
>  }
>
> diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
> index 0e86ca7..1273533 100644
> --- a/hw/sparc/sun4m.c
> +++ b/hw/sparc/sun4m.c
> @@ -264,9 +264,8 @@ static void secondary_cpu_reset(void *opaque)
>
>  static void cpu_halt_signal(void *opaque, int irq, int level)
>  {
> -    if (level && cpu_single_env) {
> -        cpu_interrupt(CPU(sparc_env_get_cpu(cpu_single_env)),
> -                      CPU_INTERRUPT_HALT);
> +    if (level && cpu_single_cpu) {
> +        cpu_interrupt(cpu_single_cpu, CPU_INTERRUPT_HALT);
>      }
>  }
>
> diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
> index 317f5e4..1aa300b 100644
> --- a/hw/timer/arm_mptimer.c
> +++ b/hw/timer/arm_mptimer.c
> @@ -49,8 +49,6 @@ typedef struct {
>
>  static inline int get_current_cpu(ARMMPTimerState *s)
>  {
> -    CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
> -
>      if (cpu_single_cpu->cpu_index >= s->num_cpu) {
>          hw_error("arm_mptimer: num-cpu %d but this cpu is %d!\n",
>                   s->num_cpu, cpu_single_cpu->cpu_index);
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index 35bdf85..6760851 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -20,7 +20,6 @@
>  #define CPU_ALL_H
>
>  #include "qemu-common.h"
> -#include "qemu/tls.h"
>  #include "exec/cpu-common.h"
>  #include "qemu/thread.h"
>
> @@ -358,8 +357,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
>  void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
>      GCC_FMT_ATTR(2, 3);
>  extern CPUArchState *first_cpu;
> -DECLARE_TLS(CPUArchState *,cpu_single_env);
> -#define cpu_single_env tls_var(cpu_single_env)
>
>  /* Flags for use in ENV->INTERRUPT_PENDING.
>
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 7afc442..0e2e76c 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -24,6 +24,7 @@
>  #include "hw/qdev-core.h"
>  #include "exec/hwaddr.h"
>  #include "qemu/thread.h"
> +#include "qemu/tls.h"
>  #include "qemu/typedefs.h"
>
>  typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque);
> @@ -156,6 +157,9 @@ struct CPUState {
>      uint32_t halted; /* used by alpha, cris, ppc TCG */
>  };
>
> +DECLARE_TLS(CPUState *, cpu_single_cpu);
> +#define cpu_single_cpu tls_var(cpu_single_cpu)
> +
>  /**
>   * cpu_paging_enabled:
>   * @cpu: The CPU whose state is to be inspected.
> diff --git a/memory.c b/memory.c
> index 3bc98ad..f960bd0 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -857,9 +857,8 @@ static uint64_t unassigned_mem_read(void *opaque, hwaddr addr,
>  #ifdef DEBUG_UNASSIGNED
>      printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
>  #endif
> -    if (cpu_single_env != NULL) {
> -        cpu_unassigned_access(ENV_GET_CPU(cpu_single_env),
> -                              addr, false, false, 0, size);
> +    if (cpu_single_cpu != NULL) {
> +        cpu_unassigned_access(cpu_single_cpu, addr, false, false, 0, size);
>      }
>      return 0;
>  }
> @@ -870,9 +869,8 @@ static void unassigned_mem_write(void *opaque, hwaddr addr,
>  #ifdef DEBUG_UNASSIGNED
>      printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val);
>  #endif
> -    if (cpu_single_env != NULL) {
> -        cpu_unassigned_access(ENV_GET_CPU(cpu_single_env),
> -                              addr, true, false, 0, size);
> +    if (cpu_single_cpu != NULL) {
> +        cpu_unassigned_access(cpu_single_cpu, addr, true, false, 0, size);
>      }
>  }
>
> diff --git a/translate-all.c b/translate-all.c
> index df7c697..4177293 100644
> --- a/translate-all.c
> +++ b/translate-all.c
> @@ -999,8 +999,10 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
>                                     int is_cpu_write_access)
>  {
>      TranslationBlock *tb, *tb_next, *saved_tb;
> -    CPUArchState *env = cpu_single_env;
> -    CPUState *cpu = NULL;
> +    CPUState *cpu = cpu_single_cpu;
> +#if defined(TARGET_HAS_PRECISE_SMC) || !defined(CONFIG_USER_ONLY)
> +    CPUArchState *env = NULL;
> +#endif
>      tb_page_addr_t tb_start, tb_end;
>      PageDesc *p;
>      int n;
> @@ -1023,9 +1025,11 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
>          /* build code bitmap */
>          build_page_bitmap(p);
>      }
> -    if (env != NULL) {
> -        cpu = ENV_GET_CPU(env);
> +#if defined(TARGET_HAS_PRECISE_SMC) || !defined(CONFIG_USER_ONLY)
> +    if (cpu != NULL) {
> +        env = cpu->env_ptr;
>      }
> +#endif
>
>      /* we remove all the TBs in the range [start, end[ */
>      /* XXX: see if in some cases it could be faster to invalidate all
> @@ -1147,8 +1151,8 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr,
>      int n;
>  #ifdef TARGET_HAS_PRECISE_SMC
>      TranslationBlock *current_tb = NULL;
> -    CPUArchState *env = cpu_single_env;
> -    CPUState *cpu = NULL;
> +    CPUState *cpu = cpu_single_cpu;
> +    CPUArchState *env = NULL;
>      int current_tb_modified = 0;
>      target_ulong current_pc = 0;
>      target_ulong current_cs_base = 0;
> @@ -1165,8 +1169,8 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr,
>      if (tb && pc != 0) {
>          current_tb = tb_find_pc(pc);
>      }
> -    if (env != NULL) {
> -        cpu = ENV_GET_CPU(env);
> +    if (cpu != NULL) {
> +        env = cpu->env_ptr;
>      }
>  #endif
>      while (tb != NULL) {
> diff --git a/user-exec.c b/user-exec.c
> index fa7f1f1..aebdf1e 100644
> --- a/user-exec.c
> +++ b/user-exec.c
> @@ -81,6 +81,7 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
>                                      int is_write, sigset_t *old_set,
>                                      void *puc)
>  {
> +    CPUArchState *env;
>      int ret;
>
>  #if defined(DEBUG_SIGNAL)
> @@ -93,9 +94,9 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
>          return 1;
>      }
>
> +    env = cpu_single_cpu->env_ptr;
>      /* see if it is an MMU fault */
> -    ret = cpu_handle_mmu_fault(cpu_single_env, address, is_write,
> -                               MMU_USER_IDX);
> +    ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX);
>      if (ret < 0) {
>          return 0; /* not an MMU fault */
>      }
> @@ -103,12 +104,12 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
>          return 1; /* the MMU fault was handled without causing real CPU fault */
>      }
>      /* now we have a real cpu fault */
> -    cpu_restore_state(cpu_single_env, pc);
> +    cpu_restore_state(env, pc);
>
>      /* we restore the process signal mask as the sigreturn should
>         do it (XXX: use sigsetjmp) */
>      sigprocmask(SIG_SETMASK, old_set, NULL);
> -    exception_action(cpu_single_env);
> +    exception_action(env);
>
>      /* never comes here */
>      return 1;
> --
> 1.8.1.4
>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH qom-cpu v2 07/29] kvm: Change kvm_set_signal_mask() argument to CPUState
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
@ 2013-06-17 16:15     ` Paolo Bonzini
  -1 siblings, 0 replies; 98+ messages in thread
From: Paolo Bonzini @ 2013-06-17 16:15 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Marcelo Tosatti, qemu-devel, Gleb Natapov, Overall

Il 16/06/2013 17:57, Andreas Färber ha scritto:
> CPUArchState is no longer needed.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c               | 3 ++-
>  include/sysemu/kvm.h | 2 +-
>  kvm-all.c            | 3 +--
>  kvm-stub.c           | 2 +-
>  4 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index fe19962..fca5e1f 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -570,6 +570,7 @@ static void dummy_signal(int sig)
>  
>  static void qemu_kvm_init_cpu_signals(CPUArchState *env)
>  {
> +    CPUState *cpu = ENV_GET_CPU(env);
>      int r;
>      sigset_t set;
>      struct sigaction sigact;
> @@ -581,7 +582,7 @@ static void qemu_kvm_init_cpu_signals(CPUArchState *env)
>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>      sigdelset(&set, SIG_IPI);
>      sigdelset(&set, SIGBUS);
> -    r = kvm_set_signal_mask(env, &set);
> +    r = kvm_set_signal_mask(cpu, &set);
>      if (r) {
>          fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
>          exit(1);
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index 06da2b3..5adb044 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -166,7 +166,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>  void kvm_remove_all_breakpoints(CPUArchState *current_env);
>  int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
>  #ifndef _WIN32
> -int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset);
> +int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset);
>  #endif
>  
>  int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
> diff --git a/kvm-all.c b/kvm-all.c
> index e7202ff..88297b1 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -2034,9 +2034,8 @@ void kvm_remove_all_breakpoints(CPUArchState *current_env)
>  }
>  #endif /* !KVM_CAP_SET_GUEST_DEBUG */
>  
> -int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
> +int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)
>  {
> -    CPUState *cpu = ENV_GET_CPU(env);
>      struct kvm_signal_mask *sigmask;
>      int r;
>  
> diff --git a/kvm-stub.c b/kvm-stub.c
> index 128faf7..50af700 100644
> --- a/kvm-stub.c
> +++ b/kvm-stub.c
> @@ -100,7 +100,7 @@ void kvm_remove_all_breakpoints(CPUArchState *current_env)
>  }
>  
>  #ifndef _WIN32
> -int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
> +int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)
>  {
>      abort();
>  }
> 

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 07/29] kvm: Change kvm_set_signal_mask() argument to CPUState
@ 2013-06-17 16:15     ` Paolo Bonzini
  0 siblings, 0 replies; 98+ messages in thread
From: Paolo Bonzini @ 2013-06-17 16:15 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Marcelo Tosatti, qemu-devel, Gleb Natapov, Overall

Il 16/06/2013 17:57, Andreas Färber ha scritto:
> CPUArchState is no longer needed.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c               | 3 ++-
>  include/sysemu/kvm.h | 2 +-
>  kvm-all.c            | 3 +--
>  kvm-stub.c           | 2 +-
>  4 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index fe19962..fca5e1f 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -570,6 +570,7 @@ static void dummy_signal(int sig)
>  
>  static void qemu_kvm_init_cpu_signals(CPUArchState *env)
>  {
> +    CPUState *cpu = ENV_GET_CPU(env);
>      int r;
>      sigset_t set;
>      struct sigaction sigact;
> @@ -581,7 +582,7 @@ static void qemu_kvm_init_cpu_signals(CPUArchState *env)
>      pthread_sigmask(SIG_BLOCK, NULL, &set);
>      sigdelset(&set, SIG_IPI);
>      sigdelset(&set, SIGBUS);
> -    r = kvm_set_signal_mask(env, &set);
> +    r = kvm_set_signal_mask(cpu, &set);
>      if (r) {
>          fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
>          exit(1);
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index 06da2b3..5adb044 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -166,7 +166,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>  void kvm_remove_all_breakpoints(CPUArchState *current_env);
>  int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
>  #ifndef _WIN32
> -int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset);
> +int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset);
>  #endif
>  
>  int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
> diff --git a/kvm-all.c b/kvm-all.c
> index e7202ff..88297b1 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -2034,9 +2034,8 @@ void kvm_remove_all_breakpoints(CPUArchState *current_env)
>  }
>  #endif /* !KVM_CAP_SET_GUEST_DEBUG */
>  
> -int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
> +int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)
>  {
> -    CPUState *cpu = ENV_GET_CPU(env);
>      struct kvm_signal_mask *sigmask;
>      int r;
>  
> diff --git a/kvm-stub.c b/kvm-stub.c
> index 128faf7..50af700 100644
> --- a/kvm-stub.c
> +++ b/kvm-stub.c
> @@ -100,7 +100,7 @@ void kvm_remove_all_breakpoints(CPUArchState *current_env)
>  }
>  
>  #ifndef _WIN32
> -int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
> +int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)
>  {
>      abort();
>  }
> 

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH qom-cpu v2 10/29] kvm: Change kvm_handle_internal_error() argument to CPUState
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
@ 2013-06-17 16:16     ` Paolo Bonzini
  -1 siblings, 0 replies; 98+ messages in thread
From: Paolo Bonzini @ 2013-06-17 16:16 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Marcelo Tosatti, qemu-devel, Gleb Natapov, Overall

Il 16/06/2013 17:57, Andreas Färber ha scritto:
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  kvm-all.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/kvm-all.c b/kvm-all.c
> index 1cd4573..1675311 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1520,10 +1520,8 @@ static void kvm_handle_io(uint16_t port, void *data, int direction, int size,
>      }
>  }
>  
> -static int kvm_handle_internal_error(CPUArchState *env, struct kvm_run *run)
> +static int kvm_handle_internal_error(CPUState *cpu, struct kvm_run *run)
>  {
> -    CPUState *cpu = ENV_GET_CPU(env);
> -
>      fprintf(stderr, "KVM internal error.");
>      if (kvm_check_extension(kvm_state, KVM_CAP_INTERNAL_ERROR_DATA)) {
>          int i;
> @@ -1685,7 +1683,7 @@ int kvm_cpu_exec(CPUArchState *env)
>              ret = -1;
>              break;
>          case KVM_EXIT_INTERNAL_ERROR:
> -            ret = kvm_handle_internal_error(env, run);
> +            ret = kvm_handle_internal_error(cpu, run);
>              break;
>          default:
>              DPRINTF("kvm_arch_handle_exit\n");
> 

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 10/29] kvm: Change kvm_handle_internal_error() argument to CPUState
@ 2013-06-17 16:16     ` Paolo Bonzini
  0 siblings, 0 replies; 98+ messages in thread
From: Paolo Bonzini @ 2013-06-17 16:16 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Marcelo Tosatti, qemu-devel, Gleb Natapov, Overall

Il 16/06/2013 17:57, Andreas Färber ha scritto:
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  kvm-all.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/kvm-all.c b/kvm-all.c
> index 1cd4573..1675311 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1520,10 +1520,8 @@ static void kvm_handle_io(uint16_t port, void *data, int direction, int size,
>      }
>  }
>  
> -static int kvm_handle_internal_error(CPUArchState *env, struct kvm_run *run)
> +static int kvm_handle_internal_error(CPUState *cpu, struct kvm_run *run)
>  {
> -    CPUState *cpu = ENV_GET_CPU(env);
> -
>      fprintf(stderr, "KVM internal error.");
>      if (kvm_check_extension(kvm_state, KVM_CAP_INTERNAL_ERROR_DATA)) {
>          int i;
> @@ -1685,7 +1683,7 @@ int kvm_cpu_exec(CPUArchState *env)
>              ret = -1;
>              break;
>          case KVM_EXIT_INTERNAL_ERROR:
> -            ret = kvm_handle_internal_error(env, run);
> +            ret = kvm_handle_internal_error(cpu, run);
>              break;
>          default:
>              DPRINTF("kvm_arch_handle_exit\n");
> 

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH qom-cpu v2 11/29] kvm: Change kvm_cpu_exec() argument to CPUState
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
@ 2013-06-17 16:17     ` Paolo Bonzini
  -1 siblings, 0 replies; 98+ messages in thread
From: Paolo Bonzini @ 2013-06-17 16:17 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Marcelo Tosatti, qemu-devel, Gleb Natapov, Overall

Il 16/06/2013 17:57, Andreas Färber ha scritto:
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c               | 2 +-
>  include/sysemu/kvm.h | 2 +-
>  kvm-all.c            | 3 +--
>  kvm-stub.c           | 4 ++--
>  4 files changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index bbaf13c..47ab818 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -752,7 +752,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
>  
>      while (1) {
>          if (cpu_can_run(cpu)) {
> -            r = kvm_cpu_exec(env);
> +            r = kvm_cpu_exec(cpu);
>              if (r == EXCP_DEBUG) {
>                  cpu_handle_guest_debug(env);
>              }
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index 5adb044..fe8bc40 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -147,9 +147,9 @@ int kvm_has_gsi_routing(void);
>  int kvm_has_intx_set_mask(void);
>  
>  int kvm_init_vcpu(CPUState *cpu);
> +int kvm_cpu_exec(CPUState *cpu);
>  
>  #ifdef NEED_CPU_H
> -int kvm_cpu_exec(CPUArchState *env);
>  
>  #if !defined(CONFIG_USER_ONLY)
>  void *kvm_ram_alloc(ram_addr_t size);
> diff --git a/kvm-all.c b/kvm-all.c
> index 1675311..90b89cd 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1602,9 +1602,8 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
>      cpu->kvm_vcpu_dirty = false;
>  }
>  
> -int kvm_cpu_exec(CPUArchState *env)
> +int kvm_cpu_exec(CPUState *cpu)
>  {
> -    CPUState *cpu = ENV_GET_CPU(env);

Always good to see some of these go.

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

>      struct kvm_run *run = cpu->kvm_run;
>      int ret, run_ret;
>  
> diff --git a/kvm-stub.c b/kvm-stub.c
> index 50af700..5457fe8 100644
> --- a/kvm-stub.c
> +++ b/kvm-stub.c
> @@ -54,9 +54,9 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
>  {
>  }
>  
> -int kvm_cpu_exec(CPUArchState *env)
> +int kvm_cpu_exec(CPUState *cpu)
>  {
> -    abort ();
> +    abort();
>  }
>  
>  int kvm_has_sync_mmu(void)
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 11/29] kvm: Change kvm_cpu_exec() argument to CPUState
@ 2013-06-17 16:17     ` Paolo Bonzini
  0 siblings, 0 replies; 98+ messages in thread
From: Paolo Bonzini @ 2013-06-17 16:17 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Marcelo Tosatti, qemu-devel, Gleb Natapov, Overall

Il 16/06/2013 17:57, Andreas Färber ha scritto:
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c               | 2 +-
>  include/sysemu/kvm.h | 2 +-
>  kvm-all.c            | 3 +--
>  kvm-stub.c           | 4 ++--
>  4 files changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index bbaf13c..47ab818 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -752,7 +752,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
>  
>      while (1) {
>          if (cpu_can_run(cpu)) {
> -            r = kvm_cpu_exec(env);
> +            r = kvm_cpu_exec(cpu);
>              if (r == EXCP_DEBUG) {
>                  cpu_handle_guest_debug(env);
>              }
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index 5adb044..fe8bc40 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -147,9 +147,9 @@ int kvm_has_gsi_routing(void);
>  int kvm_has_intx_set_mask(void);
>  
>  int kvm_init_vcpu(CPUState *cpu);
> +int kvm_cpu_exec(CPUState *cpu);
>  
>  #ifdef NEED_CPU_H
> -int kvm_cpu_exec(CPUArchState *env);
>  
>  #if !defined(CONFIG_USER_ONLY)
>  void *kvm_ram_alloc(ram_addr_t size);
> diff --git a/kvm-all.c b/kvm-all.c
> index 1675311..90b89cd 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1602,9 +1602,8 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
>      cpu->kvm_vcpu_dirty = false;
>  }
>  
> -int kvm_cpu_exec(CPUArchState *env)
> +int kvm_cpu_exec(CPUState *cpu)
>  {
> -    CPUState *cpu = ENV_GET_CPU(env);

Always good to see some of these go.

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

>      struct kvm_run *run = cpu->kvm_run;
>      int ret, run_ret;
>  
> diff --git a/kvm-stub.c b/kvm-stub.c
> index 50af700..5457fe8 100644
> --- a/kvm-stub.c
> +++ b/kvm-stub.c
> @@ -54,9 +54,9 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
>  {
>  }
>  
> -int kvm_cpu_exec(CPUArchState *env)
> +int kvm_cpu_exec(CPUState *cpu)
>  {
> -    abort ();
> +    abort();
>  }
>  
>  int kvm_has_sync_mmu(void)
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH qom-cpu v2 20/29] kvm: Change kvm_remove_all_breakpoints() argument to CPUState
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
@ 2013-06-17 16:17     ` Paolo Bonzini
  -1 siblings, 0 replies; 98+ messages in thread
From: Paolo Bonzini @ 2013-06-17 16:17 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Marcelo Tosatti, qemu-devel, Gleb Natapov, Overall

Il 16/06/2013 17:57, Andreas Färber ha scritto:
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  gdbstub.c            | 2 +-
>  include/sysemu/kvm.h | 2 +-
>  kvm-all.c            | 5 ++---
>  kvm-stub.c           | 2 +-
>  4 files changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/gdbstub.c b/gdbstub.c
> index 3101a43..9e7f7a1 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -2019,7 +2019,7 @@ static void gdb_breakpoint_remove_all(void)
>      CPUArchState *env;
>  
>      if (kvm_enabled()) {
> -        kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
> +        kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu));

Planning to make gdbserver_state take a CPUState, too?

Anyway, KVM changes are trivial:

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

>          return;
>      }
>  
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index fe8bc40..c767488 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -163,7 +163,7 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
>                            target_ulong len, int type);
>  int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>                            target_ulong len, int type);
> -void kvm_remove_all_breakpoints(CPUArchState *current_env);
> +void kvm_remove_all_breakpoints(CPUState *current_cpu);
>  int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
>  #ifndef _WIN32
>  int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset);
> diff --git a/kvm-all.c b/kvm-all.c
> index 90b89cd..b3ba6aa 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1979,9 +1979,8 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>      return 0;
>  }
>  
> -void kvm_remove_all_breakpoints(CPUArchState *current_env)
> +void kvm_remove_all_breakpoints(CPUState *current_cpu)
>  {
> -    CPUState *current_cpu = ENV_GET_CPU(current_env);
>      struct kvm_sw_breakpoint *bp, *next;
>      KVMState *s = current_cpu->kvm_state;
>      CPUArchState *env;
> @@ -2026,7 +2025,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>      return -EINVAL;
>  }
>  
> -void kvm_remove_all_breakpoints(CPUArchState *current_env)
> +void kvm_remove_all_breakpoints(CPUState *current_cpu)
>  {
>  }
>  #endif /* !KVM_CAP_SET_GUEST_DEBUG */
> diff --git a/kvm-stub.c b/kvm-stub.c
> index 5457fe8..f614f92 100644
> --- a/kvm-stub.c
> +++ b/kvm-stub.c
> @@ -95,7 +95,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>      return -EINVAL;
>  }
>  
> -void kvm_remove_all_breakpoints(CPUArchState *current_env)
> +void kvm_remove_all_breakpoints(CPUState *current_cpu)
>  {
>  }
>  
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 20/29] kvm: Change kvm_remove_all_breakpoints() argument to CPUState
@ 2013-06-17 16:17     ` Paolo Bonzini
  0 siblings, 0 replies; 98+ messages in thread
From: Paolo Bonzini @ 2013-06-17 16:17 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Marcelo Tosatti, qemu-devel, Gleb Natapov, Overall

Il 16/06/2013 17:57, Andreas Färber ha scritto:
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  gdbstub.c            | 2 +-
>  include/sysemu/kvm.h | 2 +-
>  kvm-all.c            | 5 ++---
>  kvm-stub.c           | 2 +-
>  4 files changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/gdbstub.c b/gdbstub.c
> index 3101a43..9e7f7a1 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -2019,7 +2019,7 @@ static void gdb_breakpoint_remove_all(void)
>      CPUArchState *env;
>  
>      if (kvm_enabled()) {
> -        kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
> +        kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu));

Planning to make gdbserver_state take a CPUState, too?

Anyway, KVM changes are trivial:

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

>          return;
>      }
>  
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index fe8bc40..c767488 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -163,7 +163,7 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
>                            target_ulong len, int type);
>  int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>                            target_ulong len, int type);
> -void kvm_remove_all_breakpoints(CPUArchState *current_env);
> +void kvm_remove_all_breakpoints(CPUState *current_cpu);
>  int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
>  #ifndef _WIN32
>  int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset);
> diff --git a/kvm-all.c b/kvm-all.c
> index 90b89cd..b3ba6aa 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1979,9 +1979,8 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>      return 0;
>  }
>  
> -void kvm_remove_all_breakpoints(CPUArchState *current_env)
> +void kvm_remove_all_breakpoints(CPUState *current_cpu)
>  {
> -    CPUState *current_cpu = ENV_GET_CPU(current_env);
>      struct kvm_sw_breakpoint *bp, *next;
>      KVMState *s = current_cpu->kvm_state;
>      CPUArchState *env;
> @@ -2026,7 +2025,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>      return -EINVAL;
>  }
>  
> -void kvm_remove_all_breakpoints(CPUArchState *current_env)
> +void kvm_remove_all_breakpoints(CPUState *current_cpu)
>  {
>  }
>  #endif /* !KVM_CAP_SET_GUEST_DEBUG */
> diff --git a/kvm-stub.c b/kvm-stub.c
> index 5457fe8..f614f92 100644
> --- a/kvm-stub.c
> +++ b/kvm-stub.c
> @@ -95,7 +95,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>      return -EINVAL;
>  }
>  
> -void kvm_remove_all_breakpoints(CPUArchState *current_env)
> +void kvm_remove_all_breakpoints(CPUState *current_cpu)
>  {
>  }
>  
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH qom-cpu v2 21/29] cpu: Make first_cpu and next_cpu CPUState
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
@ 2013-06-17 16:20     ` Paolo Bonzini
  -1 siblings, 0 replies; 98+ messages in thread
From: Paolo Bonzini @ 2013-06-17 16:20 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Anthony Liguori, Riku Voipio, Igor Mitsyanko,
	Mark Langsdorf, Evgeny Voevodin, Marcelo Tosatti, qemu-devel,
	Gleb Natapov, Alexander Graf, Peter Crosthwaite,
	Andreas Färber, PowerPC, Paul Brook, David Gibson, kvm,
	Luiz Capitulino, Edgar E. Iglesias, Maksim Kozlov,
	Aurelien Jarno, Dmitry Solodkiy

Il 16/06/2013 17:57, Andreas Färber ha scritto:
> Move first_cpu to qom/cpu.h.
> 
> gdbstub needs to use CPUState::env_ptr for now.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c                    | 126 ++++++++++++++++++++++++----------------------
>  cputlb.c                  |   4 +-
>  dump.c                    |  16 +++---
>  exec.c                    |  43 ++++++++--------
>  gdbstub.c                 |  33 +++++++-----
>  hw/arm/boot.c             |  10 ++--
>  hw/arm/exynos4_boards.c   |   4 +-
>  hw/arm/highbank.c         |   2 +-
>  hw/arm/realview.c         |   2 +-
>  hw/arm/vexpress.c         |   2 +-
>  hw/arm/xilinx_zynq.c      |   2 +-
>  hw/i386/kvm/clock.c       |  12 +++--
>  hw/i386/kvmvapic.c        |  13 +++--
>  hw/i386/pc.c              |  17 ++++---
>  hw/i386/pc_piix.c         |   3 +-
>  hw/intc/sh_intc.c         |   5 +-
>  hw/isa/lpc_ich9.c         |   2 +-
>  hw/mips/mips_malta.c      |   3 +-
>  hw/ppc/ppc.c              |  11 ++--
>  hw/ppc/prep.c             |   6 ++-
>  hw/ppc/spapr.c            |  27 +++++-----
>  include/exec/cpu-all.h    |   1 -
>  include/exec/cpu-defs.h   |   1 -
>  include/qom/cpu.h         |   4 ++
>  kvm-all.c                 |  20 +++++---
>  linux-user/elfload.c      |   7 +--
>  linux-user/main.c         |   8 ++-
>  linux-user/syscall.c      |   9 ++--
>  memory_mapping.c          |  16 +++---
>  monitor.c                 |   4 +-
>  target-i386/arch_dump.c   |   7 ++-
>  target-i386/helper.c      |  15 +++---
>  target-i386/kvm.c         |   8 +--
>  target-i386/misc_helper.c |   2 +-
>  target-mips/op_helper.c   |  25 +++++----
>  target-ppc/excp_helper.c  |   9 ++--
>  target-ppc/kvm.c          |   2 +-
>  translate-all.c           |  12 +++--
>  38 files changed, 267 insertions(+), 226 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index 808503b..ec38644 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -60,7 +60,7 @@
>  
>  #endif /* CONFIG_LINUX */
>  
> -static CPUArchState *next_cpu;
> +static CPUState *next_cpu;
>  
>  static bool cpu_thread_is_idle(CPUState *cpu)
>  {
> @@ -79,10 +79,10 @@ static bool cpu_thread_is_idle(CPUState *cpu)
>  
>  static bool all_cpu_threads_idle(void)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        if (!cpu_thread_is_idle(ENV_GET_CPU(env))) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        if (!cpu_thread_is_idle(cpu)) {
>              return false;
>          }
>      }
> @@ -388,15 +388,13 @@ void configure_icount(const char *option)
>  void hw_error(const char *fmt, ...)
>  {
>      va_list ap;
> -    CPUArchState *env;
>      CPUState *cpu;
>  
>      va_start(ap, fmt);
>      fprintf(stderr, "qemu: hardware error: ");
>      vfprintf(stderr, fmt, ap);
>      fprintf(stderr, "\n");
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cpu = ENV_GET_CPU(env);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
>          cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU);
>      }
> @@ -406,28 +404,28 @@ void hw_error(const char *fmt, ...)
>  
>  void cpu_synchronize_all_states(void)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
> -    for (env = first_cpu; env; env = env->next_cpu) {
> -        cpu_synchronize_state(ENV_GET_CPU(env));
> +    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
> +        cpu_synchronize_state(cpu);
>      }
>  }
>  
>  void cpu_synchronize_all_post_reset(void)
>  {
> -    CPUArchState *cpu;
> +    CPUState *cpu;
>  
>      for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
> -        cpu_synchronize_post_reset(ENV_GET_CPU(cpu));
> +        cpu_synchronize_post_reset(cpu);
>      }
>  }
>  
>  void cpu_synchronize_all_post_init(void)
>  {
> -    CPUArchState *cpu;
> +    CPUState *cpu;
>  
>      for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
> -        cpu_synchronize_post_init(ENV_GET_CPU(cpu));
> +        cpu_synchronize_post_init(cpu);
>      }
>  }
>  
> @@ -698,7 +696,7 @@ static void qemu_wait_io_event_common(CPUState *cpu)
>  
>  static void qemu_tcg_wait_io_event(void)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
>      while (all_cpu_threads_idle()) {
>         /* Start accounting real time to the virtual clock if the CPUs
> @@ -711,8 +709,8 @@ static void qemu_tcg_wait_io_event(void)
>          qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex);
>      }
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        qemu_wait_io_event_common(ENV_GET_CPU(env));
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        qemu_wait_io_event_common(cpu);
>      }
>  }
>  
> @@ -814,7 +812,6 @@ static void tcg_signal_cpu_creation(CPUState *cpu, void *data)
>  static void *qemu_tcg_cpu_thread_fn(void *arg)
>  {
>      CPUState *cpu = arg;
> -    CPUArchState *env;
>  
>      qemu_tcg_init_cpu_signals();
>      qemu_thread_get_self(cpu->thread);
> @@ -824,12 +821,12 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
>      qemu_cond_signal(&qemu_cpu_cond);
>  
>      /* wait for initial kick-off after machine start */
> -    while (ENV_GET_CPU(first_cpu)->stopped) {
> +    while (first_cpu->stopped) {
>          qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
>  
>          /* process any pending work */
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -            qemu_wait_io_event_common(ENV_GET_CPU(env));
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +            qemu_wait_io_event_common(cpu);
>          }
>      }
>  
> @@ -923,7 +920,7 @@ void qemu_mutex_lock_iothread(void)
>      } else {
>          iothread_requesting_mutex = true;
>          if (qemu_mutex_trylock(&qemu_global_mutex)) {
> -            qemu_cpu_kick_thread(ENV_GET_CPU(first_cpu));
> +            qemu_cpu_kick_thread(first_cpu);
>              qemu_mutex_lock(&qemu_global_mutex);
>          }
>          iothread_requesting_mutex = false;
> @@ -938,14 +935,13 @@ void qemu_mutex_unlock_iothread(void)
>  
>  static int all_vcpus_paused(void)
>  {
> -    CPUArchState *penv = first_cpu;
> +    CPUState *cpu = first_cpu;
>  
> -    while (penv) {
> -        CPUState *pcpu = ENV_GET_CPU(penv);
> -        if (!pcpu->stopped) {
> +    while (cpu) {
> +        if (!cpu->stopped) {
>              return 0;
>          }
> -        penv = penv->next_cpu;
> +        cpu = cpu->next_cpu;
>      }
>  
>      return 1;
> @@ -953,25 +949,23 @@ static int all_vcpus_paused(void)
>  
>  void pause_all_vcpus(void)
>  {
> -    CPUArchState *penv = first_cpu;
> +    CPUState *cpu = first_cpu;
>  
>      qemu_clock_enable(vm_clock, false);
> -    while (penv) {
> -        CPUState *pcpu = ENV_GET_CPU(penv);
> -        pcpu->stop = true;
> -        qemu_cpu_kick(pcpu);
> -        penv = penv->next_cpu;
> +    while (cpu) {
> +        cpu->stop = true;
> +        qemu_cpu_kick(cpu);
> +        cpu = cpu->next_cpu;
>      }
>  
>      if (qemu_in_vcpu_thread()) {
>          cpu_stop_current();
>          if (!kvm_enabled()) {
> -            penv = first_cpu;
> -            while (penv) {
> -                CPUState *pcpu = ENV_GET_CPU(penv);
> -                pcpu->stop = false;
> -                pcpu->stopped = true;
> -                penv = penv->next_cpu;
> +            cpu = first_cpu;
> +            while (cpu) {
> +                cpu->stop = false;
> +                cpu->stopped = true;
> +                cpu = cpu->next_cpu;
>              }
>              return;
>          }
> @@ -979,10 +973,10 @@ void pause_all_vcpus(void)
>  
>      while (!all_vcpus_paused()) {
>          qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
> -        penv = first_cpu;
> -        while (penv) {
> -            qemu_cpu_kick(ENV_GET_CPU(penv));
> -            penv = penv->next_cpu;
> +        cpu = first_cpu;
> +        while (cpu) {
> +            qemu_cpu_kick(cpu);
> +            cpu = cpu->next_cpu;
>          }
>      }
>  }
> @@ -996,13 +990,12 @@ void cpu_resume(CPUState *cpu)
>  
>  void resume_all_vcpus(void)
>  {
> -    CPUArchState *penv = first_cpu;
> +    CPUState *cpu = first_cpu;
>  
>      qemu_clock_enable(vm_clock, true);
> -    while (penv) {
> -        CPUState *pcpu = ENV_GET_CPU(penv);
> -        cpu_resume(pcpu);
> -        penv = penv->next_cpu;
> +    while (cpu) {
> +        cpu_resume(cpu);
> +        cpu = cpu->next_cpu;
>      }
>  }
>  
> @@ -1151,8 +1144,8 @@ static void tcg_exec_all(void)
>          next_cpu = first_cpu;
>      }
>      for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
> -        CPUArchState *env = next_cpu;
> -        CPUState *cpu = ENV_GET_CPU(env);
> +        CPUState *cpu = next_cpu;
> +        CPUArchState *env = cpu->env_ptr;
>  
>          qemu_clock_enable(vm_clock,
>                            (env->singlestep_enabled & SSTEP_NOTIMER) == 0);
> @@ -1172,12 +1165,10 @@ static void tcg_exec_all(void)
>  
>  void set_numa_modes(void)
>  {
> -    CPUArchState *env;
>      CPUState *cpu;
>      int i;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cpu = ENV_GET_CPU(env);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          for (i = 0; i < nb_numa_nodes; i++) {
>              if (test_bit(cpu->cpu_index, node_cpumask[i])) {
>                  cpu->numa_node = i;
> @@ -1197,18 +1188,30 @@ void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
>  CpuInfoList *qmp_query_cpus(Error **errp)
>  {
>      CpuInfoList *head = NULL, *cur_item = NULL;
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        CPUState *cpu = ENV_GET_CPU(env);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          CpuInfoList *info;
> +#if defined(TARGET_I386)
> +        X86CPU *x86_cpu = X86_CPU(cpu);
> +        CPUX86State *env = &x86_cpu->env;
> +#elif defined(TARGET_PPC)
> +        PowerPCCPU *ppc_cpu = POWERPC_CPU(cpu);
> +        CPUPPCState *env = &ppc_cpu->env;
> +#elif defined(TARGET_SPARC)
> +        SPARCCPU *sparc_cpu = SPARC_CPU(cpu);
> +        CPUSPARCState *env = &sparc_cpu->env;
> +#elif defined(TARGET_MIPS)
> +        MIPSCPU *mips_cpu = MIPS_CPU(cpu);
> +        CPUMIPSState *env = &mips_cpu->env;
> +#endif
>  
>          cpu_synchronize_state(cpu);
>  
>          info = g_malloc0(sizeof(*info));
>          info->value = g_malloc0(sizeof(*info->value));
>          info->value->CPU = cpu->cpu_index;
> -        info->value->current = (env == first_cpu);
> +        info->value->current = (cpu == first_cpu);
>          info->value->halted = cpu->halted;
>          info->value->thread_id = cpu->thread_id;
>  #if defined(TARGET_I386)
> @@ -1316,11 +1319,14 @@ exit:
>  void qmp_inject_nmi(Error **errp)
>  {
>  #if defined(TARGET_I386)
> -    CPUArchState *env;
> +    CPUState *cs;
> +
> +    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
> +        X86CPU *cpu = X86_CPU(cs);
> +        CPUX86State *env = &cpu->env;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
>          if (!env->apic_state) {
> -            cpu_interrupt(CPU(x86_env_get_cpu(env)), CPU_INTERRUPT_NMI);
> +            cpu_interrupt(cs, CPU_INTERRUPT_NMI);
>          } else {
>              apic_deliver_nmi(env->apic_state);
>          }
> diff --git a/cputlb.c b/cputlb.c
> index 232c488..74b98ec 100644
> --- a/cputlb.c
> +++ b/cputlb.c
> @@ -175,11 +175,13 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
>  
>  void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length)
>  {
> +    CPUState *cpu;
>      CPUArchState *env;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          int mmu_idx;
>  
> +        env = cpu->env_ptr;
>          for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
>              unsigned int i;
>  
> diff --git a/dump.c b/dump.c
> index 44a1339..e414515 100644
> --- a/dump.c
> +++ b/dump.c
> @@ -275,13 +275,11 @@ static inline int cpu_index(CPUState *cpu)
>  
>  static int write_elf64_notes(DumpState *s)
>  {
> -    CPUArchState *env;
>      CPUState *cpu;
>      int ret;
>      int id;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cpu = ENV_GET_CPU(env);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          id = cpu_index(cpu);
>          ret = cpu_write_elf64_note(fd_write_vmcore, cpu, id, s);
>          if (ret < 0) {
> @@ -290,7 +288,7 @@ static int write_elf64_notes(DumpState *s)
>          }
>      }
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          ret = cpu_write_elf64_qemunote(fd_write_vmcore, cpu, s);
>          if (ret < 0) {
>              dump_error(s, "dump: failed to write CPU status.\n");
> @@ -327,13 +325,11 @@ static int write_elf32_note(DumpState *s)
>  
>  static int write_elf32_notes(DumpState *s)
>  {
> -    CPUArchState *env;
>      CPUState *cpu;
>      int ret;
>      int id;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cpu = ENV_GET_CPU(env);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          id = cpu_index(cpu);
>          ret = cpu_write_elf32_note(fd_write_vmcore, cpu, id, s);
>          if (ret < 0) {
> @@ -342,7 +338,7 @@ static int write_elf32_notes(DumpState *s)
>          }
>      }
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          ret = cpu_write_elf32_qemunote(fd_write_vmcore, cpu, s);
>          if (ret < 0) {
>              dump_error(s, "dump: failed to write CPU status.\n");
> @@ -705,7 +701,7 @@ static ram_addr_t get_start_block(DumpState *s)
>  static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
>                       int64_t begin, int64_t length, Error **errp)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>      int nr_cpus;
>      Error *err = NULL;
>      int ret;
> @@ -738,7 +734,7 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
>       */
>      cpu_synchronize_all_states();
>      nr_cpus = 0;
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          nr_cpus++;
>      }
>  
> diff --git a/exec.c b/exec.c
> index e14a815..191eb4e 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -70,7 +70,7 @@ static MemoryRegion io_mem_unassigned, io_mem_subpage_ram;
>  
>  #endif
>  
> -CPUArchState *first_cpu;
> +CPUState *first_cpu;
>  /* current CPU in the current thread. It is only valid inside
>     cpu_exec() */
>  DEFINE_TLS(CPUState *,cpu_single_cpu);
> @@ -264,27 +264,26 @@ static const VMStateDescription vmstate_cpu_common = {
>  
>  CPUState *qemu_get_cpu(int index)
>  {
> -    CPUArchState *env = first_cpu;
> -    CPUState *cpu = NULL;
> +    CPUState *cpu = first_cpu;
>  
> -    while (env) {
> -        cpu = ENV_GET_CPU(env);
> +    while (cpu) {
>          if (cpu->cpu_index == index) {
>              break;
>          }
> -        env = env->next_cpu;
> +        cpu = cpu->next_cpu;
>      }
>  
> -    return env ? cpu : NULL;
> +    return cpu;
>  }
>  
>  void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data)
>  {
> -    CPUArchState *env = first_cpu;
> +    CPUState *cpu;
>  
> -    while (env) {
> -        func(ENV_GET_CPU(env), data);
> -        env = env->next_cpu;
> +    cpu = first_cpu;
> +    while (cpu) {
> +        func(cpu, data);
> +        cpu = cpu->next_cpu;
>      }
>  }
>  
> @@ -292,17 +291,17 @@ void cpu_exec_init(CPUArchState *env)
>  {
>      CPUState *cpu = ENV_GET_CPU(env);
>      CPUClass *cc = CPU_GET_CLASS(cpu);
> -    CPUArchState **penv;
> +    CPUState **pcpu;
>      int cpu_index;
>  
>  #if defined(CONFIG_USER_ONLY)
>      cpu_list_lock();
>  #endif
> -    env->next_cpu = NULL;
> -    penv = &first_cpu;
> +    cpu->next_cpu = NULL;
> +    pcpu = &first_cpu;
>      cpu_index = 0;
> -    while (*penv != NULL) {
> -        penv = &(*penv)->next_cpu;
> +    while (*pcpu != NULL) {
> +        pcpu = &(*pcpu)->next_cpu;
>          cpu_index++;
>      }
>      cpu->cpu_index = cpu_index;
> @@ -312,7 +311,7 @@ void cpu_exec_init(CPUArchState *env)
>  #ifndef CONFIG_USER_ONLY
>      cpu->thread_id = qemu_get_thread_id();
>  #endif
> -    *penv = env;
> +    *pcpu = cpu;
>  #if defined(CONFIG_USER_ONLY)
>      cpu_list_unlock();
>  #endif
> @@ -551,7 +550,7 @@ void cpu_abort(CPUArchState *env, const char *fmt, ...)
>  CPUArchState *cpu_copy(CPUArchState *env)
>  {
>      CPUArchState *new_env = cpu_init(env->cpu_model_str);
> -    CPUArchState *next_cpu = new_env->next_cpu;
> +    CPUState *next_cpu = ENV_GET_CPU(new_env)->next_cpu;
>  #if defined(TARGET_HAS_ICE)
>      CPUBreakpoint *bp;
>      CPUWatchpoint *wp;
> @@ -560,7 +559,7 @@ CPUArchState *cpu_copy(CPUArchState *env)
>      memcpy(new_env, env, sizeof(CPUArchState));
>  
>      /* Preserve chaining. */
> -    new_env->next_cpu = next_cpu;
> +    ENV_GET_CPU(new_env)->next_cpu = next_cpu;
>  
>      /* Clone all break/watchpoints.
>         Note: Once we support ptrace with hw-debug register access, make sure
> @@ -1707,12 +1706,14 @@ static void core_begin(MemoryListener *listener)
>  
>  static void tcg_commit(MemoryListener *listener)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
>      /* since each CPU stores ram addresses in its TLB cache, we must
>         reset the modified entries */
>      /* XXX: slow ! */
> -    for(env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUArchState *env = cpu->env_ptr;
> +
>          tlb_flush(env, 1);
>      }
>  }
> diff --git a/gdbstub.c b/gdbstub.c
> index 9e7f7a1..5793bcd 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -1839,6 +1839,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
>          /* Generate the XML description for this CPU.  */
>          if (!target_xml[0]) {
>              GDBRegisterState *r;
> +            CPUArchState *env = first_cpu->env_ptr;
>  
>              snprintf(target_xml, sizeof(target_xml),
>                       "<?xml version=\"1.0\"?>"
> @@ -1847,7 +1848,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
>                       "<xi:include href=\"%s\"/>",
>                       GDB_CORE_XML);
>  
> -            for (r = first_cpu->gdb_regs; r; r = r->next) {
> +            for (r = env->gdb_regs; r; r = r->next) {
>                  pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
>                  pstrcat(target_xml, sizeof(target_xml), r->xml);
>                  pstrcat(target_xml, sizeof(target_xml), "\"/>");
> @@ -1949,6 +1950,7 @@ static const int xlat_gdb_type[] = {
>  
>  static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
>  {
> +    CPUState *cpu;
>      CPUArchState *env;
>      int err = 0;
>  
> @@ -1958,7 +1960,8 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
>      switch (type) {
>      case GDB_BREAKPOINT_SW:
>      case GDB_BREAKPOINT_HW:
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +            env = cpu->env_ptr;
>              err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
>              if (err)
>                  break;
> @@ -1968,7 +1971,8 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
>      case GDB_WATCHPOINT_WRITE:
>      case GDB_WATCHPOINT_READ:
>      case GDB_WATCHPOINT_ACCESS:
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +            env = cpu->env_ptr;
>              err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
>                                          NULL);
>              if (err)
> @@ -1983,6 +1987,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
>  
>  static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
>  {
> +    CPUState *cpu;
>      CPUArchState *env;
>      int err = 0;
>  
> @@ -1992,7 +1997,8 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
>      switch (type) {
>      case GDB_BREAKPOINT_SW:
>      case GDB_BREAKPOINT_HW:
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +            env = cpu->env_ptr;
>              err = cpu_breakpoint_remove(env, addr, BP_GDB);
>              if (err)
>                  break;
> @@ -2002,7 +2008,8 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
>      case GDB_WATCHPOINT_WRITE:
>      case GDB_WATCHPOINT_READ:
>      case GDB_WATCHPOINT_ACCESS:
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +            env = cpu->env_ptr;
>              err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
>              if (err)
>                  break;
> @@ -2016,6 +2023,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
>  
>  static void gdb_breakpoint_remove_all(void)
>  {
> +    CPUState *cpu;
>      CPUArchState *env;
>  
>      if (kvm_enabled()) {
> @@ -2023,7 +2031,8 @@ static void gdb_breakpoint_remove_all(void)
>          return;
>      }
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        env = cpu->env_ptr;
>          cpu_breakpoint_remove_all(env, BP_GDB);
>  #ifndef CONFIG_USER_ONLY
>          cpu_watchpoint_remove_all(env, BP_GDB);
> @@ -2390,7 +2399,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
>              put_packet(s, "QC1");
>              break;
>          } else if (strcmp(p,"fThreadInfo") == 0) {
> -            s->query_cpu = first_cpu;
> +            s->query_cpu = first_cpu->env_ptr;
>              goto report_cpuinfo;
>          } else if (strcmp(p,"sThreadInfo") == 0) {
>          report_cpuinfo:
> @@ -2398,7 +2407,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
>                  snprintf(buf, sizeof(buf), "m%x",
>                           cpu_index(ENV_GET_CPU(s->query_cpu)));
>                  put_packet(s, buf);
> -                s->query_cpu = s->query_cpu->next_cpu;
> +                s->query_cpu = ENV_GET_CPU(s->query_cpu)->next_cpu->env_ptr;
>              } else
>                  put_packet(s, "l");
>              break;
> @@ -2865,8 +2874,8 @@ static void gdb_accept(void)
>      socket_set_nodelay(fd);
>  
>      s = g_malloc0(sizeof(GDBState));
> -    s->c_cpu = first_cpu;
> -    s->g_cpu = first_cpu;
> +    s->c_cpu = first_cpu->env_ptr;
> +    s->g_cpu = first_cpu->env_ptr;
>      s->fd = fd;
>      gdb_has_xml = 0;
>  
> @@ -3050,8 +3059,8 @@ int gdbserver_start(const char *device)
>          mon_chr = s->mon_chr;
>          memset(s, 0, sizeof(GDBState));
>      }
> -    s->c_cpu = first_cpu;
> -    s->g_cpu = first_cpu;
> +    s->c_cpu = first_cpu->env_ptr;
> +    s->g_cpu = first_cpu->env_ptr;
>      s->chr = chr;
>      s->state = chr ? RS_IDLE : RS_INACTIVE;
>      s->mon_chr = mon_chr;
> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
> index f451529..ad13d3f 100644
> --- a/hw/arm/boot.c
> +++ b/hw/arm/boot.c
> @@ -329,7 +329,7 @@ static void do_cpu_reset(void *opaque)
>              env->regs[15] = info->entry & 0xfffffffe;
>              env->thumb = info->entry & 1;
>          } else {
> -            if (env == first_cpu) {
> +            if (CPU(cpu) == first_cpu) {
>                  env->regs[15] = info->loader_start;
>                  if (!info->dtb_filename) {
>                      if (old_param) {
> @@ -347,7 +347,7 @@ static void do_cpu_reset(void *opaque)
>  
>  void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
>  {
> -    CPUARMState *env = &cpu->env;
> +    CPUState *cs = CPU(cpu);
>      int kernel_size;
>      int initrd_size;
>      int n;
> @@ -472,9 +472,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
>      }
>      info->is_linux = is_linux;
>  
> -    for (; env; env = env->next_cpu) {
> -        cpu = arm_env_get_cpu(env);
> -        env->boot_info = info;
> +    for (; cs; cs = cs->next_cpu) {
> +        cpu = ARM_CPU(cs);
> +        cpu->env.boot_info = info;
>          qemu_register_reset(do_cpu_reset, cpu);
>      }
>  }
> diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
> index 74f110b..7c90b2d 100644
> --- a/hw/arm/exynos4_boards.c
> +++ b/hw/arm/exynos4_boards.c
> @@ -131,7 +131,7 @@ static void nuri_init(QEMUMachineInitArgs *args)
>  {
>      exynos4_boards_init_common(args, EXYNOS4_BOARD_NURI);
>  
> -    arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
> +    arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo);
>  }
>  
>  static void smdkc210_init(QEMUMachineInitArgs *args)
> @@ -141,7 +141,7 @@ static void smdkc210_init(QEMUMachineInitArgs *args)
>  
>      lan9215_init(SMDK_LAN9118_BASE_ADDR,
>              qemu_irq_invert(s->irq_table[exynos4210_get_irq(37, 1)]));
> -    arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
> +    arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo);
>  }
>  
>  static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS] = {
> diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
> index 4405dbd..1d28842 100644
> --- a/hw/arm/highbank.c
> +++ b/hw/arm/highbank.c
> @@ -321,7 +321,7 @@ static void highbank_init(QEMUMachineInitArgs *args)
>      highbank_binfo.loader_start = 0;
>      highbank_binfo.write_secondary_boot = hb_write_secondary;
>      highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary;
> -    arm_load_kernel(arm_env_get_cpu(first_cpu), &highbank_binfo);
> +    arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo);
>  }
>  
>  static QEMUMachine highbank_machine = {
> diff --git a/hw/arm/realview.c b/hw/arm/realview.c
> index d6f47bf..05dc3f3 100644
> --- a/hw/arm/realview.c
> +++ b/hw/arm/realview.c
> @@ -329,7 +329,7 @@ static void realview_init(QEMUMachineInitArgs *args,
>      realview_binfo.nb_cpus = smp_cpus;
>      realview_binfo.board_id = realview_board_id[board_type];
>      realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0);
> -    arm_load_kernel(arm_env_get_cpu(first_cpu), &realview_binfo);
> +    arm_load_kernel(ARM_CPU(first_cpu), &realview_binfo);
>  }
>  
>  static void realview_eb_init(QEMUMachineInitArgs *args)
> diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
> index a077c62..c8f2890 100644
> --- a/hw/arm/vexpress.c
> +++ b/hw/arm/vexpress.c
> @@ -519,7 +519,7 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard,
>      vexpress_binfo.smp_loader_start = map[VE_SRAM];
>      vexpress_binfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30;
>      vexpress_binfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr;
> -    arm_load_kernel(arm_env_get_cpu(first_cpu), &vexpress_binfo);
> +    arm_load_kernel(ARM_CPU(first_cpu), &vexpress_binfo);
>  }
>  
>  static void vexpress_a9_init(QEMUMachineInitArgs *args)
> diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
> index 4602a6f..f73eeed 100644
> --- a/hw/arm/xilinx_zynq.c
> +++ b/hw/arm/xilinx_zynq.c
> @@ -226,7 +226,7 @@ static void zynq_init(QEMUMachineInitArgs *args)
>      zynq_binfo.nb_cpus = 1;
>      zynq_binfo.board_id = 0xd32;
>      zynq_binfo.loader_start = 0;
> -    arm_load_kernel(arm_env_get_cpu(first_cpu), &zynq_binfo);
> +    arm_load_kernel(ARM_CPU(first_cpu), &zynq_binfo);
>  }
>  
>  static QEMUMachine zynq_machine = {
> diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
> index 87d4d0f..eba275a 100644
> --- a/hw/i386/kvm/clock.c
> +++ b/hw/i386/kvm/clock.c
> @@ -65,7 +65,7 @@ static void kvmclock_vm_state_change(void *opaque, int running,
>                                       RunState state)
>  {
>      KVMClockState *s = opaque;
> -    CPUArchState *penv = first_cpu;
> +    CPUState *cpu = first_cpu;
>      int cap_clock_ctrl = kvm_check_extension(kvm_state, KVM_CAP_KVMCLOCK_CTRL);
>      int ret;
>  
> @@ -75,8 +75,8 @@ static void kvmclock_vm_state_change(void *opaque, int running,
>          if (!cap_clock_ctrl) {
>              return;
>          }
> -        for (penv = first_cpu; penv != NULL; penv = penv->next_cpu) {
> -            ret = kvm_vcpu_ioctl(ENV_GET_CPU(penv), KVM_KVMCLOCK_CTRL, 0);
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +            ret = kvm_vcpu_ioctl(cpu, KVM_KVMCLOCK_CTRL, 0);
>              if (ret) {
>                  if (ret != -EINVAL) {
>                      fprintf(stderr, "%s: %s\n", __func__, strerror(-ret));
> @@ -128,9 +128,11 @@ static const TypeInfo kvmclock_info = {
>  /* Note: Must be called after VCPU initialization. */
>  void kvmclock_create(void)
>  {
> +    X86CPU *cpu = X86_CPU(first_cpu);
> +
>      if (kvm_enabled() &&
> -        first_cpu->features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
> -                                         (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
> +        cpu->env.features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
> +                                       (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
>          sysbus_create_simple("kvmclock", -1, NULL);
>      }
>  }
> diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
> index 9aac9de..5538071 100644
> --- a/hw/i386/kvmvapic.c
> +++ b/hw/i386/kvmvapic.c
> @@ -490,13 +490,15 @@ static void vapic_enable_tpr_reporting(bool enable)
>      VAPICEnableTPRReporting info = {
>          .enable = enable,
>      };
> +    CPUState *cs;
>      X86CPU *cpu;
>      CPUX86State *env;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cpu = x86_env_get_cpu(env);
> +    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
> +        cpu = X86_CPU(cs);
> +        env = &cpu->env;
>          info.apic = env->apic_state;
> -        run_on_cpu(CPU(cpu), vapic_do_enable_tpr_reporting, &info);
> +        run_on_cpu(cs, vapic_do_enable_tpr_reporting, &info);
>      }
>  }
>  
> @@ -718,8 +720,9 @@ static int vapic_init(SysBusDevice *dev)
>  static void do_vapic_enable(void *data)
>  {
>      VAPICROMState *s = data;
> +    X86CPU *cpu = X86_CPU(first_cpu);
>  
> -    vapic_enable(s, first_cpu);
> +    vapic_enable(s, &cpu->env);
>  }
>  
>  static int vapic_post_load(void *opaque, int version_id)
> @@ -742,7 +745,7 @@ static int vapic_post_load(void *opaque, int version_id)
>      }
>      if (s->state == VAPIC_ACTIVE) {
>          if (smp_cpus == 1) {
> -            run_on_cpu(ENV_GET_CPU(first_cpu), do_vapic_enable, s);
> +            run_on_cpu(first_cpu, do_vapic_enable, s);
>          } else {
>              zero = g_malloc0(s->rom_state.vapic_size);
>              cpu_physical_memory_rw(s->vapic_paddr, zero,
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index c43be54..38722a1 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -160,8 +160,9 @@ void cpu_smm_register(cpu_set_smm_t callback, void *arg)
>  
>  void cpu_smm_update(CPUX86State *env)
>  {
> -    if (smm_set && smm_arg && env == first_cpu)
> +    if (smm_set && smm_arg && CPU(x86_env_get_cpu(env)) == first_cpu) {
>          smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
> +    }
>  }
>  
>  
> @@ -185,18 +186,21 @@ int cpu_get_pic_interrupt(CPUX86State *env)
>  
>  static void pic_irq_request(void *opaque, int irq, int level)
>  {
> -    CPUX86State *env = first_cpu;
> +    CPUState *cs = first_cpu;
> +    X86CPU *cpu = X86_CPU(cs);
> +    CPUX86State *env = &cpu->env;
>  
>      DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq);
>      if (env->apic_state) {
> -        while (env) {
> +        while (cs) {
> +            cpu = X86_CPU(cs);
> +            env = &cpu->env;
>              if (apic_accept_pic_intr(env->apic_state)) {
>                  apic_deliver_pic_intr(env->apic_state, level);
>              }
> -            env = env->next_cpu;
> +            cs = cs->next_cpu;
>          }
>      } else {
> -        CPUState *cs = CPU(x86_env_get_cpu(env));
>          if (level) {
>              cpu_interrupt(cs, CPU_INTERRUPT_HARD);
>          } else {
> @@ -1205,8 +1209,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
>          }
>      }
>  
> -    a20_line = qemu_allocate_irqs(handle_a20_line_change,
> -                                  x86_env_get_cpu(first_cpu), 2);
> +    a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2);
>      i8042 = isa_create_simple(isa_bus, "i8042");
>      i8042_setup_a20_line(i8042, &a20_line[0]);
>      if (!no_vmport) {
> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> index 97362f2..f3bf240 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -213,8 +213,7 @@ static void pc_init1(MemoryRegion *system_memory,
>      if (pci_enabled && acpi_enabled) {
>          i2c_bus *smbus;
>  
> -        smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt,
> -                                     x86_env_get_cpu(first_cpu), 1);
> +        smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
>          /* TODO: Populate SPD eeprom data.  */
>          smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
>                                gsi[9], *smi_irq,
> diff --git a/hw/intc/sh_intc.c b/hw/intc/sh_intc.c
> index 050bfb6..f1138e3 100644
> --- a/hw/intc/sh_intc.c
> +++ b/hw/intc/sh_intc.c
> @@ -42,16 +42,15 @@ void sh_intc_toggle_source(struct intc_source *source,
>          pending_changed = 1;
>  
>      if (pending_changed) {
> -        CPUState *cpu = CPU(sh_env_get_cpu(first_cpu));
>          if (source->pending) {
>              source->parent->pending++;
>              if (source->parent->pending == 1) {
> -                cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
> +                cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD);
>              }
>          } else {
>              source->parent->pending--;
>              if (source->parent->pending == 0) {
> -                cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
> +                cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD);
>              }
>  	}
>      }
> diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
> index 667e882..69e1f50 100644
> --- a/hw/isa/lpc_ich9.c
> +++ b/hw/isa/lpc_ich9.c
> @@ -380,7 +380,7 @@ static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
>  
>      /* SMI_EN = PMBASE + 30. SMI control and enable register */
>      if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) {
> -        cpu_interrupt(CPU(x86_env_get_cpu(first_cpu)), CPU_INTERRUPT_SMI);
> +        cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
>      }
>  }
>  
> diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
> index 4fc611c..adea146 100644
> --- a/hw/mips/mips_malta.c
> +++ b/hw/mips/mips_malta.c
> @@ -844,7 +844,8 @@ void mips_malta_init(QEMUMachineInitArgs *args)
>          cpu_mips_clock_init(env);
>          qemu_register_reset(main_cpu_reset, cpu);
>      }
> -    env = first_cpu;
> +    cpu = MIPS_CPU(first_cpu);
> +    env = &cpu->env;
>  
>      /* allocate RAM */
>      if (ram_size > (256 << 20)) {
> diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
> index fb57b42..554f244 100644
> --- a/hw/ppc/ppc.c
> +++ b/hw/ppc/ppc.c
> @@ -440,15 +440,14 @@ void ppce500_irq_init(CPUPPCState *env)
>  /* Enable or Disable the E500 EPR capability */
>  void ppce500_set_mpic_proxy(bool enabled)
>  {
> -    CPUPPCState *env;
> +    CPUState *cs;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        PowerPCCPU *cpu = ppc_env_get_cpu(env);
> -        CPUState *cs = CPU(cpu);
> +    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
> +        PowerPCCPU *cpu = POWERPC_CPU(cs);
>  
> -        env->mpic_proxy = enabled;
> +        cpu->env.mpic_proxy = enabled;
>          if (kvm_enabled()) {
> -            kvmppc_set_mpic_proxy(POWERPC_CPU(cs), enabled);
> +            kvmppc_set_mpic_proxy(cpu, enabled);
>          }
>      }
>  }
> diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
> index 16e3132..45625ca 100644
> --- a/hw/ppc/prep.c
> +++ b/hw/ppc/prep.c
> @@ -594,8 +594,9 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
>      /* PCI -> ISA bridge */
>      pci = pci_create_simple(pci_bus, PCI_DEVFN(1, 0), "i82378");
>      cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
> +    cpu = POWERPC_CPU(first_cpu);
>      qdev_connect_gpio_out(&pci->qdev, 0,
> -                          first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
> +                          cpu->env.irq_inputs[PPC6xx_INPUT_INT]);
>      qdev_connect_gpio_out(&pci->qdev, 1, *cpu_exit_irq);
>      sysbus_connect_irq(&pcihost->busdev, 0, qdev_get_gpio_in(&pci->qdev, 9));
>      sysbus_connect_irq(&pcihost->busdev, 1, qdev_get_gpio_in(&pci->qdev, 11));
> @@ -640,7 +641,8 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
>      }
>      isa_create_simple(isa_bus, "i8042");
>  
> -    sysctrl->reset_irq = first_cpu->irq_inputs[PPC6xx_INPUT_HRESET];
> +    cpu = POWERPC_CPU(first_cpu);
> +    sysctrl->reset_irq = cpu->env.irq_inputs[PPC6xx_INPUT_HRESET];
>      /* System control ports */
>      register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);
>      register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 218ea23..4fce87a 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -131,7 +131,6 @@ int spapr_allocate_irq_block(int num, bool lsi)
>  static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
>  {
>      int ret = 0, offset;
> -    CPUPPCState *env;
>      CPUState *cpu;
>      char cpu_model[32];
>      int smt = kvmppc_smt_threads();
> @@ -139,8 +138,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
>  
>      assert(spapr->cpu_model);
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cpu = CPU(ppc_env_get_cpu(env));
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          uint32_t associativity[] = {cpu_to_be32(0x5),
>                                      cpu_to_be32(0x0),
>                                      cpu_to_be32(0x0),
> @@ -231,7 +229,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
>                                     uint32_t epow_irq)
>  {
>      void *fdt;
> -    CPUPPCState *env;
> +    CPUState *cs;
>      uint32_t start_prop = cpu_to_be32(initrd_base);
>      uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
>      char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
> @@ -304,10 +302,11 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
>      /* This is needed during FDT finalization */
>      spapr->cpu_model = g_strdup(modelname);
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        CPUState *cpu = CPU(ppc_env_get_cpu(env));
> -        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
> -        int index = cpu->cpu_index;
> +    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
> +        PowerPCCPU *cpu = POWERPC_CPU(cs);
> +        CPUPPCState *env = &cpu->env;
> +        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
> +        int index = cs->cpu_index;
>          uint32_t servers_prop[smp_threads];
>          uint32_t gservers_prop[smp_threads * 2];
>          char *nodename;
> @@ -632,7 +631,7 @@ static void spapr_reset_htab(sPAPREnvironment *spapr)
>  
>  static void ppc_spapr_reset(void)
>  {
> -    CPUState *first_cpu_cpu;
> +    PowerPCCPU *first_ppc_cpu;
>  
>      /* Reset the hash table & recalc the RMA */
>      spapr_reset_htab(spapr);
> @@ -644,11 +643,11 @@ static void ppc_spapr_reset(void)
>                         spapr->rtas_size);
>  
>      /* Set up the entry state */
> -    first_cpu_cpu = ENV_GET_CPU(first_cpu);
> -    first_cpu->gpr[3] = spapr->fdt_addr;
> -    first_cpu->gpr[5] = 0;
> -    first_cpu_cpu->halted = 0;
> -    first_cpu->nip = spapr->entry_point;
> +    first_ppc_cpu = POWERPC_CPU(first_cpu);
> +    first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
> +    first_ppc_cpu->env.gpr[5] = 0;
> +    first_cpu->halted = 0;
> +    first_ppc_cpu->env.nip = spapr->entry_point;
>  
>  }
>  
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index 6760851..6499cd0 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -356,7 +356,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
>  
>  void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
>      GCC_FMT_ATTR(2, 3);
> -extern CPUArchState *first_cpu;
>  
>  /* Flags for use in ENV->INTERRUPT_PENDING.
>  
> diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
> index c4ac929..39094b3 100644
> --- a/include/exec/cpu-defs.h
> +++ b/include/exec/cpu-defs.h
> @@ -181,7 +181,6 @@ typedef struct CPUWatchpoint {
>      sigjmp_buf jmp_env;                                                 \
>      int exception_index;                                                \
>                                                                          \
> -    CPUArchState *next_cpu; /* next CPU sharing TB cache */                 \
>      /* user data */                                                     \
>      void *opaque;                                                       \
>                                                                          \
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 0e2e76c..2a64af2 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -114,6 +114,7 @@ struct kvm_run;
>   *           CPU and return to its top level loop.
>   * @env_ptr: Pointer to subclass-specific CPUArchState field.
>   * @current_tb: Currently executing TB.
> + * @next_cpu: Next CPU sharing TB cache.
>   * @kvm_fd: vCPU file descriptor for KVM.
>   *
>   * State of one CPU core or thread.
> @@ -146,6 +147,7 @@ struct CPUState {
>  
>      void *env_ptr; /* CPUArchState */
>      struct TranslationBlock *current_tb;
> +    CPUState *next_cpu;
>  
>      int kvm_fd;
>      bool kvm_vcpu_dirty;
> @@ -157,6 +159,8 @@ struct CPUState {
>      uint32_t halted; /* used by alpha, cris, ppc TCG */
>  };
>  
> +extern CPUState *first_cpu;
> +
>  DECLARE_TLS(CPUState *, cpu_single_cpu);
>  #define cpu_single_cpu tls_var(cpu_single_cpu)
>  
> diff --git a/kvm-all.c b/kvm-all.c
> index b3ba6aa..6b9e343 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1896,7 +1896,7 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
>  {
>      CPUState *current_cpu = ENV_GET_CPU(current_env);
>      struct kvm_sw_breakpoint *bp;
> -    CPUArchState *env;
> +    CPUState *cpu;
>      int err;
>  
>      if (type == GDB_BREAKPOINT_SW) {
> @@ -1928,7 +1928,9 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
>          }
>      }
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUArchState *env = cpu->env_ptr;
> +
>          err = kvm_update_guest_debug(env, 0);
>          if (err) {
>              return err;
> @@ -1942,7 +1944,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>  {
>      CPUState *current_cpu = ENV_GET_CPU(current_env);
>      struct kvm_sw_breakpoint *bp;
> -    CPUArchState *env;
> +    CPUState *cpu;
>      int err;
>  
>      if (type == GDB_BREAKPOINT_SW) {
> @@ -1970,7 +1972,9 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>          }
>      }
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUArchState *env = cpu->env_ptr;
> +
>          err = kvm_update_guest_debug(env, 0);
>          if (err) {
>              return err;
> @@ -1983,14 +1987,12 @@ void kvm_remove_all_breakpoints(CPUState *current_cpu)
>  {
>      struct kvm_sw_breakpoint *bp, *next;
>      KVMState *s = current_cpu->kvm_state;
> -    CPUArchState *env;
>      CPUState *cpu;
>  
>      QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
>          if (kvm_arch_remove_sw_breakpoint(current_cpu, bp) != 0) {
>              /* Try harder to find a CPU that currently sees the breakpoint. */
> -            for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -                cpu = ENV_GET_CPU(env);
> +            for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>                  if (kvm_arch_remove_sw_breakpoint(cpu, bp) == 0) {
>                      break;
>                  }
> @@ -2001,7 +2003,9 @@ void kvm_remove_all_breakpoints(CPUState *current_cpu)
>      }
>      kvm_arch_remove_all_hw_breakpoints();
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUArchState *env = cpu->env_ptr;
> +
>          kvm_update_guest_debug(env, 0);
>      }
>  }
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index ddef23e..d517450 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -2628,7 +2628,7 @@ static int fill_note_info(struct elf_note_info *info,
>                            long signr, const CPUArchState *env)
>  {
>  #define NUMNOTES 3
> -    CPUArchState *cpu = NULL;
> +    CPUState *cpu = NULL;
>      TaskState *ts = (TaskState *)env->opaque;
>      int i;
>  
> @@ -2667,9 +2667,10 @@ static int fill_note_info(struct elf_note_info *info,
>      /* read and fill status of all threads */
>      cpu_list_lock();
>      for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> -        if (cpu == thread_env)
> +        if (cpu == ENV_GET_CPU(thread_env)) {
>              continue;
> -        fill_thread_info(info, cpu);
> +        }
> +        fill_thread_info(info, (CPUArchState *)cpu->env_ptr);
>      }
>      cpu_list_unlock();
>  
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 95e17cf..3e60877 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -120,8 +120,8 @@ void fork_end(int child)
>      if (child) {
>          /* Child processes created by fork() only have a single thread.
>             Discard information about the parent threads.  */
> -        first_cpu = thread_env;
> -        thread_env->next_cpu = NULL;
> +        first_cpu = ENV_GET_CPU(thread_env);
> +        first_cpu->next_cpu = NULL;
>          pending_cpus = 0;
>          pthread_mutex_init(&exclusive_lock, NULL);
>          pthread_mutex_init(&cpu_list_mutex, NULL);
> @@ -148,7 +148,6 @@ static inline void exclusive_idle(void)
>     Must only be called from outside cpu_arm_exec.   */
>  static inline void start_exclusive(void)
>  {
> -    CPUArchState *other;
>      CPUState *other_cpu;
>  
>      pthread_mutex_lock(&exclusive_lock);
> @@ -156,8 +155,7 @@ static inline void start_exclusive(void)
>  
>      pending_cpus = 1;
>      /* Make all other cpus stop executing.  */
> -    for (other = first_cpu; other; other = other->next_cpu) {
> -        other_cpu = ENV_GET_CPU(other);
> +    for (other_cpu = first_cpu; other_cpu; other_cpu = other_cpu->next_cpu) {
>          if (other_cpu->running) {
>              pending_cpus++;
>              cpu_exit(other_cpu);
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index cdd0c28..340666f 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -5030,6 +5030,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>                      abi_long arg5, abi_long arg6, abi_long arg7,
>                      abi_long arg8)
>  {
> +#ifdef CONFIG_USE_NPTL
> +    CPUState *cpu = ENV_GET_CPU(cpu_env);
> +#endif
>      abi_long ret;
>      struct stat st;
>      struct statfs stfs;
> @@ -5052,13 +5055,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>           be disabling signals.  */
>        if (first_cpu->next_cpu) {
>            TaskState *ts;
> -          CPUArchState **lastp;
> -          CPUArchState *p;
> +          CPUState **lastp;
> +          CPUState *p;
>  
>            cpu_list_lock();
>            lastp = &first_cpu;
>            p = first_cpu;
> -          while (p && p != (CPUArchState *)cpu_env) {
> +          while (p && p != cpu) {
>                lastp = &p->next_cpu;
>                p = p->next_cpu;
>            }
> diff --git a/memory_mapping.c b/memory_mapping.c
> index 5634f81..515a984 100644
> --- a/memory_mapping.c
> +++ b/memory_mapping.c
> @@ -165,13 +165,13 @@ void memory_mapping_list_init(MemoryMappingList *list)
>      QTAILQ_INIT(&list->head);
>  }
>  
> -static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
> +static CPUState *find_paging_enabled_cpu(CPUState *start_cpu)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
> -    for (env = start_cpu; env != NULL; env = env->next_cpu) {
> -        if (cpu_paging_enabled(ENV_GET_CPU(env))) {
> -            return env;
> +    for (cpu = start_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        if (cpu_paging_enabled(cpu)) {
> +            return cpu;
>          }
>      }
>  
> @@ -180,15 +180,15 @@ static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
>  
>  void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp)
>  {
> -    CPUArchState *env, *first_paging_enabled_cpu;
> +    CPUState *cpu, *first_paging_enabled_cpu;
>      RAMBlock *block;
>      ram_addr_t offset, length;
>  
>      first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu);
>      if (first_paging_enabled_cpu) {
> -        for (env = first_paging_enabled_cpu; env != NULL; env = env->next_cpu) {
> +        for (cpu = first_paging_enabled_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>              Error *err = NULL;
> -            cpu_get_memory_mapping(ENV_GET_CPU(env), list, &err);
> +            cpu_get_memory_mapping(cpu, list, &err);
>              if (err) {
>                  error_propagate(errp, err);
>                  return;
> diff --git a/monitor.c b/monitor.c
> index 9be515c..2ba7876 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -1806,14 +1806,12 @@ static void do_info_mtree(Monitor *mon, const QDict *qdict)
>  static void do_info_numa(Monitor *mon, const QDict *qdict)
>  {
>      int i;
> -    CPUArchState *env;
>      CPUState *cpu;
>  
>      monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
>      for (i = 0; i < nb_numa_nodes; i++) {
>          monitor_printf(mon, "node %d cpus:", i);
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -            cpu = ENV_GET_CPU(env);
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>              if (cpu->numa_node == i) {
>                  monitor_printf(mon, " %d", cpu->cpu_index);
>              }
> diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
> index 83898cd..d133228 100644
> --- a/target-i386/arch_dump.c
> +++ b/target-i386/arch_dump.c
> @@ -185,7 +185,8 @@ int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
>      X86CPU *cpu = X86_CPU(cs);
>      int ret;
>  #ifdef TARGET_X86_64
> -    bool lma = !!(first_cpu->hflags & HF_LMA_MASK);
> +    X86CPU *first_x86_cpu = X86_CPU(first_cpu);
> +    bool lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);
>  
>      if (lma) {
>          ret = x86_64_write_elf64_note(f, &cpu->env, cpuid, opaque);
> @@ -394,7 +395,9 @@ int cpu_get_dump_info(ArchDumpInfo *info)
>      RAMBlock *block;
>  
>  #ifdef TARGET_X86_64
> -    lma = !!(first_cpu->hflags & HF_LMA_MASK);
> +    X86CPU *first_x86_cpu = X86_CPU(first_cpu);
> +
> +    lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);
>  #endif
>  
>      if (lma) {
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 5e5abe3..d6f43d7 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -1188,6 +1188,7 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
>                          uint64_t status, uint64_t mcg_status, uint64_t addr,
>                          uint64_t misc, int flags)
>  {
> +    CPUState *cs = CPU(cpu);
>      CPUX86State *cenv = &cpu->env;
>      MCEInjectionParams params = {
>          .mon = mon,
> @@ -1200,7 +1201,6 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
>          .flags = flags,
>      };
>      unsigned bank_num = cenv->mcg_cap & 0xff;
> -    CPUX86State *env;
>  
>      if (!cenv->mcg_cap) {
>          monitor_printf(mon, "MCE injection not supported\n");
> @@ -1220,19 +1220,22 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
>          return;
>      }
>  
> -    run_on_cpu(CPU(cpu), do_inject_x86_mce, &params);
> +    run_on_cpu(cs, do_inject_x86_mce, &params);
>      if (flags & MCE_INJECT_BROADCAST) {
> +        CPUState *other_cs;
> +
>          params.bank = 1;
>          params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
>          params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
>          params.addr = 0;
>          params.misc = 0;
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -            if (cenv == env) {
> +        for (other_cs = first_cpu; other_cs != NULL;
> +             other_cs = other_cs->next_cpu) {
> +            if (other_cs == cs) {
>                  continue;
>              }
> -            params.cpu = x86_env_get_cpu(env);
> -            run_on_cpu(CPU(cpu), do_inject_x86_mce, &params);
> +            params.cpu = X86_CPU(other_cs);
> +            run_on_cpu(other_cs, do_inject_x86_mce, &params);
>          }
>      }
>  }
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 39f4fbb..cc3dcec 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -345,20 +345,22 @@ int kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
>  
>  int kvm_arch_on_sigbus(int code, void *addr)
>  {
> -    if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
> +    X86CPU *cpu = X86_CPU(first_cpu);
> +
> +    if ((cpu->env.mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
>          ram_addr_t ram_addr;
>          hwaddr paddr;
>  
>          /* Hope we are lucky for AO MCE */
>          if (qemu_ram_addr_from_host(addr, &ram_addr) ||
> -            !kvm_physical_memory_addr_from_host(CPU(first_cpu)->kvm_state,
> +            !kvm_physical_memory_addr_from_host(first_cpu->kvm_state,
>                                                  addr, &paddr)) {
>              fprintf(stderr, "Hardware memory error for memory used by "
>                      "QEMU itself instead of guest system!: %p\n", addr);
>              return 0;
>          }
>          kvm_hwpoison_page_add(ram_addr);
> -        kvm_mce_inject(x86_env_get_cpu(first_cpu), paddr, code);
> +        kvm_mce_inject(X86_CPU(first_cpu), paddr, code);
>      } else {
>          if (code == BUS_MCEERR_AO) {
>              return 0;
> diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
> index e345f9a..957926c 100644
> --- a/target-i386/misc_helper.c
> +++ b/target-i386/misc_helper.c
> @@ -610,7 +610,7 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
>      cpu = x86_env_get_cpu(env);
>      cs = CPU(cpu);
>      /* XXX: not complete but not completely erroneous */
> -    if (cs->cpu_index != 0 || env->next_cpu != NULL) {
> +    if (cs->cpu_index != 0 || cs->next_cpu != NULL) {
>          /* more than one CPU: do not sleep because another CPU may
>             wake this one */
>      } else {
> diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
> index f6838ec..5cf1c3f 100644
> --- a/target-mips/op_helper.c
> +++ b/target-mips/op_helper.c
> @@ -1696,39 +1696,38 @@ target_ulong helper_emt(void)
>  
>  target_ulong helper_dvpe(CPUMIPSState *env)
>  {
> -    CPUMIPSState *other_cpu_env = first_cpu;
> +    CPUState *other_cs = first_cpu;
>      target_ulong prev = env->mvp->CP0_MVPControl;
>  
>      do {
> +        MIPSCPU *other_cpu = MIPS_CPU(other_cs);
>          /* Turn off all VPEs except the one executing the dvpe.  */
> -        if (other_cpu_env != env) {
> -            MIPSCPU *other_cpu = mips_env_get_cpu(other_cpu_env);
> -
> -            other_cpu_env->mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
> +        if (&other_cpu->env != env) {
> +            other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
>              mips_vpe_sleep(other_cpu);
>          }
> -        other_cpu_env = other_cpu_env->next_cpu;
> -    } while (other_cpu_env);
> +        other_cs = other_cs->next_cpu;
> +    } while (other_cs);
>      return prev;
>  }
>  
>  target_ulong helper_evpe(CPUMIPSState *env)
>  {
> -    CPUMIPSState *other_cpu_env = first_cpu;
> +    CPUState *other_cs = first_cpu;
>      target_ulong prev = env->mvp->CP0_MVPControl;
>  
>      do {
> -        MIPSCPU *other_cpu = mips_env_get_cpu(other_cpu_env);
> +        MIPSCPU *other_cpu = MIPS_CPU(other_cs);
>  
> -        if (other_cpu_env != env
> +        if (&other_cpu->env != env
>              /* If the VPE is WFI, don't disturb its sleep.  */
>              && !mips_vpe_is_wfi(other_cpu)) {
>              /* Enable the VPE.  */
> -            other_cpu_env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
> +            other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
>              mips_vpe_wake(other_cpu); /* And wake it up.  */
>          }
> -        other_cpu_env = other_cpu_env->next_cpu;
> -    } while (other_cpu_env);
> +        other_cs = other_cs->next_cpu;
> +    } while (other_cs);
>      return prev;
>  }
>  #endif /* !CONFIG_USER_ONLY */
> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> index 4a0fc6d..e9fcad8 100644
> --- a/target-ppc/excp_helper.c
> +++ b/target-ppc/excp_helper.c
> @@ -986,16 +986,19 @@ void helper_msgsnd(target_ulong rb)
>  {
>      int irq = dbell2irq(rb);
>      int pir = rb & DBELL_PIRTAG_MASK;
> -    CPUPPCState *cenv;
> +    CPUState *cs;
>  
>      if (irq < 0) {
>          return;
>      }
>  
> -    for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
> +    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
> +        PowerPCCPU *cpu = POWERPC_CPU(cs);
> +        CPUPPCState *cenv = &cpu->env;
> +
>          if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
>              cenv->pending_interrupts |= 1 << irq;
> -            cpu_interrupt(CPU(ppc_env_get_cpu(cenv)), CPU_INTERRUPT_HARD);
> +            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
>          }
>      }
>  }
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index 2bbc3b8..416c41e 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -1574,7 +1574,7 @@ uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift)
>  
>      /* Find the largest hardware supported page size that's less than
>       * or equal to the (logical) backing page size of guest RAM */
> -    kvm_get_smmu_info(ppc_env_get_cpu(first_cpu), &info);
> +    kvm_get_smmu_info(POWERPC_CPU(first_cpu), &info);
>      rampagesize = getrampagesize();
>      best_page_shift = 0;
>  
> diff --git a/translate-all.c b/translate-all.c
> index 4177293..64cf855 100644
> --- a/translate-all.c
> +++ b/translate-all.c
> @@ -681,7 +681,7 @@ static void page_flush_tb(void)
>  /* XXX: tb_flush is currently not thread safe */
>  void tb_flush(CPUArchState *env1)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
>  #if defined(DEBUG_FLUSH)
>      printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
> @@ -696,7 +696,9 @@ void tb_flush(CPUArchState *env1)
>      }
>      tcg_ctx.tb_ctx.nb_tbs = 0;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUArchState *env = cpu->env_ptr;
> +
>          memset(env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *));
>      }
>  
> @@ -821,7 +823,7 @@ static inline void tb_reset_jump(TranslationBlock *tb, int n)
>  /* invalidate one TB */
>  void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>      PageDesc *p;
>      unsigned int h, n1;
>      tb_page_addr_t phys_pc;
> @@ -848,7 +850,9 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
>  
>      /* 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) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUArchState *env = cpu->env_ptr;
> +
>          if (env->tb_jmp_cache[h] == tb) {
>              env->tb_jmp_cache[h] = NULL;
>          }
> 

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 21/29] cpu: Make first_cpu and next_cpu CPUState
@ 2013-06-17 16:20     ` Paolo Bonzini
  0 siblings, 0 replies; 98+ messages in thread
From: Paolo Bonzini @ 2013-06-17 16:20 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Anthony Liguori, Riku Voipio, Igor Mitsyanko,
	Mark Langsdorf, Evgeny Voevodin, Marcelo Tosatti, qemu-devel,
	Gleb Natapov, Alexander Graf, Peter Crosthwaite,
	Andreas Färber, PowerPC, Paul Brook, David Gibson, kvm,
	Luiz Capitulino, Edgar E. Iglesias, Maksim Kozlov,
	Aurelien Jarno, Dmitry Solodkiy

Il 16/06/2013 17:57, Andreas Färber ha scritto:
> Move first_cpu to qom/cpu.h.
> 
> gdbstub needs to use CPUState::env_ptr for now.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c                    | 126 ++++++++++++++++++++++++----------------------
>  cputlb.c                  |   4 +-
>  dump.c                    |  16 +++---
>  exec.c                    |  43 ++++++++--------
>  gdbstub.c                 |  33 +++++++-----
>  hw/arm/boot.c             |  10 ++--
>  hw/arm/exynos4_boards.c   |   4 +-
>  hw/arm/highbank.c         |   2 +-
>  hw/arm/realview.c         |   2 +-
>  hw/arm/vexpress.c         |   2 +-
>  hw/arm/xilinx_zynq.c      |   2 +-
>  hw/i386/kvm/clock.c       |  12 +++--
>  hw/i386/kvmvapic.c        |  13 +++--
>  hw/i386/pc.c              |  17 ++++---
>  hw/i386/pc_piix.c         |   3 +-
>  hw/intc/sh_intc.c         |   5 +-
>  hw/isa/lpc_ich9.c         |   2 +-
>  hw/mips/mips_malta.c      |   3 +-
>  hw/ppc/ppc.c              |  11 ++--
>  hw/ppc/prep.c             |   6 ++-
>  hw/ppc/spapr.c            |  27 +++++-----
>  include/exec/cpu-all.h    |   1 -
>  include/exec/cpu-defs.h   |   1 -
>  include/qom/cpu.h         |   4 ++
>  kvm-all.c                 |  20 +++++---
>  linux-user/elfload.c      |   7 +--
>  linux-user/main.c         |   8 ++-
>  linux-user/syscall.c      |   9 ++--
>  memory_mapping.c          |  16 +++---
>  monitor.c                 |   4 +-
>  target-i386/arch_dump.c   |   7 ++-
>  target-i386/helper.c      |  15 +++---
>  target-i386/kvm.c         |   8 +--
>  target-i386/misc_helper.c |   2 +-
>  target-mips/op_helper.c   |  25 +++++----
>  target-ppc/excp_helper.c  |   9 ++--
>  target-ppc/kvm.c          |   2 +-
>  translate-all.c           |  12 +++--
>  38 files changed, 267 insertions(+), 226 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index 808503b..ec38644 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -60,7 +60,7 @@
>  
>  #endif /* CONFIG_LINUX */
>  
> -static CPUArchState *next_cpu;
> +static CPUState *next_cpu;
>  
>  static bool cpu_thread_is_idle(CPUState *cpu)
>  {
> @@ -79,10 +79,10 @@ static bool cpu_thread_is_idle(CPUState *cpu)
>  
>  static bool all_cpu_threads_idle(void)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        if (!cpu_thread_is_idle(ENV_GET_CPU(env))) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        if (!cpu_thread_is_idle(cpu)) {
>              return false;
>          }
>      }
> @@ -388,15 +388,13 @@ void configure_icount(const char *option)
>  void hw_error(const char *fmt, ...)
>  {
>      va_list ap;
> -    CPUArchState *env;
>      CPUState *cpu;
>  
>      va_start(ap, fmt);
>      fprintf(stderr, "qemu: hardware error: ");
>      vfprintf(stderr, fmt, ap);
>      fprintf(stderr, "\n");
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cpu = ENV_GET_CPU(env);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
>          cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU);
>      }
> @@ -406,28 +404,28 @@ void hw_error(const char *fmt, ...)
>  
>  void cpu_synchronize_all_states(void)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
> -    for (env = first_cpu; env; env = env->next_cpu) {
> -        cpu_synchronize_state(ENV_GET_CPU(env));
> +    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
> +        cpu_synchronize_state(cpu);
>      }
>  }
>  
>  void cpu_synchronize_all_post_reset(void)
>  {
> -    CPUArchState *cpu;
> +    CPUState *cpu;
>  
>      for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
> -        cpu_synchronize_post_reset(ENV_GET_CPU(cpu));
> +        cpu_synchronize_post_reset(cpu);
>      }
>  }
>  
>  void cpu_synchronize_all_post_init(void)
>  {
> -    CPUArchState *cpu;
> +    CPUState *cpu;
>  
>      for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
> -        cpu_synchronize_post_init(ENV_GET_CPU(cpu));
> +        cpu_synchronize_post_init(cpu);
>      }
>  }
>  
> @@ -698,7 +696,7 @@ static void qemu_wait_io_event_common(CPUState *cpu)
>  
>  static void qemu_tcg_wait_io_event(void)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
>      while (all_cpu_threads_idle()) {
>         /* Start accounting real time to the virtual clock if the CPUs
> @@ -711,8 +709,8 @@ static void qemu_tcg_wait_io_event(void)
>          qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex);
>      }
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        qemu_wait_io_event_common(ENV_GET_CPU(env));
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        qemu_wait_io_event_common(cpu);
>      }
>  }
>  
> @@ -814,7 +812,6 @@ static void tcg_signal_cpu_creation(CPUState *cpu, void *data)
>  static void *qemu_tcg_cpu_thread_fn(void *arg)
>  {
>      CPUState *cpu = arg;
> -    CPUArchState *env;
>  
>      qemu_tcg_init_cpu_signals();
>      qemu_thread_get_self(cpu->thread);
> @@ -824,12 +821,12 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
>      qemu_cond_signal(&qemu_cpu_cond);
>  
>      /* wait for initial kick-off after machine start */
> -    while (ENV_GET_CPU(first_cpu)->stopped) {
> +    while (first_cpu->stopped) {
>          qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
>  
>          /* process any pending work */
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -            qemu_wait_io_event_common(ENV_GET_CPU(env));
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +            qemu_wait_io_event_common(cpu);
>          }
>      }
>  
> @@ -923,7 +920,7 @@ void qemu_mutex_lock_iothread(void)
>      } else {
>          iothread_requesting_mutex = true;
>          if (qemu_mutex_trylock(&qemu_global_mutex)) {
> -            qemu_cpu_kick_thread(ENV_GET_CPU(first_cpu));
> +            qemu_cpu_kick_thread(first_cpu);
>              qemu_mutex_lock(&qemu_global_mutex);
>          }
>          iothread_requesting_mutex = false;
> @@ -938,14 +935,13 @@ void qemu_mutex_unlock_iothread(void)
>  
>  static int all_vcpus_paused(void)
>  {
> -    CPUArchState *penv = first_cpu;
> +    CPUState *cpu = first_cpu;
>  
> -    while (penv) {
> -        CPUState *pcpu = ENV_GET_CPU(penv);
> -        if (!pcpu->stopped) {
> +    while (cpu) {
> +        if (!cpu->stopped) {
>              return 0;
>          }
> -        penv = penv->next_cpu;
> +        cpu = cpu->next_cpu;
>      }
>  
>      return 1;
> @@ -953,25 +949,23 @@ static int all_vcpus_paused(void)
>  
>  void pause_all_vcpus(void)
>  {
> -    CPUArchState *penv = first_cpu;
> +    CPUState *cpu = first_cpu;
>  
>      qemu_clock_enable(vm_clock, false);
> -    while (penv) {
> -        CPUState *pcpu = ENV_GET_CPU(penv);
> -        pcpu->stop = true;
> -        qemu_cpu_kick(pcpu);
> -        penv = penv->next_cpu;
> +    while (cpu) {
> +        cpu->stop = true;
> +        qemu_cpu_kick(cpu);
> +        cpu = cpu->next_cpu;
>      }
>  
>      if (qemu_in_vcpu_thread()) {
>          cpu_stop_current();
>          if (!kvm_enabled()) {
> -            penv = first_cpu;
> -            while (penv) {
> -                CPUState *pcpu = ENV_GET_CPU(penv);
> -                pcpu->stop = false;
> -                pcpu->stopped = true;
> -                penv = penv->next_cpu;
> +            cpu = first_cpu;
> +            while (cpu) {
> +                cpu->stop = false;
> +                cpu->stopped = true;
> +                cpu = cpu->next_cpu;
>              }
>              return;
>          }
> @@ -979,10 +973,10 @@ void pause_all_vcpus(void)
>  
>      while (!all_vcpus_paused()) {
>          qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
> -        penv = first_cpu;
> -        while (penv) {
> -            qemu_cpu_kick(ENV_GET_CPU(penv));
> -            penv = penv->next_cpu;
> +        cpu = first_cpu;
> +        while (cpu) {
> +            qemu_cpu_kick(cpu);
> +            cpu = cpu->next_cpu;
>          }
>      }
>  }
> @@ -996,13 +990,12 @@ void cpu_resume(CPUState *cpu)
>  
>  void resume_all_vcpus(void)
>  {
> -    CPUArchState *penv = first_cpu;
> +    CPUState *cpu = first_cpu;
>  
>      qemu_clock_enable(vm_clock, true);
> -    while (penv) {
> -        CPUState *pcpu = ENV_GET_CPU(penv);
> -        cpu_resume(pcpu);
> -        penv = penv->next_cpu;
> +    while (cpu) {
> +        cpu_resume(cpu);
> +        cpu = cpu->next_cpu;
>      }
>  }
>  
> @@ -1151,8 +1144,8 @@ static void tcg_exec_all(void)
>          next_cpu = first_cpu;
>      }
>      for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
> -        CPUArchState *env = next_cpu;
> -        CPUState *cpu = ENV_GET_CPU(env);
> +        CPUState *cpu = next_cpu;
> +        CPUArchState *env = cpu->env_ptr;
>  
>          qemu_clock_enable(vm_clock,
>                            (env->singlestep_enabled & SSTEP_NOTIMER) == 0);
> @@ -1172,12 +1165,10 @@ static void tcg_exec_all(void)
>  
>  void set_numa_modes(void)
>  {
> -    CPUArchState *env;
>      CPUState *cpu;
>      int i;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cpu = ENV_GET_CPU(env);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          for (i = 0; i < nb_numa_nodes; i++) {
>              if (test_bit(cpu->cpu_index, node_cpumask[i])) {
>                  cpu->numa_node = i;
> @@ -1197,18 +1188,30 @@ void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
>  CpuInfoList *qmp_query_cpus(Error **errp)
>  {
>      CpuInfoList *head = NULL, *cur_item = NULL;
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        CPUState *cpu = ENV_GET_CPU(env);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          CpuInfoList *info;
> +#if defined(TARGET_I386)
> +        X86CPU *x86_cpu = X86_CPU(cpu);
> +        CPUX86State *env = &x86_cpu->env;
> +#elif defined(TARGET_PPC)
> +        PowerPCCPU *ppc_cpu = POWERPC_CPU(cpu);
> +        CPUPPCState *env = &ppc_cpu->env;
> +#elif defined(TARGET_SPARC)
> +        SPARCCPU *sparc_cpu = SPARC_CPU(cpu);
> +        CPUSPARCState *env = &sparc_cpu->env;
> +#elif defined(TARGET_MIPS)
> +        MIPSCPU *mips_cpu = MIPS_CPU(cpu);
> +        CPUMIPSState *env = &mips_cpu->env;
> +#endif
>  
>          cpu_synchronize_state(cpu);
>  
>          info = g_malloc0(sizeof(*info));
>          info->value = g_malloc0(sizeof(*info->value));
>          info->value->CPU = cpu->cpu_index;
> -        info->value->current = (env == first_cpu);
> +        info->value->current = (cpu == first_cpu);
>          info->value->halted = cpu->halted;
>          info->value->thread_id = cpu->thread_id;
>  #if defined(TARGET_I386)
> @@ -1316,11 +1319,14 @@ exit:
>  void qmp_inject_nmi(Error **errp)
>  {
>  #if defined(TARGET_I386)
> -    CPUArchState *env;
> +    CPUState *cs;
> +
> +    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
> +        X86CPU *cpu = X86_CPU(cs);
> +        CPUX86State *env = &cpu->env;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
>          if (!env->apic_state) {
> -            cpu_interrupt(CPU(x86_env_get_cpu(env)), CPU_INTERRUPT_NMI);
> +            cpu_interrupt(cs, CPU_INTERRUPT_NMI);
>          } else {
>              apic_deliver_nmi(env->apic_state);
>          }
> diff --git a/cputlb.c b/cputlb.c
> index 232c488..74b98ec 100644
> --- a/cputlb.c
> +++ b/cputlb.c
> @@ -175,11 +175,13 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
>  
>  void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length)
>  {
> +    CPUState *cpu;
>      CPUArchState *env;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          int mmu_idx;
>  
> +        env = cpu->env_ptr;
>          for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
>              unsigned int i;
>  
> diff --git a/dump.c b/dump.c
> index 44a1339..e414515 100644
> --- a/dump.c
> +++ b/dump.c
> @@ -275,13 +275,11 @@ static inline int cpu_index(CPUState *cpu)
>  
>  static int write_elf64_notes(DumpState *s)
>  {
> -    CPUArchState *env;
>      CPUState *cpu;
>      int ret;
>      int id;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cpu = ENV_GET_CPU(env);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          id = cpu_index(cpu);
>          ret = cpu_write_elf64_note(fd_write_vmcore, cpu, id, s);
>          if (ret < 0) {
> @@ -290,7 +288,7 @@ static int write_elf64_notes(DumpState *s)
>          }
>      }
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          ret = cpu_write_elf64_qemunote(fd_write_vmcore, cpu, s);
>          if (ret < 0) {
>              dump_error(s, "dump: failed to write CPU status.\n");
> @@ -327,13 +325,11 @@ static int write_elf32_note(DumpState *s)
>  
>  static int write_elf32_notes(DumpState *s)
>  {
> -    CPUArchState *env;
>      CPUState *cpu;
>      int ret;
>      int id;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cpu = ENV_GET_CPU(env);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          id = cpu_index(cpu);
>          ret = cpu_write_elf32_note(fd_write_vmcore, cpu, id, s);
>          if (ret < 0) {
> @@ -342,7 +338,7 @@ static int write_elf32_notes(DumpState *s)
>          }
>      }
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          ret = cpu_write_elf32_qemunote(fd_write_vmcore, cpu, s);
>          if (ret < 0) {
>              dump_error(s, "dump: failed to write CPU status.\n");
> @@ -705,7 +701,7 @@ static ram_addr_t get_start_block(DumpState *s)
>  static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
>                       int64_t begin, int64_t length, Error **errp)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>      int nr_cpus;
>      Error *err = NULL;
>      int ret;
> @@ -738,7 +734,7 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
>       */
>      cpu_synchronize_all_states();
>      nr_cpus = 0;
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          nr_cpus++;
>      }
>  
> diff --git a/exec.c b/exec.c
> index e14a815..191eb4e 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -70,7 +70,7 @@ static MemoryRegion io_mem_unassigned, io_mem_subpage_ram;
>  
>  #endif
>  
> -CPUArchState *first_cpu;
> +CPUState *first_cpu;
>  /* current CPU in the current thread. It is only valid inside
>     cpu_exec() */
>  DEFINE_TLS(CPUState *,cpu_single_cpu);
> @@ -264,27 +264,26 @@ static const VMStateDescription vmstate_cpu_common = {
>  
>  CPUState *qemu_get_cpu(int index)
>  {
> -    CPUArchState *env = first_cpu;
> -    CPUState *cpu = NULL;
> +    CPUState *cpu = first_cpu;
>  
> -    while (env) {
> -        cpu = ENV_GET_CPU(env);
> +    while (cpu) {
>          if (cpu->cpu_index == index) {
>              break;
>          }
> -        env = env->next_cpu;
> +        cpu = cpu->next_cpu;
>      }
>  
> -    return env ? cpu : NULL;
> +    return cpu;
>  }
>  
>  void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data)
>  {
> -    CPUArchState *env = first_cpu;
> +    CPUState *cpu;
>  
> -    while (env) {
> -        func(ENV_GET_CPU(env), data);
> -        env = env->next_cpu;
> +    cpu = first_cpu;
> +    while (cpu) {
> +        func(cpu, data);
> +        cpu = cpu->next_cpu;
>      }
>  }
>  
> @@ -292,17 +291,17 @@ void cpu_exec_init(CPUArchState *env)
>  {
>      CPUState *cpu = ENV_GET_CPU(env);
>      CPUClass *cc = CPU_GET_CLASS(cpu);
> -    CPUArchState **penv;
> +    CPUState **pcpu;
>      int cpu_index;
>  
>  #if defined(CONFIG_USER_ONLY)
>      cpu_list_lock();
>  #endif
> -    env->next_cpu = NULL;
> -    penv = &first_cpu;
> +    cpu->next_cpu = NULL;
> +    pcpu = &first_cpu;
>      cpu_index = 0;
> -    while (*penv != NULL) {
> -        penv = &(*penv)->next_cpu;
> +    while (*pcpu != NULL) {
> +        pcpu = &(*pcpu)->next_cpu;
>          cpu_index++;
>      }
>      cpu->cpu_index = cpu_index;
> @@ -312,7 +311,7 @@ void cpu_exec_init(CPUArchState *env)
>  #ifndef CONFIG_USER_ONLY
>      cpu->thread_id = qemu_get_thread_id();
>  #endif
> -    *penv = env;
> +    *pcpu = cpu;
>  #if defined(CONFIG_USER_ONLY)
>      cpu_list_unlock();
>  #endif
> @@ -551,7 +550,7 @@ void cpu_abort(CPUArchState *env, const char *fmt, ...)
>  CPUArchState *cpu_copy(CPUArchState *env)
>  {
>      CPUArchState *new_env = cpu_init(env->cpu_model_str);
> -    CPUArchState *next_cpu = new_env->next_cpu;
> +    CPUState *next_cpu = ENV_GET_CPU(new_env)->next_cpu;
>  #if defined(TARGET_HAS_ICE)
>      CPUBreakpoint *bp;
>      CPUWatchpoint *wp;
> @@ -560,7 +559,7 @@ CPUArchState *cpu_copy(CPUArchState *env)
>      memcpy(new_env, env, sizeof(CPUArchState));
>  
>      /* Preserve chaining. */
> -    new_env->next_cpu = next_cpu;
> +    ENV_GET_CPU(new_env)->next_cpu = next_cpu;
>  
>      /* Clone all break/watchpoints.
>         Note: Once we support ptrace with hw-debug register access, make sure
> @@ -1707,12 +1706,14 @@ static void core_begin(MemoryListener *listener)
>  
>  static void tcg_commit(MemoryListener *listener)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
>      /* since each CPU stores ram addresses in its TLB cache, we must
>         reset the modified entries */
>      /* XXX: slow ! */
> -    for(env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUArchState *env = cpu->env_ptr;
> +
>          tlb_flush(env, 1);
>      }
>  }
> diff --git a/gdbstub.c b/gdbstub.c
> index 9e7f7a1..5793bcd 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -1839,6 +1839,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
>          /* Generate the XML description for this CPU.  */
>          if (!target_xml[0]) {
>              GDBRegisterState *r;
> +            CPUArchState *env = first_cpu->env_ptr;
>  
>              snprintf(target_xml, sizeof(target_xml),
>                       "<?xml version=\"1.0\"?>"
> @@ -1847,7 +1848,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
>                       "<xi:include href=\"%s\"/>",
>                       GDB_CORE_XML);
>  
> -            for (r = first_cpu->gdb_regs; r; r = r->next) {
> +            for (r = env->gdb_regs; r; r = r->next) {
>                  pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
>                  pstrcat(target_xml, sizeof(target_xml), r->xml);
>                  pstrcat(target_xml, sizeof(target_xml), "\"/>");
> @@ -1949,6 +1950,7 @@ static const int xlat_gdb_type[] = {
>  
>  static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
>  {
> +    CPUState *cpu;
>      CPUArchState *env;
>      int err = 0;
>  
> @@ -1958,7 +1960,8 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
>      switch (type) {
>      case GDB_BREAKPOINT_SW:
>      case GDB_BREAKPOINT_HW:
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +            env = cpu->env_ptr;
>              err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
>              if (err)
>                  break;
> @@ -1968,7 +1971,8 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
>      case GDB_WATCHPOINT_WRITE:
>      case GDB_WATCHPOINT_READ:
>      case GDB_WATCHPOINT_ACCESS:
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +            env = cpu->env_ptr;
>              err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
>                                          NULL);
>              if (err)
> @@ -1983,6 +1987,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
>  
>  static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
>  {
> +    CPUState *cpu;
>      CPUArchState *env;
>      int err = 0;
>  
> @@ -1992,7 +1997,8 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
>      switch (type) {
>      case GDB_BREAKPOINT_SW:
>      case GDB_BREAKPOINT_HW:
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +            env = cpu->env_ptr;
>              err = cpu_breakpoint_remove(env, addr, BP_GDB);
>              if (err)
>                  break;
> @@ -2002,7 +2008,8 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
>      case GDB_WATCHPOINT_WRITE:
>      case GDB_WATCHPOINT_READ:
>      case GDB_WATCHPOINT_ACCESS:
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +            env = cpu->env_ptr;
>              err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
>              if (err)
>                  break;
> @@ -2016,6 +2023,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
>  
>  static void gdb_breakpoint_remove_all(void)
>  {
> +    CPUState *cpu;
>      CPUArchState *env;
>  
>      if (kvm_enabled()) {
> @@ -2023,7 +2031,8 @@ static void gdb_breakpoint_remove_all(void)
>          return;
>      }
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        env = cpu->env_ptr;
>          cpu_breakpoint_remove_all(env, BP_GDB);
>  #ifndef CONFIG_USER_ONLY
>          cpu_watchpoint_remove_all(env, BP_GDB);
> @@ -2390,7 +2399,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
>              put_packet(s, "QC1");
>              break;
>          } else if (strcmp(p,"fThreadInfo") == 0) {
> -            s->query_cpu = first_cpu;
> +            s->query_cpu = first_cpu->env_ptr;
>              goto report_cpuinfo;
>          } else if (strcmp(p,"sThreadInfo") == 0) {
>          report_cpuinfo:
> @@ -2398,7 +2407,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
>                  snprintf(buf, sizeof(buf), "m%x",
>                           cpu_index(ENV_GET_CPU(s->query_cpu)));
>                  put_packet(s, buf);
> -                s->query_cpu = s->query_cpu->next_cpu;
> +                s->query_cpu = ENV_GET_CPU(s->query_cpu)->next_cpu->env_ptr;
>              } else
>                  put_packet(s, "l");
>              break;
> @@ -2865,8 +2874,8 @@ static void gdb_accept(void)
>      socket_set_nodelay(fd);
>  
>      s = g_malloc0(sizeof(GDBState));
> -    s->c_cpu = first_cpu;
> -    s->g_cpu = first_cpu;
> +    s->c_cpu = first_cpu->env_ptr;
> +    s->g_cpu = first_cpu->env_ptr;
>      s->fd = fd;
>      gdb_has_xml = 0;
>  
> @@ -3050,8 +3059,8 @@ int gdbserver_start(const char *device)
>          mon_chr = s->mon_chr;
>          memset(s, 0, sizeof(GDBState));
>      }
> -    s->c_cpu = first_cpu;
> -    s->g_cpu = first_cpu;
> +    s->c_cpu = first_cpu->env_ptr;
> +    s->g_cpu = first_cpu->env_ptr;
>      s->chr = chr;
>      s->state = chr ? RS_IDLE : RS_INACTIVE;
>      s->mon_chr = mon_chr;
> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
> index f451529..ad13d3f 100644
> --- a/hw/arm/boot.c
> +++ b/hw/arm/boot.c
> @@ -329,7 +329,7 @@ static void do_cpu_reset(void *opaque)
>              env->regs[15] = info->entry & 0xfffffffe;
>              env->thumb = info->entry & 1;
>          } else {
> -            if (env == first_cpu) {
> +            if (CPU(cpu) == first_cpu) {
>                  env->regs[15] = info->loader_start;
>                  if (!info->dtb_filename) {
>                      if (old_param) {
> @@ -347,7 +347,7 @@ static void do_cpu_reset(void *opaque)
>  
>  void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
>  {
> -    CPUARMState *env = &cpu->env;
> +    CPUState *cs = CPU(cpu);
>      int kernel_size;
>      int initrd_size;
>      int n;
> @@ -472,9 +472,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
>      }
>      info->is_linux = is_linux;
>  
> -    for (; env; env = env->next_cpu) {
> -        cpu = arm_env_get_cpu(env);
> -        env->boot_info = info;
> +    for (; cs; cs = cs->next_cpu) {
> +        cpu = ARM_CPU(cs);
> +        cpu->env.boot_info = info;
>          qemu_register_reset(do_cpu_reset, cpu);
>      }
>  }
> diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
> index 74f110b..7c90b2d 100644
> --- a/hw/arm/exynos4_boards.c
> +++ b/hw/arm/exynos4_boards.c
> @@ -131,7 +131,7 @@ static void nuri_init(QEMUMachineInitArgs *args)
>  {
>      exynos4_boards_init_common(args, EXYNOS4_BOARD_NURI);
>  
> -    arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
> +    arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo);
>  }
>  
>  static void smdkc210_init(QEMUMachineInitArgs *args)
> @@ -141,7 +141,7 @@ static void smdkc210_init(QEMUMachineInitArgs *args)
>  
>      lan9215_init(SMDK_LAN9118_BASE_ADDR,
>              qemu_irq_invert(s->irq_table[exynos4210_get_irq(37, 1)]));
> -    arm_load_kernel(arm_env_get_cpu(first_cpu), &exynos4_board_binfo);
> +    arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo);
>  }
>  
>  static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS] = {
> diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
> index 4405dbd..1d28842 100644
> --- a/hw/arm/highbank.c
> +++ b/hw/arm/highbank.c
> @@ -321,7 +321,7 @@ static void highbank_init(QEMUMachineInitArgs *args)
>      highbank_binfo.loader_start = 0;
>      highbank_binfo.write_secondary_boot = hb_write_secondary;
>      highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary;
> -    arm_load_kernel(arm_env_get_cpu(first_cpu), &highbank_binfo);
> +    arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo);
>  }
>  
>  static QEMUMachine highbank_machine = {
> diff --git a/hw/arm/realview.c b/hw/arm/realview.c
> index d6f47bf..05dc3f3 100644
> --- a/hw/arm/realview.c
> +++ b/hw/arm/realview.c
> @@ -329,7 +329,7 @@ static void realview_init(QEMUMachineInitArgs *args,
>      realview_binfo.nb_cpus = smp_cpus;
>      realview_binfo.board_id = realview_board_id[board_type];
>      realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0);
> -    arm_load_kernel(arm_env_get_cpu(first_cpu), &realview_binfo);
> +    arm_load_kernel(ARM_CPU(first_cpu), &realview_binfo);
>  }
>  
>  static void realview_eb_init(QEMUMachineInitArgs *args)
> diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
> index a077c62..c8f2890 100644
> --- a/hw/arm/vexpress.c
> +++ b/hw/arm/vexpress.c
> @@ -519,7 +519,7 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard,
>      vexpress_binfo.smp_loader_start = map[VE_SRAM];
>      vexpress_binfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30;
>      vexpress_binfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr;
> -    arm_load_kernel(arm_env_get_cpu(first_cpu), &vexpress_binfo);
> +    arm_load_kernel(ARM_CPU(first_cpu), &vexpress_binfo);
>  }
>  
>  static void vexpress_a9_init(QEMUMachineInitArgs *args)
> diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
> index 4602a6f..f73eeed 100644
> --- a/hw/arm/xilinx_zynq.c
> +++ b/hw/arm/xilinx_zynq.c
> @@ -226,7 +226,7 @@ static void zynq_init(QEMUMachineInitArgs *args)
>      zynq_binfo.nb_cpus = 1;
>      zynq_binfo.board_id = 0xd32;
>      zynq_binfo.loader_start = 0;
> -    arm_load_kernel(arm_env_get_cpu(first_cpu), &zynq_binfo);
> +    arm_load_kernel(ARM_CPU(first_cpu), &zynq_binfo);
>  }
>  
>  static QEMUMachine zynq_machine = {
> diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
> index 87d4d0f..eba275a 100644
> --- a/hw/i386/kvm/clock.c
> +++ b/hw/i386/kvm/clock.c
> @@ -65,7 +65,7 @@ static void kvmclock_vm_state_change(void *opaque, int running,
>                                       RunState state)
>  {
>      KVMClockState *s = opaque;
> -    CPUArchState *penv = first_cpu;
> +    CPUState *cpu = first_cpu;
>      int cap_clock_ctrl = kvm_check_extension(kvm_state, KVM_CAP_KVMCLOCK_CTRL);
>      int ret;
>  
> @@ -75,8 +75,8 @@ static void kvmclock_vm_state_change(void *opaque, int running,
>          if (!cap_clock_ctrl) {
>              return;
>          }
> -        for (penv = first_cpu; penv != NULL; penv = penv->next_cpu) {
> -            ret = kvm_vcpu_ioctl(ENV_GET_CPU(penv), KVM_KVMCLOCK_CTRL, 0);
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +            ret = kvm_vcpu_ioctl(cpu, KVM_KVMCLOCK_CTRL, 0);
>              if (ret) {
>                  if (ret != -EINVAL) {
>                      fprintf(stderr, "%s: %s\n", __func__, strerror(-ret));
> @@ -128,9 +128,11 @@ static const TypeInfo kvmclock_info = {
>  /* Note: Must be called after VCPU initialization. */
>  void kvmclock_create(void)
>  {
> +    X86CPU *cpu = X86_CPU(first_cpu);
> +
>      if (kvm_enabled() &&
> -        first_cpu->features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
> -                                         (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
> +        cpu->env.features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
> +                                       (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
>          sysbus_create_simple("kvmclock", -1, NULL);
>      }
>  }
> diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
> index 9aac9de..5538071 100644
> --- a/hw/i386/kvmvapic.c
> +++ b/hw/i386/kvmvapic.c
> @@ -490,13 +490,15 @@ static void vapic_enable_tpr_reporting(bool enable)
>      VAPICEnableTPRReporting info = {
>          .enable = enable,
>      };
> +    CPUState *cs;
>      X86CPU *cpu;
>      CPUX86State *env;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cpu = x86_env_get_cpu(env);
> +    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
> +        cpu = X86_CPU(cs);
> +        env = &cpu->env;
>          info.apic = env->apic_state;
> -        run_on_cpu(CPU(cpu), vapic_do_enable_tpr_reporting, &info);
> +        run_on_cpu(cs, vapic_do_enable_tpr_reporting, &info);
>      }
>  }
>  
> @@ -718,8 +720,9 @@ static int vapic_init(SysBusDevice *dev)
>  static void do_vapic_enable(void *data)
>  {
>      VAPICROMState *s = data;
> +    X86CPU *cpu = X86_CPU(first_cpu);
>  
> -    vapic_enable(s, first_cpu);
> +    vapic_enable(s, &cpu->env);
>  }
>  
>  static int vapic_post_load(void *opaque, int version_id)
> @@ -742,7 +745,7 @@ static int vapic_post_load(void *opaque, int version_id)
>      }
>      if (s->state == VAPIC_ACTIVE) {
>          if (smp_cpus == 1) {
> -            run_on_cpu(ENV_GET_CPU(first_cpu), do_vapic_enable, s);
> +            run_on_cpu(first_cpu, do_vapic_enable, s);
>          } else {
>              zero = g_malloc0(s->rom_state.vapic_size);
>              cpu_physical_memory_rw(s->vapic_paddr, zero,
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index c43be54..38722a1 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -160,8 +160,9 @@ void cpu_smm_register(cpu_set_smm_t callback, void *arg)
>  
>  void cpu_smm_update(CPUX86State *env)
>  {
> -    if (smm_set && smm_arg && env == first_cpu)
> +    if (smm_set && smm_arg && CPU(x86_env_get_cpu(env)) == first_cpu) {
>          smm_set(!!(env->hflags & HF_SMM_MASK), smm_arg);
> +    }
>  }
>  
>  
> @@ -185,18 +186,21 @@ int cpu_get_pic_interrupt(CPUX86State *env)
>  
>  static void pic_irq_request(void *opaque, int irq, int level)
>  {
> -    CPUX86State *env = first_cpu;
> +    CPUState *cs = first_cpu;
> +    X86CPU *cpu = X86_CPU(cs);
> +    CPUX86State *env = &cpu->env;
>  
>      DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq);
>      if (env->apic_state) {
> -        while (env) {
> +        while (cs) {
> +            cpu = X86_CPU(cs);
> +            env = &cpu->env;
>              if (apic_accept_pic_intr(env->apic_state)) {
>                  apic_deliver_pic_intr(env->apic_state, level);
>              }
> -            env = env->next_cpu;
> +            cs = cs->next_cpu;
>          }
>      } else {
> -        CPUState *cs = CPU(x86_env_get_cpu(env));
>          if (level) {
>              cpu_interrupt(cs, CPU_INTERRUPT_HARD);
>          } else {
> @@ -1205,8 +1209,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
>          }
>      }
>  
> -    a20_line = qemu_allocate_irqs(handle_a20_line_change,
> -                                  x86_env_get_cpu(first_cpu), 2);
> +    a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2);
>      i8042 = isa_create_simple(isa_bus, "i8042");
>      i8042_setup_a20_line(i8042, &a20_line[0]);
>      if (!no_vmport) {
> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> index 97362f2..f3bf240 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -213,8 +213,7 @@ static void pc_init1(MemoryRegion *system_memory,
>      if (pci_enabled && acpi_enabled) {
>          i2c_bus *smbus;
>  
> -        smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt,
> -                                     x86_env_get_cpu(first_cpu), 1);
> +        smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
>          /* TODO: Populate SPD eeprom data.  */
>          smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
>                                gsi[9], *smi_irq,
> diff --git a/hw/intc/sh_intc.c b/hw/intc/sh_intc.c
> index 050bfb6..f1138e3 100644
> --- a/hw/intc/sh_intc.c
> +++ b/hw/intc/sh_intc.c
> @@ -42,16 +42,15 @@ void sh_intc_toggle_source(struct intc_source *source,
>          pending_changed = 1;
>  
>      if (pending_changed) {
> -        CPUState *cpu = CPU(sh_env_get_cpu(first_cpu));
>          if (source->pending) {
>              source->parent->pending++;
>              if (source->parent->pending == 1) {
> -                cpu_interrupt(cpu, CPU_INTERRUPT_HARD);
> +                cpu_interrupt(first_cpu, CPU_INTERRUPT_HARD);
>              }
>          } else {
>              source->parent->pending--;
>              if (source->parent->pending == 0) {
> -                cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
> +                cpu_reset_interrupt(first_cpu, CPU_INTERRUPT_HARD);
>              }
>  	}
>      }
> diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
> index 667e882..69e1f50 100644
> --- a/hw/isa/lpc_ich9.c
> +++ b/hw/isa/lpc_ich9.c
> @@ -380,7 +380,7 @@ static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
>  
>      /* SMI_EN = PMBASE + 30. SMI control and enable register */
>      if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) {
> -        cpu_interrupt(CPU(x86_env_get_cpu(first_cpu)), CPU_INTERRUPT_SMI);
> +        cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI);
>      }
>  }
>  
> diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
> index 4fc611c..adea146 100644
> --- a/hw/mips/mips_malta.c
> +++ b/hw/mips/mips_malta.c
> @@ -844,7 +844,8 @@ void mips_malta_init(QEMUMachineInitArgs *args)
>          cpu_mips_clock_init(env);
>          qemu_register_reset(main_cpu_reset, cpu);
>      }
> -    env = first_cpu;
> +    cpu = MIPS_CPU(first_cpu);
> +    env = &cpu->env;
>  
>      /* allocate RAM */
>      if (ram_size > (256 << 20)) {
> diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
> index fb57b42..554f244 100644
> --- a/hw/ppc/ppc.c
> +++ b/hw/ppc/ppc.c
> @@ -440,15 +440,14 @@ void ppce500_irq_init(CPUPPCState *env)
>  /* Enable or Disable the E500 EPR capability */
>  void ppce500_set_mpic_proxy(bool enabled)
>  {
> -    CPUPPCState *env;
> +    CPUState *cs;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        PowerPCCPU *cpu = ppc_env_get_cpu(env);
> -        CPUState *cs = CPU(cpu);
> +    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
> +        PowerPCCPU *cpu = POWERPC_CPU(cs);
>  
> -        env->mpic_proxy = enabled;
> +        cpu->env.mpic_proxy = enabled;
>          if (kvm_enabled()) {
> -            kvmppc_set_mpic_proxy(POWERPC_CPU(cs), enabled);
> +            kvmppc_set_mpic_proxy(cpu, enabled);
>          }
>      }
>  }
> diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
> index 16e3132..45625ca 100644
> --- a/hw/ppc/prep.c
> +++ b/hw/ppc/prep.c
> @@ -594,8 +594,9 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
>      /* PCI -> ISA bridge */
>      pci = pci_create_simple(pci_bus, PCI_DEVFN(1, 0), "i82378");
>      cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
> +    cpu = POWERPC_CPU(first_cpu);
>      qdev_connect_gpio_out(&pci->qdev, 0,
> -                          first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
> +                          cpu->env.irq_inputs[PPC6xx_INPUT_INT]);
>      qdev_connect_gpio_out(&pci->qdev, 1, *cpu_exit_irq);
>      sysbus_connect_irq(&pcihost->busdev, 0, qdev_get_gpio_in(&pci->qdev, 9));
>      sysbus_connect_irq(&pcihost->busdev, 1, qdev_get_gpio_in(&pci->qdev, 11));
> @@ -640,7 +641,8 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
>      }
>      isa_create_simple(isa_bus, "i8042");
>  
> -    sysctrl->reset_irq = first_cpu->irq_inputs[PPC6xx_INPUT_HRESET];
> +    cpu = POWERPC_CPU(first_cpu);
> +    sysctrl->reset_irq = cpu->env.irq_inputs[PPC6xx_INPUT_HRESET];
>      /* System control ports */
>      register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);
>      register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 218ea23..4fce87a 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -131,7 +131,6 @@ int spapr_allocate_irq_block(int num, bool lsi)
>  static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
>  {
>      int ret = 0, offset;
> -    CPUPPCState *env;
>      CPUState *cpu;
>      char cpu_model[32];
>      int smt = kvmppc_smt_threads();
> @@ -139,8 +138,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
>  
>      assert(spapr->cpu_model);
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cpu = CPU(ppc_env_get_cpu(env));
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          uint32_t associativity[] = {cpu_to_be32(0x5),
>                                      cpu_to_be32(0x0),
>                                      cpu_to_be32(0x0),
> @@ -231,7 +229,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
>                                     uint32_t epow_irq)
>  {
>      void *fdt;
> -    CPUPPCState *env;
> +    CPUState *cs;
>      uint32_t start_prop = cpu_to_be32(initrd_base);
>      uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
>      char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
> @@ -304,10 +302,11 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
>      /* This is needed during FDT finalization */
>      spapr->cpu_model = g_strdup(modelname);
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        CPUState *cpu = CPU(ppc_env_get_cpu(env));
> -        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
> -        int index = cpu->cpu_index;
> +    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
> +        PowerPCCPU *cpu = POWERPC_CPU(cs);
> +        CPUPPCState *env = &cpu->env;
> +        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
> +        int index = cs->cpu_index;
>          uint32_t servers_prop[smp_threads];
>          uint32_t gservers_prop[smp_threads * 2];
>          char *nodename;
> @@ -632,7 +631,7 @@ static void spapr_reset_htab(sPAPREnvironment *spapr)
>  
>  static void ppc_spapr_reset(void)
>  {
> -    CPUState *first_cpu_cpu;
> +    PowerPCCPU *first_ppc_cpu;
>  
>      /* Reset the hash table & recalc the RMA */
>      spapr_reset_htab(spapr);
> @@ -644,11 +643,11 @@ static void ppc_spapr_reset(void)
>                         spapr->rtas_size);
>  
>      /* Set up the entry state */
> -    first_cpu_cpu = ENV_GET_CPU(first_cpu);
> -    first_cpu->gpr[3] = spapr->fdt_addr;
> -    first_cpu->gpr[5] = 0;
> -    first_cpu_cpu->halted = 0;
> -    first_cpu->nip = spapr->entry_point;
> +    first_ppc_cpu = POWERPC_CPU(first_cpu);
> +    first_ppc_cpu->env.gpr[3] = spapr->fdt_addr;
> +    first_ppc_cpu->env.gpr[5] = 0;
> +    first_cpu->halted = 0;
> +    first_ppc_cpu->env.nip = spapr->entry_point;
>  
>  }
>  
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index 6760851..6499cd0 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -356,7 +356,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
>  
>  void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
>      GCC_FMT_ATTR(2, 3);
> -extern CPUArchState *first_cpu;
>  
>  /* Flags for use in ENV->INTERRUPT_PENDING.
>  
> diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
> index c4ac929..39094b3 100644
> --- a/include/exec/cpu-defs.h
> +++ b/include/exec/cpu-defs.h
> @@ -181,7 +181,6 @@ typedef struct CPUWatchpoint {
>      sigjmp_buf jmp_env;                                                 \
>      int exception_index;                                                \
>                                                                          \
> -    CPUArchState *next_cpu; /* next CPU sharing TB cache */                 \
>      /* user data */                                                     \
>      void *opaque;                                                       \
>                                                                          \
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 0e2e76c..2a64af2 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -114,6 +114,7 @@ struct kvm_run;
>   *           CPU and return to its top level loop.
>   * @env_ptr: Pointer to subclass-specific CPUArchState field.
>   * @current_tb: Currently executing TB.
> + * @next_cpu: Next CPU sharing TB cache.
>   * @kvm_fd: vCPU file descriptor for KVM.
>   *
>   * State of one CPU core or thread.
> @@ -146,6 +147,7 @@ struct CPUState {
>  
>      void *env_ptr; /* CPUArchState */
>      struct TranslationBlock *current_tb;
> +    CPUState *next_cpu;
>  
>      int kvm_fd;
>      bool kvm_vcpu_dirty;
> @@ -157,6 +159,8 @@ struct CPUState {
>      uint32_t halted; /* used by alpha, cris, ppc TCG */
>  };
>  
> +extern CPUState *first_cpu;
> +
>  DECLARE_TLS(CPUState *, cpu_single_cpu);
>  #define cpu_single_cpu tls_var(cpu_single_cpu)
>  
> diff --git a/kvm-all.c b/kvm-all.c
> index b3ba6aa..6b9e343 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1896,7 +1896,7 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
>  {
>      CPUState *current_cpu = ENV_GET_CPU(current_env);
>      struct kvm_sw_breakpoint *bp;
> -    CPUArchState *env;
> +    CPUState *cpu;
>      int err;
>  
>      if (type == GDB_BREAKPOINT_SW) {
> @@ -1928,7 +1928,9 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
>          }
>      }
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUArchState *env = cpu->env_ptr;
> +
>          err = kvm_update_guest_debug(env, 0);
>          if (err) {
>              return err;
> @@ -1942,7 +1944,7 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>  {
>      CPUState *current_cpu = ENV_GET_CPU(current_env);
>      struct kvm_sw_breakpoint *bp;
> -    CPUArchState *env;
> +    CPUState *cpu;
>      int err;
>  
>      if (type == GDB_BREAKPOINT_SW) {
> @@ -1970,7 +1972,9 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
>          }
>      }
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUArchState *env = cpu->env_ptr;
> +
>          err = kvm_update_guest_debug(env, 0);
>          if (err) {
>              return err;
> @@ -1983,14 +1987,12 @@ void kvm_remove_all_breakpoints(CPUState *current_cpu)
>  {
>      struct kvm_sw_breakpoint *bp, *next;
>      KVMState *s = current_cpu->kvm_state;
> -    CPUArchState *env;
>      CPUState *cpu;
>  
>      QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
>          if (kvm_arch_remove_sw_breakpoint(current_cpu, bp) != 0) {
>              /* Try harder to find a CPU that currently sees the breakpoint. */
> -            for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -                cpu = ENV_GET_CPU(env);
> +            for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>                  if (kvm_arch_remove_sw_breakpoint(cpu, bp) == 0) {
>                      break;
>                  }
> @@ -2001,7 +2003,9 @@ void kvm_remove_all_breakpoints(CPUState *current_cpu)
>      }
>      kvm_arch_remove_all_hw_breakpoints();
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUArchState *env = cpu->env_ptr;
> +
>          kvm_update_guest_debug(env, 0);
>      }
>  }
> diff --git a/linux-user/elfload.c b/linux-user/elfload.c
> index ddef23e..d517450 100644
> --- a/linux-user/elfload.c
> +++ b/linux-user/elfload.c
> @@ -2628,7 +2628,7 @@ static int fill_note_info(struct elf_note_info *info,
>                            long signr, const CPUArchState *env)
>  {
>  #define NUMNOTES 3
> -    CPUArchState *cpu = NULL;
> +    CPUState *cpu = NULL;
>      TaskState *ts = (TaskState *)env->opaque;
>      int i;
>  
> @@ -2667,9 +2667,10 @@ static int fill_note_info(struct elf_note_info *info,
>      /* read and fill status of all threads */
>      cpu_list_lock();
>      for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> -        if (cpu == thread_env)
> +        if (cpu == ENV_GET_CPU(thread_env)) {
>              continue;
> -        fill_thread_info(info, cpu);
> +        }
> +        fill_thread_info(info, (CPUArchState *)cpu->env_ptr);
>      }
>      cpu_list_unlock();
>  
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 95e17cf..3e60877 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -120,8 +120,8 @@ void fork_end(int child)
>      if (child) {
>          /* Child processes created by fork() only have a single thread.
>             Discard information about the parent threads.  */
> -        first_cpu = thread_env;
> -        thread_env->next_cpu = NULL;
> +        first_cpu = ENV_GET_CPU(thread_env);
> +        first_cpu->next_cpu = NULL;
>          pending_cpus = 0;
>          pthread_mutex_init(&exclusive_lock, NULL);
>          pthread_mutex_init(&cpu_list_mutex, NULL);
> @@ -148,7 +148,6 @@ static inline void exclusive_idle(void)
>     Must only be called from outside cpu_arm_exec.   */
>  static inline void start_exclusive(void)
>  {
> -    CPUArchState *other;
>      CPUState *other_cpu;
>  
>      pthread_mutex_lock(&exclusive_lock);
> @@ -156,8 +155,7 @@ static inline void start_exclusive(void)
>  
>      pending_cpus = 1;
>      /* Make all other cpus stop executing.  */
> -    for (other = first_cpu; other; other = other->next_cpu) {
> -        other_cpu = ENV_GET_CPU(other);
> +    for (other_cpu = first_cpu; other_cpu; other_cpu = other_cpu->next_cpu) {
>          if (other_cpu->running) {
>              pending_cpus++;
>              cpu_exit(other_cpu);
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index cdd0c28..340666f 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -5030,6 +5030,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>                      abi_long arg5, abi_long arg6, abi_long arg7,
>                      abi_long arg8)
>  {
> +#ifdef CONFIG_USE_NPTL
> +    CPUState *cpu = ENV_GET_CPU(cpu_env);
> +#endif
>      abi_long ret;
>      struct stat st;
>      struct statfs stfs;
> @@ -5052,13 +5055,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>           be disabling signals.  */
>        if (first_cpu->next_cpu) {
>            TaskState *ts;
> -          CPUArchState **lastp;
> -          CPUArchState *p;
> +          CPUState **lastp;
> +          CPUState *p;
>  
>            cpu_list_lock();
>            lastp = &first_cpu;
>            p = first_cpu;
> -          while (p && p != (CPUArchState *)cpu_env) {
> +          while (p && p != cpu) {
>                lastp = &p->next_cpu;
>                p = p->next_cpu;
>            }
> diff --git a/memory_mapping.c b/memory_mapping.c
> index 5634f81..515a984 100644
> --- a/memory_mapping.c
> +++ b/memory_mapping.c
> @@ -165,13 +165,13 @@ void memory_mapping_list_init(MemoryMappingList *list)
>      QTAILQ_INIT(&list->head);
>  }
>  
> -static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
> +static CPUState *find_paging_enabled_cpu(CPUState *start_cpu)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
> -    for (env = start_cpu; env != NULL; env = env->next_cpu) {
> -        if (cpu_paging_enabled(ENV_GET_CPU(env))) {
> -            return env;
> +    for (cpu = start_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        if (cpu_paging_enabled(cpu)) {
> +            return cpu;
>          }
>      }
>  
> @@ -180,15 +180,15 @@ static CPUArchState *find_paging_enabled_cpu(CPUArchState *start_cpu)
>  
>  void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp)
>  {
> -    CPUArchState *env, *first_paging_enabled_cpu;
> +    CPUState *cpu, *first_paging_enabled_cpu;
>      RAMBlock *block;
>      ram_addr_t offset, length;
>  
>      first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu);
>      if (first_paging_enabled_cpu) {
> -        for (env = first_paging_enabled_cpu; env != NULL; env = env->next_cpu) {
> +        for (cpu = first_paging_enabled_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>              Error *err = NULL;
> -            cpu_get_memory_mapping(ENV_GET_CPU(env), list, &err);
> +            cpu_get_memory_mapping(cpu, list, &err);
>              if (err) {
>                  error_propagate(errp, err);
>                  return;
> diff --git a/monitor.c b/monitor.c
> index 9be515c..2ba7876 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -1806,14 +1806,12 @@ static void do_info_mtree(Monitor *mon, const QDict *qdict)
>  static void do_info_numa(Monitor *mon, const QDict *qdict)
>  {
>      int i;
> -    CPUArchState *env;
>      CPUState *cpu;
>  
>      monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
>      for (i = 0; i < nb_numa_nodes; i++) {
>          monitor_printf(mon, "node %d cpus:", i);
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -            cpu = ENV_GET_CPU(env);
> +        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>              if (cpu->numa_node == i) {
>                  monitor_printf(mon, " %d", cpu->cpu_index);
>              }
> diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
> index 83898cd..d133228 100644
> --- a/target-i386/arch_dump.c
> +++ b/target-i386/arch_dump.c
> @@ -185,7 +185,8 @@ int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
>      X86CPU *cpu = X86_CPU(cs);
>      int ret;
>  #ifdef TARGET_X86_64
> -    bool lma = !!(first_cpu->hflags & HF_LMA_MASK);
> +    X86CPU *first_x86_cpu = X86_CPU(first_cpu);
> +    bool lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);
>  
>      if (lma) {
>          ret = x86_64_write_elf64_note(f, &cpu->env, cpuid, opaque);
> @@ -394,7 +395,9 @@ int cpu_get_dump_info(ArchDumpInfo *info)
>      RAMBlock *block;
>  
>  #ifdef TARGET_X86_64
> -    lma = !!(first_cpu->hflags & HF_LMA_MASK);
> +    X86CPU *first_x86_cpu = X86_CPU(first_cpu);
> +
> +    lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);
>  #endif
>  
>      if (lma) {
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 5e5abe3..d6f43d7 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -1188,6 +1188,7 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
>                          uint64_t status, uint64_t mcg_status, uint64_t addr,
>                          uint64_t misc, int flags)
>  {
> +    CPUState *cs = CPU(cpu);
>      CPUX86State *cenv = &cpu->env;
>      MCEInjectionParams params = {
>          .mon = mon,
> @@ -1200,7 +1201,6 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
>          .flags = flags,
>      };
>      unsigned bank_num = cenv->mcg_cap & 0xff;
> -    CPUX86State *env;
>  
>      if (!cenv->mcg_cap) {
>          monitor_printf(mon, "MCE injection not supported\n");
> @@ -1220,19 +1220,22 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
>          return;
>      }
>  
> -    run_on_cpu(CPU(cpu), do_inject_x86_mce, &params);
> +    run_on_cpu(cs, do_inject_x86_mce, &params);
>      if (flags & MCE_INJECT_BROADCAST) {
> +        CPUState *other_cs;
> +
>          params.bank = 1;
>          params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
>          params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
>          params.addr = 0;
>          params.misc = 0;
> -        for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -            if (cenv == env) {
> +        for (other_cs = first_cpu; other_cs != NULL;
> +             other_cs = other_cs->next_cpu) {
> +            if (other_cs == cs) {
>                  continue;
>              }
> -            params.cpu = x86_env_get_cpu(env);
> -            run_on_cpu(CPU(cpu), do_inject_x86_mce, &params);
> +            params.cpu = X86_CPU(other_cs);
> +            run_on_cpu(other_cs, do_inject_x86_mce, &params);
>          }
>      }
>  }
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 39f4fbb..cc3dcec 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -345,20 +345,22 @@ int kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
>  
>  int kvm_arch_on_sigbus(int code, void *addr)
>  {
> -    if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
> +    X86CPU *cpu = X86_CPU(first_cpu);
> +
> +    if ((cpu->env.mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
>          ram_addr_t ram_addr;
>          hwaddr paddr;
>  
>          /* Hope we are lucky for AO MCE */
>          if (qemu_ram_addr_from_host(addr, &ram_addr) ||
> -            !kvm_physical_memory_addr_from_host(CPU(first_cpu)->kvm_state,
> +            !kvm_physical_memory_addr_from_host(first_cpu->kvm_state,
>                                                  addr, &paddr)) {
>              fprintf(stderr, "Hardware memory error for memory used by "
>                      "QEMU itself instead of guest system!: %p\n", addr);
>              return 0;
>          }
>          kvm_hwpoison_page_add(ram_addr);
> -        kvm_mce_inject(x86_env_get_cpu(first_cpu), paddr, code);
> +        kvm_mce_inject(X86_CPU(first_cpu), paddr, code);
>      } else {
>          if (code == BUS_MCEERR_AO) {
>              return 0;
> diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
> index e345f9a..957926c 100644
> --- a/target-i386/misc_helper.c
> +++ b/target-i386/misc_helper.c
> @@ -610,7 +610,7 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
>      cpu = x86_env_get_cpu(env);
>      cs = CPU(cpu);
>      /* XXX: not complete but not completely erroneous */
> -    if (cs->cpu_index != 0 || env->next_cpu != NULL) {
> +    if (cs->cpu_index != 0 || cs->next_cpu != NULL) {
>          /* more than one CPU: do not sleep because another CPU may
>             wake this one */
>      } else {
> diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
> index f6838ec..5cf1c3f 100644
> --- a/target-mips/op_helper.c
> +++ b/target-mips/op_helper.c
> @@ -1696,39 +1696,38 @@ target_ulong helper_emt(void)
>  
>  target_ulong helper_dvpe(CPUMIPSState *env)
>  {
> -    CPUMIPSState *other_cpu_env = first_cpu;
> +    CPUState *other_cs = first_cpu;
>      target_ulong prev = env->mvp->CP0_MVPControl;
>  
>      do {
> +        MIPSCPU *other_cpu = MIPS_CPU(other_cs);
>          /* Turn off all VPEs except the one executing the dvpe.  */
> -        if (other_cpu_env != env) {
> -            MIPSCPU *other_cpu = mips_env_get_cpu(other_cpu_env);
> -
> -            other_cpu_env->mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
> +        if (&other_cpu->env != env) {
> +            other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
>              mips_vpe_sleep(other_cpu);
>          }
> -        other_cpu_env = other_cpu_env->next_cpu;
> -    } while (other_cpu_env);
> +        other_cs = other_cs->next_cpu;
> +    } while (other_cs);
>      return prev;
>  }
>  
>  target_ulong helper_evpe(CPUMIPSState *env)
>  {
> -    CPUMIPSState *other_cpu_env = first_cpu;
> +    CPUState *other_cs = first_cpu;
>      target_ulong prev = env->mvp->CP0_MVPControl;
>  
>      do {
> -        MIPSCPU *other_cpu = mips_env_get_cpu(other_cpu_env);
> +        MIPSCPU *other_cpu = MIPS_CPU(other_cs);
>  
> -        if (other_cpu_env != env
> +        if (&other_cpu->env != env
>              /* If the VPE is WFI, don't disturb its sleep.  */
>              && !mips_vpe_is_wfi(other_cpu)) {
>              /* Enable the VPE.  */
> -            other_cpu_env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
> +            other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
>              mips_vpe_wake(other_cpu); /* And wake it up.  */
>          }
> -        other_cpu_env = other_cpu_env->next_cpu;
> -    } while (other_cpu_env);
> +        other_cs = other_cs->next_cpu;
> +    } while (other_cs);
>      return prev;
>  }
>  #endif /* !CONFIG_USER_ONLY */
> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> index 4a0fc6d..e9fcad8 100644
> --- a/target-ppc/excp_helper.c
> +++ b/target-ppc/excp_helper.c
> @@ -986,16 +986,19 @@ void helper_msgsnd(target_ulong rb)
>  {
>      int irq = dbell2irq(rb);
>      int pir = rb & DBELL_PIRTAG_MASK;
> -    CPUPPCState *cenv;
> +    CPUState *cs;
>  
>      if (irq < 0) {
>          return;
>      }
>  
> -    for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
> +    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
> +        PowerPCCPU *cpu = POWERPC_CPU(cs);
> +        CPUPPCState *cenv = &cpu->env;
> +
>          if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
>              cenv->pending_interrupts |= 1 << irq;
> -            cpu_interrupt(CPU(ppc_env_get_cpu(cenv)), CPU_INTERRUPT_HARD);
> +            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
>          }
>      }
>  }
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index 2bbc3b8..416c41e 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -1574,7 +1574,7 @@ uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift)
>  
>      /* Find the largest hardware supported page size that's less than
>       * or equal to the (logical) backing page size of guest RAM */
> -    kvm_get_smmu_info(ppc_env_get_cpu(first_cpu), &info);
> +    kvm_get_smmu_info(POWERPC_CPU(first_cpu), &info);
>      rampagesize = getrampagesize();
>      best_page_shift = 0;
>  
> diff --git a/translate-all.c b/translate-all.c
> index 4177293..64cf855 100644
> --- a/translate-all.c
> +++ b/translate-all.c
> @@ -681,7 +681,7 @@ static void page_flush_tb(void)
>  /* XXX: tb_flush is currently not thread safe */
>  void tb_flush(CPUArchState *env1)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>  
>  #if defined(DEBUG_FLUSH)
>      printf("qemu: flush code_size=%ld nb_tbs=%d avg_tb_size=%ld\n",
> @@ -696,7 +696,9 @@ void tb_flush(CPUArchState *env1)
>      }
>      tcg_ctx.tb_ctx.nb_tbs = 0;
>  
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUArchState *env = cpu->env_ptr;
> +
>          memset(env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *));
>      }
>  
> @@ -821,7 +823,7 @@ static inline void tb_reset_jump(TranslationBlock *tb, int n)
>  /* invalidate one TB */
>  void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
>  {
> -    CPUArchState *env;
> +    CPUState *cpu;
>      PageDesc *p;
>      unsigned int h, n1;
>      tb_page_addr_t phys_pc;
> @@ -848,7 +850,9 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
>  
>      /* 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) {
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
> +        CPUArchState *env = cpu->env_ptr;
> +
>          if (env->tb_jmp_cache[h] == tb) {
>              env->tb_jmp_cache[h] = NULL;
>          }
> 

Acked-by: Paolo Bonzini <pbonzini@redhat.com>

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 02/29] kvm: Change cpu_synchronize_state() argument to CPUState
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
  (?)
@ 2013-06-17 19:46   ` Richard Henderson
  2013-06-17 20:58     ` Andreas Färber
  -1 siblings, 1 reply; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 19:46 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> @@ -627,7 +627,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
>      hwaddr rom_paddr;
>      VAPICROMState *s = opaque;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));

ENV_GET_CPU, surely.

> @@ -66,7 +66,7 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
>      unsigned char command;
>      uint32_t eax;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));

Likewise.

> @@ -78,7 +78,7 @@ void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
>      int i;
>      uint64_t slbe, slbv;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));

Likewise.

> @@ -9534,7 +9534,7 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
>  
>      int i;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));

Likewise.



r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 01/29] kvm: Change kvm_cpu_synchronize_state() argument to CPUState
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
  (?)
@ 2013-06-17 19:48   ` Richard Henderson
  -1 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 19:48 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> It no longer relies on CPUArchState since 20d695a.
> 
> Reviewed-by: liguang <lig.fnst@cn.fujitsu.com>
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  hw/ppc/spapr_rtas.c  |  2 +-
>  include/sysemu/kvm.h |  4 ++--
>  kvm-all.c            |  4 +---
>  kvm-stub.c           |  2 +-
>  target-i386/kvm.c    | 10 +++++-----
>  5 files changed, 10 insertions(+), 12 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 03/29] gdbstub: Simplify find_cpu()
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 03/29] gdbstub: Simplify find_cpu() Andreas Färber
@ 2013-06-17 19:54   ` Richard Henderson
  2013-06-19 17:30     ` Andreas Färber
  0 siblings, 1 reply; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 19:54 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> Use qemu_get_cpu() and CPUState::env_ptr.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 04/29] cpu: Change cpu_exit() argument to CPUState
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 04/29] cpu: Change cpu_exit() argument to CPUState Andreas Färber
@ 2013-06-17 19:59   ` Richard Henderson
  2013-06-17 21:00     ` Andreas Färber
  0 siblings, 1 reply; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 19:59 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> @@ -1110,7 +1110,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
>      CPUX86State *env = cpu_single_env;
>  
>      if (env && level) {
> -        cpu_exit(env);
> +        cpu_exit(CPU(x86_env_get_cpu(env)));
...
> @@ -253,7 +253,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
>      CPUMIPSState *env = cpu_single_env;
>  
>      if (env && level) {
> -        cpu_exit(env);
> +        cpu_exit(CPU(mips_env_get_cpu(env)));
...
> @@ -102,7 +102,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
>      CPUMIPSState *env = cpu_single_env;
>  
>      if (env && level) {
> -        cpu_exit(env);
> +        cpu_exit(CPU(mips_env_get_cpu(env)));
...
> @@ -773,7 +773,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
>      CPUMIPSState *env = cpu_single_env;
>  
>      if (env && level) {
> -        cpu_exit(env);
> +        cpu_exit(CPU(mips_env_get_cpu(env)));
...
> @@ -420,7 +420,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
>      CPUPPCState *env = cpu_single_env;
>  
>      if (env && level) {
> -        cpu_exit(env);
> +        cpu_exit(CPU(ppc_env_get_cpu(env)));

ENV_GET_CPU, 5 instances.


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 05/29] cpus: Change cpu_thread_is_idle() argument to CPUState
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 05/29] cpus: Change cpu_thread_is_idle() " Andreas Färber
@ 2013-06-17 20:00   ` Richard Henderson
  0 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:00 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> It no longer needs CPUArchState.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 06/29] cpus: Change qemu_kvm_wait_io_event() argument to CPUState
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 06/29] cpus: Change qemu_kvm_wait_io_event() " Andreas Färber
@ 2013-06-17 20:02   ` Richard Henderson
  0 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:02 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> It no longer uses CPUArchState.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 07/29] kvm: Change kvm_set_signal_mask() argument to CPUState
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
  (?)
  (?)
@ 2013-06-17 20:03   ` Richard Henderson
  -1 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:03 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> CPUArchState is no longer needed.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 08/29] cpus: Change qemu_kvm_init_cpu_signals() argument to CPUState
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 08/29] cpus: Change qemu_kvm_init_cpu_signals() " Andreas Färber
@ 2013-06-17 20:04   ` Richard Henderson
  0 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:04 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 09/29] cpu: Turn cpu_dump_{state, statistics}() into CPUState hooks
  2013-06-16 15:57   ` [Qemu-devel] [PATCH qom-cpu v2 09/29] cpu: Turn cpu_dump_{state, statistics}() " Andreas Färber
  (?)
@ 2013-06-17 20:12   ` Richard Henderson
  -1 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:12 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> +    CPUState *cs = CPU(sparc_env_get_cpu(env));
> +    CPUState *cs = CPU(sparc_env_get_cpu(env));
> +    CPUState *cs = CPU(openrisc_env_get_cpu(env));
> +    CPUState *cs = CPU(sh_env_get_cpu(env));
> +    CPUState *cs = CPU(cris_env_get_cpu(env));
> +    CPUState *cs = CPU(mb_env_get_cpu(env));
> +    CPUState *cs = CPU(m68k_env_get_cpu(env));
> +    CPUState *cs = CPU(alpha_env_get_cpu(env));
> +    CPUState *cs = CPU(s390_env_get_cpu(env));

ENV_GET_CPU.


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH qom-cpu v2 10/29] kvm: Change kvm_handle_internal_error() argument to CPUState
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
@ 2013-06-17 20:13     ` Richard Henderson
  -1 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:13 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Marcelo Tosatti, qemu-devel, Gleb Natapov, Overall

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  kvm-all.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 10/29] kvm: Change kvm_handle_internal_error() argument to CPUState
@ 2013-06-17 20:13     ` Richard Henderson
  0 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:13 UTC (permalink / raw)
  To: Andreas Färber; +Cc: Marcelo Tosatti, qemu-devel, Gleb Natapov, Overall

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  kvm-all.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 11/29] kvm: Change kvm_cpu_exec() argument to CPUState
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
  (?)
  (?)
@ 2013-06-17 20:14   ` Richard Henderson
  -1 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:14 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c               | 2 +-
>  include/sysemu/kvm.h | 2 +-
>  kvm-all.c            | 3 +--
>  kvm-stub.c           | 4 ++--
>  4 files changed, 5 insertions(+), 6 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 12/29] gdbstub: Set gdb_set_stop_cpu() argument to CPUState
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 12/29] gdbstub: Set gdb_set_stop_cpu() " Andreas Färber
@ 2013-06-17 20:15   ` Richard Henderson
  0 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:15 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> Use CPUState::env_ptr for now.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c                 | 2 +-
>  gdbstub.c              | 4 +++-
>  include/exec/gdbstub.h | 2 +-
>  3 files changed, 5 insertions(+), 3 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 13/29] cpus: Change cpu_handle_guest_debug() argument to CPUState
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 13/29] cpus: Change cpu_handle_guest_debug() " Andreas Färber
@ 2013-06-17 20:17   ` Richard Henderson
  0 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:17 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 14/29] cpus: Change qemu_kvm_start_vcpu() argument to CPUState
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 14/29] cpus: Change qemu_kvm_start_vcpu() " Andreas Färber
@ 2013-06-17 20:18   ` Richard Henderson
  0 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:18 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> Pass it on to qemu_kvm_cpu_thread_fn().
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c | 13 +++++--------
>  1 file changed, 5 insertions(+), 8 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 15/29] cpus: Change qemu_dummy_start_vcpu() argument to CPUState
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 15/29] cpus: Change qemu_dummy_start_vcpu() " Andreas Färber
@ 2013-06-17 20:19   ` Richard Henderson
  0 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:19 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> Pass it to qemu_dummy_cpu_thread_fn().
> Use CPUState::env_ptr for cpu_single_env.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c | 15 ++++++---------
>  1 file changed, 6 insertions(+), 9 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 16/29] cpu: Change qemu_init_vcpu() argument to CPUState
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 16/29] cpu: Change qemu_init_vcpu() " Andreas Färber
@ 2013-06-17 20:23   ` Richard Henderson
  0 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:23 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> This allows to move the call to CPUState's realizefn.
> Therefore move the stub into libqemustub.a.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c                      | 5 +----
>  include/qemu-common.h       | 8 --------
>  include/qom/cpu.h           | 8 ++++++++
>  qom/cpu.c                   | 2 ++
>  stubs/cpus.c                | 4 ++++
>  target-alpha/cpu.c          | 3 ---
>  target-arm/cpu.c            | 1 -
>  target-cris/cpu.c           | 1 -
>  target-i386/cpu.c           | 1 -
>  target-lm32/cpu.c           | 2 --
>  target-m68k/cpu.c           | 1 -
>  target-microblaze/cpu.c     | 1 -
>  target-mips/cpu.c           | 1 -
>  target-moxie/cpu.c          | 5 ++---
>  target-openrisc/cpu.c       | 1 -
>  target-ppc/translate_init.c | 2 --
>  target-s390x/cpu.c          | 1 -
>  target-sh4/cpu.c            | 1 -
>  target-sparc/cpu.c          | 3 ---
>  target-unicore32/cpu.c      | 3 ---
>  target-xtensa/cpu.c         | 3 ---
>  21 files changed, 17 insertions(+), 40 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 18/29] cpu: Turn cpu_unassigned_access() into a CPUState hook
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 18/29] cpu: Turn cpu_unassigned_access() into a CPUState hook Andreas Färber
@ 2013-06-17 20:34   ` Richard Henderson
  2013-06-21 10:31     ` Andreas Färber
  0 siblings, 1 reply; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:34 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> +        cpu = CPU(alpha_env_get_cpu(cpu_single_env));
> +        cs = CPU(alpha_env_get_cpu(cpu_single_env));
> +    CPUState *cpu_single_cpu = CPU(alpha_env_get_cpu(cpu_single_env));
> +        cs = CPU(alpha_env_get_cpu(cpu_single_env));

ENV_GET_CPU.

> +    cpu_class_set_do_unassigned_access(cc, alpha_cpu_unassigned_access);

Wouldn't it be better to arrange for the function to exist always, with
differing implementation for user and system, much like do_interrupt?

What you've got is good enough for now, I suppose.


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu Andreas Färber
  2013-06-16 20:49   ` Blue Swirl
@ 2013-06-17 20:40   ` Richard Henderson
  2013-06-21 10:32     ` Andreas Färber
  2013-07-15 14:56   ` Paolo Bonzini
  2 siblings, 1 reply; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:40 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Anthony Liguori, qemu-devel, Alexander Graf,
	Blue Swirl, Andreas Färber, Hervé Poussineau,
	Paul Brook, Scott Wood, mpc8544ds, Aurelien Jarno

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
> index 207dcad..f0b1f6f 100644
> --- a/hw/alpha/typhoon.c
> +++ b/hw/alpha/typhoon.c
> @@ -72,9 +72,8 @@ static void cpu_irq_change(AlphaCPU *cpu, uint64_t req)
>  
>  static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
>  {
> -    CPUAlphaState *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>      TyphoonState *s = opaque;
> -    CPUState *cpu;
>      uint64_t ret = 0;
>  
>      if (addr & 4) {
> @@ -95,7 +94,6 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
>  
>      case 0x0080:
>          /* MISC: Miscellaneous Register.  */
> -        cpu = ENV_GET_CPU(env);
>          ret = s->cchip.misc | (cpu->cpu_index & 3);
>          break;
>  
> @@ -197,8 +195,7 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
>          break;
>  
>      default:
> -        cpu = CPU(alpha_env_get_cpu(cpu_single_env));
> -        cpu_unassigned_access(cpu, addr, false, false, 0, size);
> +        cpu_unassigned_access(cpu_single_cpu, addr, false, false, 0, size);

Keep using the local "cpu" variable?


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 20/29] kvm: Change kvm_remove_all_breakpoints() argument to CPUState
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
  (?)
  (?)
@ 2013-06-17 20:41   ` Richard Henderson
  -1 siblings, 0 replies; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:41 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  gdbstub.c            | 2 +-
>  include/sysemu/kvm.h | 2 +-
>  kvm-all.c            | 5 ++---
>  kvm-stub.c           | 2 +-
>  4 files changed, 5 insertions(+), 6 deletions(-)

Reviewed-by: Richard Henderson <rth@twiddle.net>


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 02/29] kvm: Change cpu_synchronize_state() argument to CPUState
  2013-06-17 19:46   ` Richard Henderson
@ 2013-06-17 20:58     ` Andreas Färber
  2013-06-17 21:02       ` Richard Henderson
  0 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-17 20:58 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

Am 17.06.2013 21:46, schrieb Richard Henderson:
> On 06/16/2013 08:57 AM, Andreas Färber wrote:
>> @@ -627,7 +627,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
>>      hwaddr rom_paddr;
>>      VAPICROMState *s = opaque;
>>  
>> -    cpu_synchronize_state(env);
>> +    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
> 
> ENV_GET_CPU, surely.

No, ENV_GET_CPU() is only a compatibility macro for generic code and
shouldn't be used in target-specific code.

Background is that foo_env_get_cpu() can coexist with bar_env_get_cpu()
whereas ENV_GET_CPU() relies on there being only one arch per
executable, which we hope to fix for heterogeneous emulations.

Andreas

>> @@ -66,7 +66,7 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
>>      unsigned char command;
>>      uint32_t eax;
>>  
>> -    cpu_synchronize_state(env);
>> +    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
> 
> Likewise.
> 
>> @@ -78,7 +78,7 @@ void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
>>      int i;
>>      uint64_t slbe, slbv;
>>  
>> -    cpu_synchronize_state(env);
>> +    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
> 
> Likewise.
> 
>> @@ -9534,7 +9534,7 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
>>  
>>      int i;
>>  
>> -    cpu_synchronize_state(env);
>> +    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
> 
> Likewise.
> 
> 
> 
> r~
> 


-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 25/29] cpu: Move CPU_INTERRUPT_* to qom/cpu.h
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 25/29] cpu: Move CPU_INTERRUPT_* to qom/cpu.h Andreas Färber
@ 2013-06-17 20:59   ` Richard Henderson
  2013-06-17 21:13     ` Andreas Färber
  0 siblings, 1 reply; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 20:59 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> +enum CPUInterruptFlags {
> +    CPU_INTERRUPT_HARD      = 0x0002,
> +    CPU_INTERRUPT_EXITTB    = 0x0004,
> +    CPU_INTERRUPT_HALT      = 0x0020,
> +    CPU_INTERRUPT_DEBUG     = 0x0080,
> +
> +#if defined(CONFIG_SOFTMMU) || defined(CONFIG_USER_ONLY)
> +    /* Several target-specific external hardware interrupts.
> +     * Each target/cpu.h should define proper names based on them.
> +     */
> +    CPU_INTERRUPT_TGT_EXT_0 = 0x0008,
> +    CPU_INTERRUPT_TGT_EXT_1 = 0x0010,
> +    CPU_INTERRUPT_TGT_EXT_2 = 0x0040,
> +    CPU_INTERRUPT_TGT_EXT_3 = 0x0200,
> +    CPU_INTERRUPT_TGT_EXT_4 = 0x1000,

I don't like this.  It's a subtle point between C and C++ that the later can
change the implementation type of the enum based on the contents of the enum.
While we don't currently ever build with C++, I'd rather not have something
like this hiding.

Is the ifdef really better than the poison?


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 04/29] cpu: Change cpu_exit() argument to CPUState
  2013-06-17 19:59   ` Richard Henderson
@ 2013-06-17 21:00     ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-17 21:00 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

Am 17.06.2013 21:59, schrieb Richard Henderson:
> On 06/16/2013 08:57 AM, Andreas Färber wrote:
[...]
>> @@ -420,7 +420,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
>>      CPUPPCState *env = cpu_single_env;
>>  
>>      if (env && level) {
>> -        cpu_exit(env);
>> +        cpu_exit(CPU(ppc_env_get_cpu(env)));
> 
> ENV_GET_CPU, 5 instances.

Explained in 02/29. :)

Andreas


-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 02/29] kvm: Change cpu_synchronize_state() argument to CPUState
  2013-06-17 20:58     ` Andreas Färber
@ 2013-06-17 21:02       ` Richard Henderson
  2013-06-17 21:09         ` Andreas Färber
  0 siblings, 1 reply; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 21:02 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/17/2013 01:58 PM, Andreas Färber wrote:
> Am 17.06.2013 21:46, schrieb Richard Henderson:
>> On 06/16/2013 08:57 AM, Andreas Färber wrote:
>>> @@ -627,7 +627,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
>>>      hwaddr rom_paddr;
>>>      VAPICROMState *s = opaque;
>>>  
>>> -    cpu_synchronize_state(env);
>>> +    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
>>
>> ENV_GET_CPU, surely.
> 
> No, ENV_GET_CPU() is only a compatibility macro for generic code and
> shouldn't be used in target-specific code.
> 
> Background is that foo_env_get_cpu() can coexist with bar_env_get_cpu()
> whereas ENV_GET_CPU() relies on there being only one arch per
> executable, which we hope to fix for heterogeneous emulations.

What has that got to do with anything?  ENV_GET_CPU is a macro, and only
applies within the current translation unit.  This corresponds well with the
CPUArchState type, which is also local to the current translation unit.


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 26/29] intc/sh_intc: Build sh_intc only once
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 26/29] intc/sh_intc: Build sh_intc only once Andreas Färber
@ 2013-06-17 21:08   ` Richard Henderson
  2013-06-17 21:17     ` Andreas Färber
  0 siblings, 1 reply; 98+ messages in thread
From: Richard Henderson @ 2013-06-17 21:08 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On 06/16/2013 08:57 AM, Andreas Färber wrote:
> Since converting first_cpu to CPUState and making CPU_INTERRUPT_HARD
> available through qom/cpu.h, it no longer depends on CPUSH4State.

Re 25/, how is CPU_INTERRUPT_HARD any less target dependent than
CPU_INTERRUPT_TGT_EXT_0?  Both require knowledge of how the system delivers
interrupts.


r~

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 02/29] kvm: Change cpu_synchronize_state() argument to CPUState
  2013-06-17 21:02       ` Richard Henderson
@ 2013-06-17 21:09         ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-17 21:09 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

Am 17.06.2013 23:02, schrieb Richard Henderson:
> On 06/17/2013 01:58 PM, Andreas Färber wrote:
>> Am 17.06.2013 21:46, schrieb Richard Henderson:
>>> On 06/16/2013 08:57 AM, Andreas Färber wrote:
>>>> @@ -627,7 +627,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
>>>>      hwaddr rom_paddr;
>>>>      VAPICROMState *s = opaque;
>>>>  
>>>> -    cpu_synchronize_state(env);
>>>> +    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
>>>
>>> ENV_GET_CPU, surely.
>>
>> No, ENV_GET_CPU() is only a compatibility macro for generic code and
>> shouldn't be used in target-specific code.
>>
>> Background is that foo_env_get_cpu() can coexist with bar_env_get_cpu()
>> whereas ENV_GET_CPU() relies on there being only one arch per
>> executable, which we hope to fix for heterogeneous emulations.
> 
> What has that got to do with anything?  ENV_GET_CPU is a macro, and only
> applies within the current translation unit.  This corresponds well with the
> CPUArchState type, which is also local to the current translation unit.

The whole point of my refactorings is to drop the CPUArchState define
completely. Generic code should use CPUState instead, and CPU*State
becomes an implementation detail of the specific target. Therefore
ENV_GET_CPU() will no longer be needed either at some point, so I don't
want to introduce usages now just to save a few characters and later
have to convert them back in one big go.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 25/29] cpu: Move CPU_INTERRUPT_* to qom/cpu.h
  2013-06-17 20:59   ` Richard Henderson
@ 2013-06-17 21:13     ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-17 21:13 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

Am 17.06.2013 22:59, schrieb Richard Henderson:
> On 06/16/2013 08:57 AM, Andreas Färber wrote:
>> +enum CPUInterruptFlags {
>> +    CPU_INTERRUPT_HARD      = 0x0002,
>> +    CPU_INTERRUPT_EXITTB    = 0x0004,
>> +    CPU_INTERRUPT_HALT      = 0x0020,
>> +    CPU_INTERRUPT_DEBUG     = 0x0080,
>> +
>> +#if defined(CONFIG_SOFTMMU) || defined(CONFIG_USER_ONLY)
>> +    /* Several target-specific external hardware interrupts.
>> +     * Each target/cpu.h should define proper names based on them.
>> +     */
>> +    CPU_INTERRUPT_TGT_EXT_0 = 0x0008,
>> +    CPU_INTERRUPT_TGT_EXT_1 = 0x0010,
>> +    CPU_INTERRUPT_TGT_EXT_2 = 0x0040,
>> +    CPU_INTERRUPT_TGT_EXT_3 = 0x0200,
>> +    CPU_INTERRUPT_TGT_EXT_4 = 0x1000,
> 
> I don't like this.  It's a subtle point between C and C++ that the later can
> change the implementation type of the enum based on the contents of the enum.
> While we don't currently ever build with C++, I'd rather not have something
> like this hiding.
> 
> Is the ifdef really better than the poison?

With today's poison we can't use it in qom/cpu.c nor intc/sh_intc.c.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 26/29] intc/sh_intc: Build sh_intc only once
  2013-06-17 21:08   ` Richard Henderson
@ 2013-06-17 21:17     ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-17 21:17 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

Am 17.06.2013 23:08, schrieb Richard Henderson:
> On 06/16/2013 08:57 AM, Andreas Färber wrote:
>> Since converting first_cpu to CPUState and making CPU_INTERRUPT_HARD
>> available through qom/cpu.h, it no longer depends on CPUSH4State.
> 
> Re 25/, how is CPU_INTERRUPT_HARD any less target dependent than
> CPU_INTERRUPT_TGT_EXT_0?  Both require knowledge of how the system delivers
> interrupts.

CPU_INTERRUPT_HARD is semantically well-defined for all targets, whereas
CPU_INTERRUPT_TGT_{INT,EXT}_* can mean pretty much anything.

That said, I don't insist on this patch. It compiles the file one time
less than without but still rebuilds whenever I change qom/cpu.h.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH qom-cpu v2 02/29] kvm: Change cpu_synchronize_state() argument to CPUState
  2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
@ 2013-06-18  9:39     ` Igor Mammedov
  -1 siblings, 0 replies; 98+ messages in thread
From: Igor Mammedov @ 2013-06-18  9:39 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Alexander Graf, open list:X86, Gleb Natapov, Marcelo Tosatti,
	qemu-devel, Luiz Capitulino, open list:PowerPC,
	Richard Henderson

On Sun, 16 Jun 2013 17:57:22 +0200
Andreas Färber <afaerber@suse.de> wrote:

> Change Monitor::mon_cpu to CPUState as well.
> In cpu_synchronize_all_states() use qemu_for_each_cpu() now.
> 
> Reviewed-by: liguang <lig.fnst@cn.fujitsu.com>
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c                  | 8 ++++----
>  gdbstub.c               | 8 ++++----
>  hw/i386/kvm/apic.c      | 2 +-
>  hw/i386/kvmvapic.c      | 4 ++--
>  hw/misc/vmport.c        | 2 +-
>  hw/ppc/ppce500_spin.c   | 2 +-
>  include/sysemu/kvm.h    | 4 ++--
>  monitor.c               | 6 +++---
>  target-i386/helper.c    | 4 ++--
>  target-i386/kvm.c       | 2 +-
>  target-ppc/mmu-hash64.c | 2 +-
>  target-ppc/translate.c  | 2 +-
>  target-s390x/kvm.c      | 9 +++++----
>  13 files changed, 28 insertions(+), 27 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index c232265..3260f09 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -407,10 +407,10 @@ void hw_error(const char *fmt, ...)
>  
>  void cpu_synchronize_all_states(void)
>  {
> -    CPUArchState *cpu;
> +    CPUArchState *env;
>  
> -    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
> -        cpu_synchronize_state(cpu);
> +    for (env = first_cpu; env; env = env->next_cpu) {
> +        cpu_synchronize_state(ENV_GET_CPU(env));
>      }
>  }
>  
> @@ -1219,7 +1219,7 @@ CpuInfoList *qmp_query_cpus(Error **errp)
>          CPUState *cpu = ENV_GET_CPU(env);
>          CpuInfoList *info;
>  
> -        cpu_synchronize_state(env);
> +        cpu_synchronize_state(cpu);
>  
>          info = g_malloc0(sizeof(*info));
>          info->value = g_malloc0(sizeof(*info->value));
> diff --git a/gdbstub.c b/gdbstub.c
> index 94c78ce..bbae06d 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -2033,7 +2033,7 @@ static void gdb_breakpoint_remove_all(void)
>  
>  static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
>  {
> -    cpu_synchronize_state(s->c_cpu);
> +    cpu_synchronize_state(ENV_GET_CPU(s->c_cpu));
>  #if defined(TARGET_I386)
>      s->c_cpu->eip = pc;
>  #elif defined (TARGET_PPC)
> @@ -2232,7 +2232,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
>          }
>          break;
>      case 'g':
> -        cpu_synchronize_state(s->g_cpu);
> +        cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
>          env = s->g_cpu;
>          len = 0;
>          for (addr = 0; addr < num_g_regs; addr++) {
> @@ -2243,7 +2243,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
>          put_packet(s, buf);
>          break;
>      case 'G':
> -        cpu_synchronize_state(s->g_cpu);
> +        cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
>          env = s->g_cpu;
>          registers = mem_buf;
>          len = strlen(p) / 2;
> @@ -2411,7 +2411,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
>              env = find_cpu(thread);
>              if (env != NULL) {
>                  CPUState *cpu = ENV_GET_CPU(env);
> -                cpu_synchronize_state(env);
> +                cpu_synchronize_state(cpu);
>                  len = snprintf((char *)mem_buf, sizeof(mem_buf),
>                                 "CPU#%d [%s]", cpu->cpu_index,
>                                 cpu->halted ? "halted " : "running");
> diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
> index 8f80425..bd0bdd8 100644
> --- a/hw/i386/kvm/apic.c
> +++ b/hw/i386/kvm/apic.c
> @@ -129,7 +129,7 @@ static void do_inject_external_nmi(void *data)
>      uint32_t lvt;
>      int ret;
>  
> -    cpu_synchronize_state(&s->cpu->env);
> +    cpu_synchronize_state(cpu);
>  
>      lvt = s->lvt[APIC_LVT_LINT1];
>      if (!(lvt & APIC_LVT_MASKED) && ((lvt >> 8) & 7) == APIC_DM_NMI) {
> diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
> index 655483b..f93629f 100644
> --- a/hw/i386/kvmvapic.c
> +++ b/hw/i386/kvmvapic.c
> @@ -456,7 +456,7 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
>      X86CPU *cpu = X86_CPU(cs);
>      CPUX86State *env = &cpu->env;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(cs);
>  
>      if (evaluate_tpr_instruction(s, env, &ip, access) < 0) {
>          if (s->state == VAPIC_ACTIVE) {
> @@ -627,7 +627,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
>      hwaddr rom_paddr;
>      VAPICROMState *s = opaque;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
why not use ENV_GET_CPU() here and in several other places below to make it
uniform?

>  
>      /*
>       * The VAPIC supports two PIO-based hypercalls, both via port 0x7E.
> diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c
> index 57b71f5..8363dfd 100644
> --- a/hw/misc/vmport.c
> +++ b/hw/misc/vmport.c
> @@ -66,7 +66,7 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
>      unsigned char command;
>      uint32_t eax;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
>  
>      eax = env->regs[R_EAX];
>      if (eax != VMPORT_MAGIC)
> diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c
> index 1290d37..ea65414 100644
> --- a/hw/ppc/ppce500_spin.c
> +++ b/hw/ppc/ppce500_spin.c
> @@ -98,7 +98,7 @@ static void spin_kick(void *data)
>      hwaddr map_size = 64 * 1024 * 1024;
>      hwaddr map_start;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(cpu);
>      stl_p(&curspin->pir, env->spr[SPR_PIR]);
>      env->nip = ldq_p(&curspin->addr) & (map_size - 1);
>      env->gpr[3] = ldq_p(&curspin->r3);
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index 3e1db28..06da2b3 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -263,10 +263,10 @@ void kvm_cpu_synchronize_state(CPUState *cpu);
>  
>  /* generic hooks - to be moved/refactored once there are more users */
>  
> -static inline void cpu_synchronize_state(CPUArchState *env)
> +static inline void cpu_synchronize_state(CPUState *cpu)
>  {
>      if (kvm_enabled()) {
> -        kvm_cpu_synchronize_state(ENV_GET_CPU(env));
> +        kvm_cpu_synchronize_state(cpu);
>      }
>  }
>  
> diff --git a/monitor.c b/monitor.c
> index 70ae8f5..19c297d 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -191,7 +191,7 @@ struct Monitor {
>      QString *outbuf;
>      ReadLineState *rs;
>      MonitorControl *mc;
> -    CPUArchState *mon_cpu;
> +    CPUState *mon_cpu;
>      BlockDriverCompletionFunc *password_completion_cb;
>      void *password_opaque;
>      QError *error;
> @@ -900,7 +900,7 @@ int monitor_set_cpu(int cpu_index)
>      if (cpu == NULL) {
>          return -1;
>      }
> -    cur_mon->mon_cpu = cpu->env_ptr;
> +    cur_mon->mon_cpu = cpu;
>      return 0;
>  }
>  
> @@ -910,7 +910,7 @@ static CPUArchState *mon_get_cpu(void)
>          monitor_set_cpu(0);
>      }
>      cpu_synchronize_state(cur_mon->mon_cpu);
> -    return cur_mon->mon_cpu;
> +    return cur_mon->mon_cpu->env_ptr;
>  }
>  
>  int monitor_get_cpu_index(void)
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 158710a..803945d 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -187,7 +187,7 @@ void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
>      char cc_op_name[32];
>      static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(cs);
>  
>      eflags = cpu_compute_eflags(env);
>  #ifdef TARGET_X86_64
> @@ -1116,7 +1116,7 @@ static void do_inject_x86_mce(void *data)
>      CPUState *cpu = CPU(params->cpu);
>      uint64_t *banks = cenv->mce_banks + 4 * params->bank;
>  
> -    cpu_synchronize_state(cenv);
> +    cpu_synchronize_state(cpu);
>  
>      /*
>       * If there is an MCE exception being processed, ignore this SRAO MCE
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 0b0adfd..39f4fbb 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -2079,7 +2079,7 @@ static int kvm_handle_debug(X86CPU *cpu,
>          ret = EXCP_DEBUG;
>      }
>      if (ret == 0) {
> -        cpu_synchronize_state(env);
> +        cpu_synchronize_state(CPU(cpu));
>          assert(env->exception_injected == -1);
>  
>          /* pass to guest */
> diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
> index 43ccf45..5c67ec3 100644
> --- a/target-ppc/mmu-hash64.c
> +++ b/target-ppc/mmu-hash64.c
> @@ -78,7 +78,7 @@ void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
>      int i;
>      uint64_t slbe, slbv;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
>  
>      cpu_fprintf(f, "SLB\tESID\t\t\tVSID\n");
>      for (i = 0; i < env->slb_nr; i++) {
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index 4590c6f..076cdac 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -9534,7 +9534,7 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
>  
>      int i;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
>  
>      cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
>                  TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
> diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
> index 4d9ac4a..e7b3049 100644
> --- a/target-s390x/kvm.c
> +++ b/target-s390x/kvm.c
> @@ -450,7 +450,7 @@ static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
>      uint64_t code;
>      int r = 0;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(cpu));
>      sccb = env->regs[ipbh0 & 0xf];
>      code = env->regs[(ipbh0 & 0xf0) >> 4];
>  
> @@ -656,16 +656,17 @@ static int s390_store_status(CPUS390XState *env, uint32_t parameter)
>  
>  static int s390_cpu_initial_reset(S390CPU *cpu)
>  {
> +    CPUState *cs = CPU(cpu);
>      CPUS390XState *env = &cpu->env;
>      int i;
>  
>      s390_del_running_cpu(cpu);
> -    if (kvm_vcpu_ioctl(CPU(cpu), KVM_S390_INITIAL_RESET, NULL) < 0) {
> +    if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL) < 0) {
>          perror("cannot init reset vcpu");
>      }
>  
>      /* Manually zero out all registers */
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(cs);
>      for (i = 0; i < 16; i++) {
>          env->regs[i] = 0;
>      }
> @@ -685,7 +686,7 @@ static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
>      S390CPU *target_cpu;
>      CPUS390XState *target_env;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(cpu));
>  
>      /* get order code */
>      order_code = run->s390_sieic.ipb >> 28;
> -- 
> 1.8.1.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


-- 
Regards,
  Igor

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 02/29] kvm: Change cpu_synchronize_state() argument to CPUState
@ 2013-06-18  9:39     ` Igor Mammedov
  0 siblings, 0 replies; 98+ messages in thread
From: Igor Mammedov @ 2013-06-18  9:39 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Alexander Graf, open list:X86, Gleb Natapov, Marcelo Tosatti,
	qemu-devel, Luiz Capitulino, open list:PowerPC,
	Richard Henderson

On Sun, 16 Jun 2013 17:57:22 +0200
Andreas Färber <afaerber@suse.de> wrote:

> Change Monitor::mon_cpu to CPUState as well.
> In cpu_synchronize_all_states() use qemu_for_each_cpu() now.
> 
> Reviewed-by: liguang <lig.fnst@cn.fujitsu.com>
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c                  | 8 ++++----
>  gdbstub.c               | 8 ++++----
>  hw/i386/kvm/apic.c      | 2 +-
>  hw/i386/kvmvapic.c      | 4 ++--
>  hw/misc/vmport.c        | 2 +-
>  hw/ppc/ppce500_spin.c   | 2 +-
>  include/sysemu/kvm.h    | 4 ++--
>  monitor.c               | 6 +++---
>  target-i386/helper.c    | 4 ++--
>  target-i386/kvm.c       | 2 +-
>  target-ppc/mmu-hash64.c | 2 +-
>  target-ppc/translate.c  | 2 +-
>  target-s390x/kvm.c      | 9 +++++----
>  13 files changed, 28 insertions(+), 27 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index c232265..3260f09 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -407,10 +407,10 @@ void hw_error(const char *fmt, ...)
>  
>  void cpu_synchronize_all_states(void)
>  {
> -    CPUArchState *cpu;
> +    CPUArchState *env;
>  
> -    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
> -        cpu_synchronize_state(cpu);
> +    for (env = first_cpu; env; env = env->next_cpu) {
> +        cpu_synchronize_state(ENV_GET_CPU(env));
>      }
>  }
>  
> @@ -1219,7 +1219,7 @@ CpuInfoList *qmp_query_cpus(Error **errp)
>          CPUState *cpu = ENV_GET_CPU(env);
>          CpuInfoList *info;
>  
> -        cpu_synchronize_state(env);
> +        cpu_synchronize_state(cpu);
>  
>          info = g_malloc0(sizeof(*info));
>          info->value = g_malloc0(sizeof(*info->value));
> diff --git a/gdbstub.c b/gdbstub.c
> index 94c78ce..bbae06d 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -2033,7 +2033,7 @@ static void gdb_breakpoint_remove_all(void)
>  
>  static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
>  {
> -    cpu_synchronize_state(s->c_cpu);
> +    cpu_synchronize_state(ENV_GET_CPU(s->c_cpu));
>  #if defined(TARGET_I386)
>      s->c_cpu->eip = pc;
>  #elif defined (TARGET_PPC)
> @@ -2232,7 +2232,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
>          }
>          break;
>      case 'g':
> -        cpu_synchronize_state(s->g_cpu);
> +        cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
>          env = s->g_cpu;
>          len = 0;
>          for (addr = 0; addr < num_g_regs; addr++) {
> @@ -2243,7 +2243,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
>          put_packet(s, buf);
>          break;
>      case 'G':
> -        cpu_synchronize_state(s->g_cpu);
> +        cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
>          env = s->g_cpu;
>          registers = mem_buf;
>          len = strlen(p) / 2;
> @@ -2411,7 +2411,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
>              env = find_cpu(thread);
>              if (env != NULL) {
>                  CPUState *cpu = ENV_GET_CPU(env);
> -                cpu_synchronize_state(env);
> +                cpu_synchronize_state(cpu);
>                  len = snprintf((char *)mem_buf, sizeof(mem_buf),
>                                 "CPU#%d [%s]", cpu->cpu_index,
>                                 cpu->halted ? "halted " : "running");
> diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
> index 8f80425..bd0bdd8 100644
> --- a/hw/i386/kvm/apic.c
> +++ b/hw/i386/kvm/apic.c
> @@ -129,7 +129,7 @@ static void do_inject_external_nmi(void *data)
>      uint32_t lvt;
>      int ret;
>  
> -    cpu_synchronize_state(&s->cpu->env);
> +    cpu_synchronize_state(cpu);
>  
>      lvt = s->lvt[APIC_LVT_LINT1];
>      if (!(lvt & APIC_LVT_MASKED) && ((lvt >> 8) & 7) == APIC_DM_NMI) {
> diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
> index 655483b..f93629f 100644
> --- a/hw/i386/kvmvapic.c
> +++ b/hw/i386/kvmvapic.c
> @@ -456,7 +456,7 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
>      X86CPU *cpu = X86_CPU(cs);
>      CPUX86State *env = &cpu->env;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(cs);
>  
>      if (evaluate_tpr_instruction(s, env, &ip, access) < 0) {
>          if (s->state == VAPIC_ACTIVE) {
> @@ -627,7 +627,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
>      hwaddr rom_paddr;
>      VAPICROMState *s = opaque;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
why not use ENV_GET_CPU() here and in several other places below to make it
uniform?

>  
>      /*
>       * The VAPIC supports two PIO-based hypercalls, both via port 0x7E.
> diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c
> index 57b71f5..8363dfd 100644
> --- a/hw/misc/vmport.c
> +++ b/hw/misc/vmport.c
> @@ -66,7 +66,7 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
>      unsigned char command;
>      uint32_t eax;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
>  
>      eax = env->regs[R_EAX];
>      if (eax != VMPORT_MAGIC)
> diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c
> index 1290d37..ea65414 100644
> --- a/hw/ppc/ppce500_spin.c
> +++ b/hw/ppc/ppce500_spin.c
> @@ -98,7 +98,7 @@ static void spin_kick(void *data)
>      hwaddr map_size = 64 * 1024 * 1024;
>      hwaddr map_start;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(cpu);
>      stl_p(&curspin->pir, env->spr[SPR_PIR]);
>      env->nip = ldq_p(&curspin->addr) & (map_size - 1);
>      env->gpr[3] = ldq_p(&curspin->r3);
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index 3e1db28..06da2b3 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -263,10 +263,10 @@ void kvm_cpu_synchronize_state(CPUState *cpu);
>  
>  /* generic hooks - to be moved/refactored once there are more users */
>  
> -static inline void cpu_synchronize_state(CPUArchState *env)
> +static inline void cpu_synchronize_state(CPUState *cpu)
>  {
>      if (kvm_enabled()) {
> -        kvm_cpu_synchronize_state(ENV_GET_CPU(env));
> +        kvm_cpu_synchronize_state(cpu);
>      }
>  }
>  
> diff --git a/monitor.c b/monitor.c
> index 70ae8f5..19c297d 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -191,7 +191,7 @@ struct Monitor {
>      QString *outbuf;
>      ReadLineState *rs;
>      MonitorControl *mc;
> -    CPUArchState *mon_cpu;
> +    CPUState *mon_cpu;
>      BlockDriverCompletionFunc *password_completion_cb;
>      void *password_opaque;
>      QError *error;
> @@ -900,7 +900,7 @@ int monitor_set_cpu(int cpu_index)
>      if (cpu == NULL) {
>          return -1;
>      }
> -    cur_mon->mon_cpu = cpu->env_ptr;
> +    cur_mon->mon_cpu = cpu;
>      return 0;
>  }
>  
> @@ -910,7 +910,7 @@ static CPUArchState *mon_get_cpu(void)
>          monitor_set_cpu(0);
>      }
>      cpu_synchronize_state(cur_mon->mon_cpu);
> -    return cur_mon->mon_cpu;
> +    return cur_mon->mon_cpu->env_ptr;
>  }
>  
>  int monitor_get_cpu_index(void)
> diff --git a/target-i386/helper.c b/target-i386/helper.c
> index 158710a..803945d 100644
> --- a/target-i386/helper.c
> +++ b/target-i386/helper.c
> @@ -187,7 +187,7 @@ void cpu_dump_state(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
>      char cc_op_name[32];
>      static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(cs);
>  
>      eflags = cpu_compute_eflags(env);
>  #ifdef TARGET_X86_64
> @@ -1116,7 +1116,7 @@ static void do_inject_x86_mce(void *data)
>      CPUState *cpu = CPU(params->cpu);
>      uint64_t *banks = cenv->mce_banks + 4 * params->bank;
>  
> -    cpu_synchronize_state(cenv);
> +    cpu_synchronize_state(cpu);
>  
>      /*
>       * If there is an MCE exception being processed, ignore this SRAO MCE
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 0b0adfd..39f4fbb 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -2079,7 +2079,7 @@ static int kvm_handle_debug(X86CPU *cpu,
>          ret = EXCP_DEBUG;
>      }
>      if (ret == 0) {
> -        cpu_synchronize_state(env);
> +        cpu_synchronize_state(CPU(cpu));
>          assert(env->exception_injected == -1);
>  
>          /* pass to guest */
> diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
> index 43ccf45..5c67ec3 100644
> --- a/target-ppc/mmu-hash64.c
> +++ b/target-ppc/mmu-hash64.c
> @@ -78,7 +78,7 @@ void dump_slb(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
>      int i;
>      uint64_t slbe, slbv;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
>  
>      cpu_fprintf(f, "SLB\tESID\t\t\tVSID\n");
>      for (i = 0; i < env->slb_nr; i++) {
> diff --git a/target-ppc/translate.c b/target-ppc/translate.c
> index 4590c6f..076cdac 100644
> --- a/target-ppc/translate.c
> +++ b/target-ppc/translate.c
> @@ -9534,7 +9534,7 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
>  
>      int i;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(ppc_env_get_cpu(env)));
>  
>      cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
>                  TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
> diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
> index 4d9ac4a..e7b3049 100644
> --- a/target-s390x/kvm.c
> +++ b/target-s390x/kvm.c
> @@ -450,7 +450,7 @@ static int kvm_sclp_service_call(S390CPU *cpu, struct kvm_run *run,
>      uint64_t code;
>      int r = 0;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(cpu));
>      sccb = env->regs[ipbh0 & 0xf];
>      code = env->regs[(ipbh0 & 0xf0) >> 4];
>  
> @@ -656,16 +656,17 @@ static int s390_store_status(CPUS390XState *env, uint32_t parameter)
>  
>  static int s390_cpu_initial_reset(S390CPU *cpu)
>  {
> +    CPUState *cs = CPU(cpu);
>      CPUS390XState *env = &cpu->env;
>      int i;
>  
>      s390_del_running_cpu(cpu);
> -    if (kvm_vcpu_ioctl(CPU(cpu), KVM_S390_INITIAL_RESET, NULL) < 0) {
> +    if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL) < 0) {
>          perror("cannot init reset vcpu");
>      }
>  
>      /* Manually zero out all registers */
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(cs);
>      for (i = 0; i < 16; i++) {
>          env->regs[i] = 0;
>      }
> @@ -685,7 +686,7 @@ static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
>      S390CPU *target_cpu;
>      CPUS390XState *target_env;
>  
> -    cpu_synchronize_state(env);
> +    cpu_synchronize_state(CPU(cpu));
>  
>      /* get order code */
>      order_code = run->s390_sieic.ipb >> 28;
> -- 
> 1.8.1.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


-- 
Regards,
  Igor

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH qom-cpu v2 01/29] kvm: Change kvm_cpu_synchronize_state() argument to CPUState
       [not found]   ` <51BF360E.8090402@redhat.com>
@ 2013-06-18 16:36       ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-18 16:36 UTC (permalink / raw)
  To: Paolo Bonzini, Richard Henderson
  Cc: qemu-devel, kvm, Gleb Natapov, Marcelo Tosatti, Alexander Graf,
	qemu-ppc, David Gibson

Am 17.06.2013 18:15, schrieb Paolo Bonzini:
> Il 16/06/2013 17:57, Andreas Färber ha scritto:
>> It no longer relies on CPUArchState since 20d695a.
>>
>> Reviewed-by: liguang <lig.fnst@cn.fujitsu.com>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>> ---
>>  hw/ppc/spapr_rtas.c  |  2 +-
>>  include/sysemu/kvm.h |  4 ++--
>>  kvm-all.c            |  4 +---
>>  kvm-stub.c           |  2 +-
>>  target-i386/kvm.c    | 10 +++++-----
>>  5 files changed, 10 insertions(+), 12 deletions(-)
[...]
> 
> Acked-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks, applied to qom-cpu:
https://github.com/afaerber/qemu-cpu/commits/qom-cpu

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 01/29] kvm: Change kvm_cpu_synchronize_state() argument to CPUState
@ 2013-06-18 16:36       ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-18 16:36 UTC (permalink / raw)
  To: Paolo Bonzini, Richard Henderson
  Cc: kvm, Gleb Natapov, Marcelo Tosatti, qemu-devel, Alexander Graf,
	qemu-ppc, David Gibson

Am 17.06.2013 18:15, schrieb Paolo Bonzini:
> Il 16/06/2013 17:57, Andreas Färber ha scritto:
>> It no longer relies on CPUArchState since 20d695a.
>>
>> Reviewed-by: liguang <lig.fnst@cn.fujitsu.com>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>> ---
>>  hw/ppc/spapr_rtas.c  |  2 +-
>>  include/sysemu/kvm.h |  4 ++--
>>  kvm-all.c            |  4 +---
>>  kvm-stub.c           |  2 +-
>>  target-i386/kvm.c    | 10 +++++-----
>>  5 files changed, 10 insertions(+), 12 deletions(-)
[...]
> 
> Acked-by: Paolo Bonzini <pbonzini@redhat.com>

Thanks, applied to qom-cpu:
https://github.com/afaerber/qemu-cpu/commits/qom-cpu

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu
  2013-06-16 20:49   ` Blue Swirl
@ 2013-06-18 16:52     ` Andreas Färber
  2013-06-19 12:59       ` Paolo Bonzini
  0 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-06-18 16:52 UTC (permalink / raw)
  To: Blue Swirl, Paolo Bonzini
  Cc: Peter Maydell, Anthony Liguori, qemu-devel, Alexander Graf,
	Hervé Poussineau, Paul Brook, Scott Wood, qemu-ppc,
	Aurelien Jarno, Richard Henderson

Am 16.06.2013 22:49, schrieb Blue Swirl:
> On Sun, Jun 16, 2013 at 3:57 PM, Andreas Färber <afaerber@suse.de> wrote:
>> Move it to qom/cpu.h.
> 
> While renaming, perhaps a more descriptive name could be used instead
> of 'cpu_single_cpu', something like cpu_loop_current_cpu?

There were some local variables named cpu_single_cpu (blame me :)) that
this way simply fall away, but I can certainly rename it, adding just a
few lines to the patch.

However, cpu_loop_current_cpu seems to codify that we have a sequential
loop of vCPUs, which Xen and IIUC KVM do not have and occasionally
people have looked into changing for TCG.

current_cpu is already used in a few places:

include/sysemu/kvm.h:int kvm_arch_insert_sw_breakpoint(CPUState
*current_cpu,
include/sysemu/kvm.h:int kvm_arch_remove_sw_breakpoint(CPUState
*current_cpu,
kvm-all.c:    CPUState *current_cpu = ENV_GET_CPU(current_env);
kvm-all.c:        bp = kvm_find_sw_breakpoint(current_cpu, addr);
kvm-all.c:        err = kvm_arch_insert_sw_breakpoint(current_cpu, bp);
kvm-all.c:
QTAILQ_INSERT_HEAD(&current_cpu->kvm_state->kvm_sw_breakpoints,
kvm-all.c:    CPUState *current_cpu = ENV_GET_CPU(current_env);
kvm-all.c:        bp = kvm_find_sw_breakpoint(current_cpu, addr);
kvm-all.c:        err = kvm_arch_remove_sw_breakpoint(current_cpu, bp);
kvm-all.c:
QTAILQ_REMOVE(&current_cpu->kvm_state->kvm_sw_breakpoints, bp, entry);
kvm-all.c:    CPUState *current_cpu = ENV_GET_CPU(current_env);
kvm-all.c:    KVMState *s = current_cpu->kvm_state;
kvm-all.c:        if (kvm_arch_remove_sw_breakpoint(current_cpu, bp) != 0) {

but we could probably ignore these variable shadowings.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu
  2013-06-18 16:52     ` Andreas Färber
@ 2013-06-19 12:59       ` Paolo Bonzini
  0 siblings, 0 replies; 98+ messages in thread
From: Paolo Bonzini @ 2013-06-19 12:59 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Anthony Liguori, qemu-devel, Alexander Graf,
	Blue Swirl, Hervé Poussineau, Paul Brook, Scott Wood,
	qemu-ppc, Aurelien Jarno, Richard Henderson

Il 18/06/2013 18:52, Andreas Färber ha scritto:
> Am 16.06.2013 22:49, schrieb Blue Swirl:
>> On Sun, Jun 16, 2013 at 3:57 PM, Andreas Färber <afaerber@suse.de> wrote:
>>> Move it to qom/cpu.h.
>>
>> While renaming, perhaps a more descriptive name could be used instead
>> of 'cpu_single_cpu', something like cpu_loop_current_cpu?
> 
> There were some local variables named cpu_single_cpu (blame me :)) that
> this way simply fall away, but I can certainly rename it, adding just a
> few lines to the patch.
> 
> However, cpu_loop_current_cpu seems to codify that we have a sequential
> loop of vCPUs, which Xen and IIUC KVM do not have and occasionally
> people have looked into changing for TCG.
> 
> current_cpu is already used in a few places:
> 
> include/sysemu/kvm.h:int kvm_arch_insert_sw_breakpoint(CPUState
> *current_cpu,
> include/sysemu/kvm.h:int kvm_arch_remove_sw_breakpoint(CPUState
> *current_cpu,
> kvm-all.c:    CPUState *current_cpu = ENV_GET_CPU(current_env);
> kvm-all.c:        bp = kvm_find_sw_breakpoint(current_cpu, addr);
> kvm-all.c:        err = kvm_arch_insert_sw_breakpoint(current_cpu, bp);
> kvm-all.c:
> QTAILQ_INSERT_HEAD(&current_cpu->kvm_state->kvm_sw_breakpoints,
> kvm-all.c:    CPUState *current_cpu = ENV_GET_CPU(current_env);
> kvm-all.c:        bp = kvm_find_sw_breakpoint(current_cpu, addr);
> kvm-all.c:        err = kvm_arch_remove_sw_breakpoint(current_cpu, bp);
> kvm-all.c:
> QTAILQ_REMOVE(&current_cpu->kvm_state->kvm_sw_breakpoints, bp, entry);
> kvm-all.c:    CPUState *current_cpu = ENV_GET_CPU(current_env);
> kvm-all.c:    KVMState *s = current_cpu->kvm_state;
> kvm-all.c:        if (kvm_arch_remove_sw_breakpoint(current_cpu, bp) != 0) {
> 
> but we could probably ignore these variable shadowings.

Renaming those to just "cpu" and "env" is pre-acked.

Paolo

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 03/29] gdbstub: Simplify find_cpu()
  2013-06-17 19:54   ` Richard Henderson
@ 2013-06-19 17:30     ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-19 17:30 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

Am 17.06.2013 21:54, schrieb Richard Henderson:
> On 06/16/2013 08:57 AM, Andreas Färber wrote:
>> Use qemu_get_cpu() and CPUState::env_ptr.
>>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
> 
> Reviewed-by: Richard Henderson <rth@twiddle.net>

Thanks, applied to qom-cpu:
https://github.com/afaerber/qemu-cpu/commits/qom-cpu

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [PATCH qom-cpu v2 02/29] kvm: Change cpu_synchronize_state() argument to CPUState
  2013-06-18  9:39     ` [Qemu-devel] " Igor Mammedov
@ 2013-06-21 10:25       ` Andreas Färber
  -1 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-21 10:25 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: qemu-devel, Alexander Graf, Luiz Capitulino, Gleb Natapov,
	Marcelo Tosatti, Richard Henderson, qemu-ppc, kvm

Am 18.06.2013 11:39, schrieb Igor Mammedov:
> On Sun, 16 Jun 2013 17:57:22 +0200
> Andreas Färber <afaerber@suse.de> wrote:
> 
>> Change Monitor::mon_cpu to CPUState as well.
>> In cpu_synchronize_all_states() use qemu_for_each_cpu() now.
>>
>> Reviewed-by: liguang <lig.fnst@cn.fujitsu.com>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>> ---
[...]
>> diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
>> index 655483b..f93629f 100644
>> --- a/hw/i386/kvmvapic.c
>> +++ b/hw/i386/kvmvapic.c
>> @@ -456,7 +456,7 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
>>      X86CPU *cpu = X86_CPU(cs);
>>      CPUX86State *env = &cpu->env;
>>  
>> -    cpu_synchronize_state(env);
>> +    cpu_synchronize_state(cs);
>>  
>>      if (evaluate_tpr_instruction(s, env, &ip, access) < 0) {
>>          if (s->state == VAPIC_ACTIVE) {
>> @@ -627,7 +627,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
>>      hwaddr rom_paddr;
>>      VAPICROMState *s = opaque;
>>  
>> -    cpu_synchronize_state(env);
>> +    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
> why not use ENV_GET_CPU() here and in several other places below to make it
> uniform?

Explained that in another reply. There's currently about four misuses in
the tree, and there had been previous patches to clean some others up;
after the series only one remains in target-ppc/mmu-hash.c.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 02/29] kvm: Change cpu_synchronize_state() argument to CPUState
@ 2013-06-21 10:25       ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-21 10:25 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Alexander Graf, kvm, Gleb Natapov, Marcelo Tosatti, qemu-devel,
	Luiz Capitulino, qemu-ppc, Richard Henderson

Am 18.06.2013 11:39, schrieb Igor Mammedov:
> On Sun, 16 Jun 2013 17:57:22 +0200
> Andreas Färber <afaerber@suse.de> wrote:
> 
>> Change Monitor::mon_cpu to CPUState as well.
>> In cpu_synchronize_all_states() use qemu_for_each_cpu() now.
>>
>> Reviewed-by: liguang <lig.fnst@cn.fujitsu.com>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>> ---
[...]
>> diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
>> index 655483b..f93629f 100644
>> --- a/hw/i386/kvmvapic.c
>> +++ b/hw/i386/kvmvapic.c
>> @@ -456,7 +456,7 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
>>      X86CPU *cpu = X86_CPU(cs);
>>      CPUX86State *env = &cpu->env;
>>  
>> -    cpu_synchronize_state(env);
>> +    cpu_synchronize_state(cs);
>>  
>>      if (evaluate_tpr_instruction(s, env, &ip, access) < 0) {
>>          if (s->state == VAPIC_ACTIVE) {
>> @@ -627,7 +627,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
>>      hwaddr rom_paddr;
>>      VAPICROMState *s = opaque;
>>  
>> -    cpu_synchronize_state(env);
>> +    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
> why not use ENV_GET_CPU() here and in several other places below to make it
> uniform?

Explained that in another reply. There's currently about four misuses in
the tree, and there had been previous patches to clean some others up;
after the series only one remains in target-ppc/mmu-hash.c.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 18/29] cpu: Turn cpu_unassigned_access() into a CPUState hook
  2013-06-17 20:34   ` Richard Henderson
@ 2013-06-21 10:31     ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-21 10:31 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

Am 17.06.2013 22:34, schrieb Richard Henderson:
> On 06/16/2013 08:57 AM, Andreas Färber wrote:
>> +        cpu = CPU(alpha_env_get_cpu(cpu_single_env));
>> +        cs = CPU(alpha_env_get_cpu(cpu_single_env));
>> +    CPUState *cpu_single_cpu = CPU(alpha_env_get_cpu(cpu_single_env));
>> +        cs = CPU(alpha_env_get_cpu(cpu_single_env));
> 
> ENV_GET_CPU.

Intentional, and all of these get replaced later on anyway.

>> +    cpu_class_set_do_unassigned_access(cc, alpha_cpu_unassigned_access);
> 
> Wouldn't it be better to arrange for the function to exist always, with
> differing implementation for user and system, much like do_interrupt?

Sure, that would be possible. But determining what the user
implementation should do would be up to the target, i.e. you for alpha.

> What you've got is good enough for now, I suppose.

Thanks, v3 coming up.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu
  2013-06-17 20:40   ` Richard Henderson
@ 2013-06-21 10:32     ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-21 10:32 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Peter Maydell, Anthony Liguori, qemu-devel, Alexander Graf,
	Blue Swirl, Hervé Poussineau, Paul Brook, Scott Wood,
	qemu-ppc, Aurelien Jarno

Am 17.06.2013 22:40, schrieb Richard Henderson:
> On 06/16/2013 08:57 AM, Andreas Färber wrote:
>> diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
>> index 207dcad..f0b1f6f 100644
>> --- a/hw/alpha/typhoon.c
>> +++ b/hw/alpha/typhoon.c
>> @@ -72,9 +72,8 @@ static void cpu_irq_change(AlphaCPU *cpu, uint64_t req)
>>  
>>  static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
>>  {
>> -    CPUAlphaState *env = cpu_single_env;
>> +    CPUState *cpu = cpu_single_cpu;
>>      TyphoonState *s = opaque;
>> -    CPUState *cpu;
>>      uint64_t ret = 0;
>>  
>>      if (addr & 4) {
>> @@ -95,7 +94,6 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
>>  
>>      case 0x0080:
>>          /* MISC: Miscellaneous Register.  */
>> -        cpu = ENV_GET_CPU(env);
>>          ret = s->cchip.misc | (cpu->cpu_index & 3);
>>          break;
>>  
>> @@ -197,8 +195,7 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
>>          break;
>>  
>>      default:
>> -        cpu = CPU(alpha_env_get_cpu(cpu_single_env));
>> -        cpu_unassigned_access(cpu, addr, false, false, 0, size);
>> +        cpu_unassigned_access(cpu_single_cpu, addr, false, false, 0, size);
> 
> Keep using the local "cpu" variable?

Fixed, thanks.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops
  2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
                   ` (28 preceding siblings ...)
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 29/29] timer/arm_mptimer: Build arm_mptimer " Andreas Färber
@ 2013-06-26 14:20 ` Andreas Färber
  29 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-26 14:20 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Stefano Stabellini, Alexander Graf,
	Markus Armbruster, Blue Swirl, Anthony Liguori, Scott Wood,
	Paolo Bonzini, Aurélien Jarno

Am 16.06.2013 17:57, schrieb Andreas Färber:
> Andreas Färber (29):
>   kvm: Change kvm_cpu_synchronize_state() argument to CPUState

>   kvm: Change cpu_synchronize_state() argument to CPUState
>   gdbstub: Simplify find_cpu()
>   cpu: Change cpu_exit() argument to CPUState
>   cpus: Change cpu_thread_is_idle() argument to CPUState
>   cpus: Change qemu_kvm_wait_io_event() argument to CPUState
>   kvm: Change kvm_set_signal_mask() argument to CPUState
>   cpus: Change qemu_kvm_init_cpu_signals() argument to CPUState
>   cpu: Turn cpu_dump_{state,statistics}() into CPUState hooks
>   kvm: Change kvm_handle_internal_error() argument to CPUState
>   kvm: Change kvm_cpu_exec() argument to CPUState
>   gdbstub: Set gdb_set_stop_cpu() argument to CPUState
>   cpus: Change cpu_handle_guest_debug() argument to CPUState
>   cpus: Change qemu_kvm_start_vcpu() argument to CPUState
>   cpus: Change qemu_dummy_start_vcpu() argument to CPUState
>   cpu: Change qemu_init_vcpu() argument to CPUState
>   hwaddr: Make hwaddr type usable beyond softmmu
>   cpu: Turn cpu_unassigned_access() into a CPUState hook

Applied these to qom-cpu (with extended commit messages):
https://github.com/afaerber/qemu-cpu/commits/qom-cpu

v3 is still taking some time to polish; FYI a draft QTAILQ based
qemu_for_each_cpu() conversion is on qom-cpu-11 branch already but I
prefer to introduce a wrapper CPU_FOR_EACH() macro or something when I
find some time.

Andreas

>   cpu: Replace cpu_single_env with CPUState cpu_single_cpu
>   kvm: Change kvm_remove_all_breakpoints() argument to CPUState
>   cpu: Make first_cpu and next_cpu CPUState
>   linux-user: Change thread_env to CPUState
>   bsd-user: Change thread_env to CPUState
>   cpu: Drop qemu_for_each_cpu()
>   cpu: Move CPU_INTERRUPT_* to qom/cpu.h
>   intc/sh_intc: Build sh_intc only once
>   intc/arm_gic: Build arm_gic only once
>   intc/openpic: Build openpic only once
>   timer/arm_mptimer: Build arm_mptimer only once


-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 20/29] kvm: Change kvm_remove_all_breakpoints() argument to CPUState
  2013-06-17 16:17     ` [Qemu-devel] " Paolo Bonzini
  (?)
@ 2013-06-27 15:58     ` Andreas Färber
  -1 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-06-27 15:58 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Marcelo Tosatti, qemu-devel, Gleb Natapov, kvm

Am 17.06.2013 18:17, schrieb Paolo Bonzini:
> Il 16/06/2013 17:57, Andreas Färber ha scritto:
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>> ---
>>  gdbstub.c            | 2 +-
>>  include/sysemu/kvm.h | 2 +-
>>  kvm-all.c            | 5 ++---
>>  kvm-stub.c           | 2 +-
>>  4 files changed, 5 insertions(+), 6 deletions(-)
>>
>> diff --git a/gdbstub.c b/gdbstub.c
>> index 3101a43..9e7f7a1 100644
>> --- a/gdbstub.c
>> +++ b/gdbstub.c
>> @@ -2019,7 +2019,7 @@ static void gdb_breakpoint_remove_all(void)
>>      CPUArchState *env;
>>  
>>      if (kvm_enabled()) {
>> -        kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
>> +        kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu));
> 
> Planning to make gdbserver_state take a CPUState, too?

Yes, I'm still working on that: The qom-cpu-11 series is already about
as large as this one and still has only two out of three CPUArchState
fields converted. ;)

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu
  2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu Andreas Färber
  2013-06-16 20:49   ` Blue Swirl
  2013-06-17 20:40   ` Richard Henderson
@ 2013-07-15 14:56   ` Paolo Bonzini
  2013-07-15 15:20     ` Andreas Färber
  2 siblings, 1 reply; 98+ messages in thread
From: Paolo Bonzini @ 2013-07-15 14:56 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Anthony Liguori, qemu-devel, Alexander Graf,
	Blue Swirl, Andreas Färber, Hervé Poussineau,
	Paul Brook, Scott Wood, mpc8544ds, Aurelien Jarno,
	Richard Henderson

Il 16/06/2013 17:57, Andreas Färber ha scritto:
> Move it to qom/cpu.h.

Hmm, why move it to qom/cpu.h?  Isn't it an implementation detail that
there is a current CPU?

Paolo

> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpu-exec.c              | 13 +++++++------
>  cpus.c                  | 29 ++++++++++++++---------------
>  exec.c                  | 12 +++++++-----
>  hw/alpha/typhoon.c      | 16 ++++------------
>  hw/arm/pxa2xx.c         |  3 +--
>  hw/i386/kvmvapic.c      |  6 ++++--
>  hw/i386/pc.c            | 11 ++++++-----
>  hw/intc/arm_gic.c       |  3 +--
>  hw/intc/armv7m_nvic.c   | 11 ++++++++---
>  hw/intc/openpic.c       |  5 +----
>  hw/mips/mips_fulong2e.c |  6 +++---
>  hw/mips/mips_jazz.c     |  6 +++---
>  hw/mips/mips_malta.c    |  6 +++---
>  hw/misc/vmport.c        | 26 ++++++++++++++++----------
>  hw/ppc/mpc8544_guts.c   |  3 ++-
>  hw/ppc/prep.c           |  6 +++---
>  hw/sparc/sun4m.c        |  5 ++---
>  hw/timer/arm_mptimer.c  |  2 --
>  include/exec/cpu-all.h  |  3 ---
>  include/qom/cpu.h       |  4 ++++
>  memory.c                | 10 ++++------
>  translate-all.c         | 20 ++++++++++++--------
>  user-exec.c             |  9 +++++----
>  23 files changed, 110 insertions(+), 105 deletions(-)
> 
> diff --git a/cpu-exec.c b/cpu-exec.c
> index ec46380..1858c2e 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -213,12 +213,12 @@ int cpu_exec(CPUArchState *env)
>          cpu->halted = 0;
>      }
>  
> -    cpu_single_env = env;
> +    cpu_single_cpu = cpu;
>  
> -    /* As long as cpu_single_env is null, up to the assignment just above,
> +    /* As long as cpu_single_cpu is null, up to the assignment just above,
>       * requests by other threads to exit the execution loop are expected to
>       * be issued using the exit_request global. We must make sure that our
> -     * evaluation of the global value is performed past the cpu_single_env
> +     * evaluation of the global value is performed past the cpu_single_cpu
>       * value transition point, which requires a memory barrier as well as
>       * an instruction scheduling constraint on modern architectures.  */
>      smp_mb();
> @@ -673,7 +673,8 @@ int cpu_exec(CPUArchState *env)
>          } else {
>              /* Reload env after longjmp - the compiler may have smashed all
>               * local variables as longjmp is marked 'noreturn'. */
> -            env = cpu_single_env;
> +            cpu = cpu_single_cpu;
> +            env = cpu->env_ptr;
>          }
>      } /* for(;;) */
>  
> @@ -707,7 +708,7 @@ int cpu_exec(CPUArchState *env)
>  #error unsupported target CPU
>  #endif
>  
> -    /* fail safe : never use cpu_single_env outside cpu_exec() */
> -    cpu_single_env = NULL;
> +    /* fail safe : never use cpu_single_cpu outside cpu_exec() */
> +    cpu_single_cpu = NULL;
>      return ret;
>  }
> diff --git a/cpus.c b/cpus.c
> index 775d998..808503b 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -118,10 +118,11 @@ TimersState timers_state;
>  int64_t cpu_get_icount(void)
>  {
>      int64_t icount;
> -    CPUArchState *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>  
>      icount = qemu_icount;
> -    if (env) {
> +    if (cpu) {
> +        CPUArchState *env = cpu->env_ptr;
>          if (!can_do_io(env)) {
>              fprintf(stderr, "Bad clock read\n");
>          }
> @@ -468,8 +469,8 @@ static void cpu_handle_guest_debug(CPUState *cpu)
>  
>  static void cpu_signal(int sig)
>  {
> -    if (cpu_single_env) {
> -        cpu_exit(ENV_GET_CPU(cpu_single_env));
> +    if (cpu_single_cpu) {
> +        cpu_exit(cpu_single_cpu);
>      }
>      exit_request = 1;
>  }
> @@ -660,10 +661,10 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)
>  
>      qemu_cpu_kick(cpu);
>      while (!wi.done) {
> -        CPUArchState *self_env = cpu_single_env;
> +        CPUState *self_cpu = cpu_single_cpu;
>  
>          qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex);
> -        cpu_single_env = self_env;
> +        cpu_single_cpu = self_cpu;
>      }
>  }
>  
> @@ -733,7 +734,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
>      qemu_mutex_lock(&qemu_global_mutex);
>      qemu_thread_get_self(cpu->thread);
>      cpu->thread_id = qemu_get_thread_id();
> -    cpu_single_env = cpu->env_ptr;
> +    cpu_single_cpu = cpu;
>  
>      r = kvm_init_vcpu(cpu);
>      if (r < 0) {
> @@ -781,9 +782,9 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
>      cpu->created = true;
>      qemu_cond_signal(&qemu_cpu_cond);
>  
> -    cpu_single_env = cpu->env_ptr;
> +    cpu_single_cpu = cpu;
>      while (1) {
> -        cpu_single_env = NULL;
> +        cpu_single_cpu = NULL;
>          qemu_mutex_unlock_iothread();
>          do {
>              int sig;
> @@ -794,7 +795,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
>              exit(1);
>          }
>          qemu_mutex_lock_iothread();
> -        cpu_single_env = cpu->env_ptr;
> +        cpu_single_cpu = cpu;
>          qemu_wait_io_event_common(cpu);
>      }
>  
> @@ -894,8 +895,7 @@ void qemu_cpu_kick(CPUState *cpu)
>  void qemu_cpu_kick_self(void)
>  {
>  #ifndef _WIN32
> -    assert(cpu_single_env);
> -    CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
> +    assert(cpu_single_cpu);
>  
>      if (!cpu_single_cpu->thread_kicked) {
>          qemu_cpu_kick_thread(cpu_single_cpu);
> @@ -913,7 +913,7 @@ bool qemu_cpu_is_self(CPUState *cpu)
>  
>  static bool qemu_in_vcpu_thread(void)
>  {
> -    return cpu_single_env && qemu_cpu_is_self(ENV_GET_CPU(cpu_single_env));
> +    return cpu_single_cpu && qemu_cpu_is_self(cpu_single_cpu);
>  }
>  
>  void qemu_mutex_lock_iothread(void)
> @@ -1069,8 +1069,7 @@ void qemu_init_vcpu(CPUState *cpu)
>  
>  void cpu_stop_current(void)
>  {
> -    if (cpu_single_env) {
> -        CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
> +    if (cpu_single_cpu) {
>          cpu_single_cpu->stop = false;
>          cpu_single_cpu->stopped = true;
>          cpu_exit(cpu_single_cpu);
> diff --git a/exec.c b/exec.c
> index 2b99bb9..e14a815 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -73,7 +73,7 @@ static MemoryRegion io_mem_unassigned, io_mem_subpage_ram;
>  CPUArchState *first_cpu;
>  /* current CPU in the current thread. It is only valid inside
>     cpu_exec() */
> -DEFINE_TLS(CPUArchState *,cpu_single_env);
> +DEFINE_TLS(CPUState *,cpu_single_cpu);
>  /* 0 = Do not count executed instructions.
>     1 = Precise instruction counting.
>     2 = Adaptive rate instruction counting.  */
> @@ -1420,8 +1420,10 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
>      cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
>      /* we remove the notdirty callback only if the code has been
>         flushed */
> -    if (dirty_flags == 0xff)
> -        tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
> +    if (dirty_flags == 0xff) {
> +        CPUArchState *env = cpu_single_cpu->env_ptr;
> +        tlb_set_dirty(env, env->mem_io_vaddr);
> +    }
>  }
>  
>  static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
> @@ -1439,7 +1441,7 @@ static const MemoryRegionOps notdirty_mem_ops = {
>  /* Generate a debug exception if a watchpoint has been hit.  */
>  static void check_watchpoint(int offset, int len_mask, int flags)
>  {
> -    CPUArchState *env = cpu_single_env;
> +    CPUArchState *env = cpu_single_cpu->env_ptr;
>      target_ulong pc, cs_base;
>      target_ulong vaddr;
>      CPUWatchpoint *wp;
> @@ -1912,7 +1914,7 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
>          if (is_write) {
>              if (!memory_access_is_direct(section->mr, is_write)) {
>                  l = memory_access_size(l, addr1);
> -                /* XXX: could force cpu_single_env to NULL to avoid
> +                /* XXX: could force cpu_single_cpu to NULL to avoid
>                     potential bugs */
>                  if (l == 4) {
>                      /* 32 bit write access */
> diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
> index 207dcad..f0b1f6f 100644
> --- a/hw/alpha/typhoon.c
> +++ b/hw/alpha/typhoon.c
> @@ -72,9 +72,8 @@ static void cpu_irq_change(AlphaCPU *cpu, uint64_t req)
>  
>  static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
>  {
> -    CPUAlphaState *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>      TyphoonState *s = opaque;
> -    CPUState *cpu;
>      uint64_t ret = 0;
>  
>      if (addr & 4) {
> @@ -95,7 +94,6 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
>  
>      case 0x0080:
>          /* MISC: Miscellaneous Register.  */
> -        cpu = ENV_GET_CPU(env);
>          ret = s->cchip.misc | (cpu->cpu_index & 3);
>          break;
>  
> @@ -197,8 +195,7 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
>          break;
>  
>      default:
> -        cpu = CPU(alpha_env_get_cpu(cpu_single_env));
> -        cpu_unassigned_access(cpu, addr, false, false, 0, size);
> +        cpu_unassigned_access(cpu_single_cpu, addr, false, false, 0, size);
>          return -1;
>      }
>  
> @@ -215,7 +212,6 @@ static uint64_t dchip_read(void *opaque, hwaddr addr, unsigned size)
>  static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
>  {
>      TyphoonState *s = opaque;
> -    CPUState *cs;
>      uint64_t ret = 0;
>  
>      if (addr & 4) {
> @@ -302,8 +298,7 @@ static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
>          break;
>  
>      default:
> -        cs = CPU(alpha_env_get_cpu(cpu_single_env));
> -        cpu_unassigned_access(cs, addr, false, false, 0, size);
> +        cpu_unassigned_access(cpu_single_cpu, addr, false, false, 0, size);
>          return -1;
>      }
>  
> @@ -315,7 +310,6 @@ static void cchip_write(void *opaque, hwaddr addr,
>                          uint64_t v32, unsigned size)
>  {
>      TyphoonState *s = opaque;
> -    CPUState *cpu_single_cpu = CPU(alpha_env_get_cpu(cpu_single_env));
>      uint64_t val, oldval, newval;
>  
>      if (addr & 4) {
> @@ -480,7 +474,6 @@ static void pchip_write(void *opaque, hwaddr addr,
>                          uint64_t v32, unsigned size)
>  {
>      TyphoonState *s = opaque;
> -    CPUState *cs;
>      uint64_t val, oldval;
>  
>      if (addr & 4) {
> @@ -582,8 +575,7 @@ static void pchip_write(void *opaque, hwaddr addr,
>          break;
>  
>      default:
> -        cs = CPU(alpha_env_get_cpu(cpu_single_env));
> -        cpu_unassigned_access(cs, addr, true, false, 0, size);
> +        cpu_unassigned_access(cpu_single_cpu, addr, true, false, 0, size);
>          return;
>      }
>  }
> diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
> index 24b03a0..d023167 100644
> --- a/hw/arm/pxa2xx.c
> +++ b/hw/arm/pxa2xx.c
> @@ -301,8 +301,7 @@ static int pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri,
>  #endif
>  
>          /* Suspend */
> -        cpu_interrupt(CPU(arm_env_get_cpu(cpu_single_env)),
> -                      CPU_INTERRUPT_HALT);
> +        cpu_interrupt(cpu_single_cpu, CPU_INTERRUPT_HALT);
>  
>          goto message;
>  
> diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
> index f93629f..9aac9de 100644
> --- a/hw/i386/kvmvapic.c
> +++ b/hw/i386/kvmvapic.c
> @@ -623,11 +623,13 @@ static int vapic_prepare(VAPICROMState *s)
>  static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
>                          unsigned int size)
>  {
> -    CPUX86State *env = cpu_single_env;
> +    CPUState *cs = cpu_single_cpu;
> +    X86CPU *cpu = X86_CPU(cs);
> +    CPUX86State *env = &cpu->env;
>      hwaddr rom_paddr;
>      VAPICROMState *s = opaque;
>  
> -    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
> +    cpu_synchronize_state(cs);
>  
>      /*
>       * The VAPIC supports two PIO-based hypercalls, both via port 0x7E.
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index d7e8507..c43be54 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -887,8 +887,9 @@ void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd)
>  
>  DeviceState *cpu_get_current_apic(void)
>  {
> -    if (cpu_single_env) {
> -        return cpu_single_env->apic_state;
> +    if (cpu_single_cpu) {
> +        X86CPU *cpu = X86_CPU(cpu_single_cpu);
> +        return cpu->env.apic_state;
>      } else {
>          return NULL;
>      }
> @@ -1107,10 +1108,10 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus)
>  
>  static void cpu_request_exit(void *opaque, int irq, int level)
>  {
> -    CPUX86State *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>  
> -    if (env && level) {
> -        cpu_exit(CPU(x86_env_get_cpu(env)));
> +    if (cpu && level) {
> +        cpu_exit(cpu);
>      }
>  }
>  
> diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
> index bae6572..79fd4a9 100644
> --- a/hw/intc/arm_gic.c
> +++ b/hw/intc/arm_gic.c
> @@ -39,8 +39,7 @@ static const uint8_t gic_id[] = {
>  static inline int gic_get_current_cpu(GICState *s)
>  {
>      if (s->num_cpu > 1) {
> -        CPUState *cpu = ENV_GET_CPU(cpu_single_env);
> -        return cpu->cpu_index;
> +        return cpu_single_cpu->cpu_index;
>      }
>      return 0;
>  }
> diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
> index 25fa43c..53576c8 100644
> --- a/hw/intc/armv7m_nvic.c
> +++ b/hw/intc/armv7m_nvic.c
> @@ -140,6 +140,7 @@ void armv7m_nvic_complete_irq(void *opaque, int irq)
>  
>  static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
>  {
> +    ARMCPU *cpu;
>      uint32_t val;
>      int irq;
>  
> @@ -171,7 +172,8 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
>      case 0x1c: /* SysTick Calibration Value.  */
>          return 10000;
>      case 0xd00: /* CPUID Base.  */
> -        return cpu_single_env->cp15.c0_cpuid;
> +        cpu = ARM_CPU(cpu_single_cpu);
> +        return cpu->env.cp15.c0_cpuid;
>      case 0xd04: /* Interrupt Control State.  */
>          /* VECTACTIVE */
>          val = s->gic.running_irq[0];
> @@ -206,7 +208,8 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
>              val |= (1 << 31);
>          return val;
>      case 0xd08: /* Vector Table Offset.  */
> -        return cpu_single_env->v7m.vecbase;
> +        cpu = ARM_CPU(cpu_single_cpu);
> +        return cpu->env.v7m.vecbase;
>      case 0xd0c: /* Application Interrupt/Reset Control.  */
>          return 0xfa05000;
>      case 0xd10: /* System Control.  */
> @@ -279,6 +282,7 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
>  
>  static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)
>  {
> +    ARMCPU *cpu;
>      uint32_t oldval;
>      switch (offset) {
>      case 0x10: /* SysTick Control and Status.  */
> @@ -331,7 +335,8 @@ static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)
>          }
>          break;
>      case 0xd08: /* Vector Table Offset.  */
> -        cpu_single_env->v7m.vecbase = value & 0xffffff80;
> +        cpu = ARM_CPU(cpu_single_cpu);
> +        cpu->env.v7m.vecbase = value & 0xffffff80;
>          break;
>      case 0xd0c: /* Application Interrupt/Reset Control.  */
>          if ((value >> 16) == 0x05fa) {
> diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c
> index c788714..6f152e0 100644
> --- a/hw/intc/openpic.c
> +++ b/hw/intc/openpic.c
> @@ -184,13 +184,10 @@ static int output_to_inttgt(int output)
>  
>  static int get_current_cpu(void)
>  {
> -    CPUState *cpu_single_cpu;
> -
> -    if (!cpu_single_env) {
> +    if (!cpu_single_cpu) {
>          return -1;
>      }
>  
> -    cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
>      return cpu_single_cpu->cpu_index;
>  }
>  
> diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
> index 00c9071..59ee1b4 100644
> --- a/hw/mips/mips_fulong2e.c
> +++ b/hw/mips/mips_fulong2e.c
> @@ -250,10 +250,10 @@ static void network_init (void)
>  
>  static void cpu_request_exit(void *opaque, int irq, int level)
>  {
> -    CPUMIPSState *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>  
> -    if (env && level) {
> -        cpu_exit(CPU(mips_env_get_cpu(env)));
> +    if (cpu && level) {
> +        cpu_exit(cpu);
>      }
>  }
>  
> diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
> index 2ad0c0b..2ffae59 100644
> --- a/hw/mips/mips_jazz.c
> +++ b/hw/mips/mips_jazz.c
> @@ -99,10 +99,10 @@ static const MemoryRegionOps dma_dummy_ops = {
>  
>  static void cpu_request_exit(void *opaque, int irq, int level)
>  {
> -    CPUMIPSState *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>  
> -    if (env && level) {
> -        cpu_exit(CPU(mips_env_get_cpu(env)));
> +    if (cpu && level) {
> +        cpu_exit(cpu);
>      }
>  }
>  
> diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
> index 8a4459d..4fc611c 100644
> --- a/hw/mips/mips_malta.c
> +++ b/hw/mips/mips_malta.c
> @@ -770,10 +770,10 @@ static void main_cpu_reset(void *opaque)
>  
>  static void cpu_request_exit(void *opaque, int irq, int level)
>  {
> -    CPUMIPSState *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>  
> -    if (env && level) {
> -        cpu_exit(CPU(mips_env_get_cpu(env)));
> +    if (cpu && level) {
> +        cpu_exit(cpu);
>      }
>  }
>  
> diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c
> index 8363dfd..deb2232 100644
> --- a/hw/misc/vmport.c
> +++ b/hw/misc/vmport.c
> @@ -62,11 +62,13 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
>                                     unsigned size)
>  {
>      VMPortState *s = opaque;
> -    CPUX86State *env = cpu_single_env;
> +    CPUState *cs = cpu_single_cpu;
> +    X86CPU *cpu = X86_CPU(cs);
> +    CPUX86State *env = &cpu->env;
>      unsigned char command;
>      uint32_t eax;
>  
> -    cpu_synchronize_state(CPU(x86_env_get_cpu(env)));
> +    cpu_synchronize_state(cs);
>  
>      eax = env->regs[R_EAX];
>      if (eax != VMPORT_MAGIC)
> @@ -89,29 +91,32 @@ static uint64_t vmport_ioport_read(void *opaque, hwaddr addr,
>  static void vmport_ioport_write(void *opaque, hwaddr addr,
>                                  uint64_t val, unsigned size)
>  {
> -    CPUX86State *env = cpu_single_env;
> +    X86CPU *cpu = X86_CPU(cpu_single_cpu);
>  
> -    env->regs[R_EAX] = vmport_ioport_read(opaque, addr, 4);
> +    cpu->env.regs[R_EAX] = vmport_ioport_read(opaque, addr, 4);
>  }
>  
>  static uint32_t vmport_cmd_get_version(void *opaque, uint32_t addr)
>  {
> -    CPUX86State *env = cpu_single_env;
> -    env->regs[R_EBX] = VMPORT_MAGIC;
> +    X86CPU *cpu = X86_CPU(cpu_single_cpu);
> +
> +    cpu->env.regs[R_EBX] = VMPORT_MAGIC;
>      return 6;
>  }
>  
>  static uint32_t vmport_cmd_ram_size(void *opaque, uint32_t addr)
>  {
> -    CPUX86State *env = cpu_single_env;
> -    env->regs[R_EBX] = 0x1177;
> +    X86CPU *cpu = X86_CPU(cpu_single_cpu);
> +
> +    cpu->env.regs[R_EBX] = 0x1177;
>      return ram_size;
>  }
>  
>  /* vmmouse helpers */
>  void vmmouse_get_data(uint32_t *data)
>  {
> -    CPUX86State *env = cpu_single_env;
> +    X86CPU *cpu = X86_CPU(cpu_single_cpu);
> +    CPUX86State *env = &cpu->env;
>  
>      data[0] = env->regs[R_EAX]; data[1] = env->regs[R_EBX];
>      data[2] = env->regs[R_ECX]; data[3] = env->regs[R_EDX];
> @@ -120,7 +125,8 @@ void vmmouse_get_data(uint32_t *data)
>  
>  void vmmouse_set_data(const uint32_t *data)
>  {
> -    CPUX86State *env = cpu_single_env;
> +    X86CPU *cpu = X86_CPU(cpu_single_cpu);
> +    CPUX86State *env = &cpu->env;
>  
>      env->regs[R_EAX] = data[0]; env->regs[R_EBX] = data[1];
>      env->regs[R_ECX] = data[2]; env->regs[R_EDX] = data[3];
> diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c
> index 193beab..89f950f 100644
> --- a/hw/ppc/mpc8544_guts.c
> +++ b/hw/ppc/mpc8544_guts.c
> @@ -62,7 +62,8 @@ static uint64_t mpc8544_guts_read(void *opaque, hwaddr addr,
>                                    unsigned size)
>  {
>      uint32_t value = 0;
> -    CPUPPCState *env = cpu_single_env;
> +    PowerPCCPU *cpu = POWERPC_CPU(cpu_single_cpu);
> +    CPUPPCState *env = &cpu->env;
>  
>      addr &= MPC8544_GUTS_MMIO_SIZE - 1;
>      switch (addr) {
> diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
> index 90828f2..16e3132 100644
> --- a/hw/ppc/prep.c
> +++ b/hw/ppc/prep.c
> @@ -417,10 +417,10 @@ static const MemoryRegionOps PPC_prep_io_ops = {
>  
>  static void cpu_request_exit(void *opaque, int irq, int level)
>  {
> -    CPUPPCState *env = cpu_single_env;
> +    CPUState *cpu = cpu_single_cpu;
>  
> -    if (env && level) {
> -        cpu_exit(CPU(ppc_env_get_cpu(env)));
> +    if (cpu && level) {
> +        cpu_exit(cpu);
>      }
>  }
>  
> diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
> index 0e86ca7..1273533 100644
> --- a/hw/sparc/sun4m.c
> +++ b/hw/sparc/sun4m.c
> @@ -264,9 +264,8 @@ static void secondary_cpu_reset(void *opaque)
>  
>  static void cpu_halt_signal(void *opaque, int irq, int level)
>  {
> -    if (level && cpu_single_env) {
> -        cpu_interrupt(CPU(sparc_env_get_cpu(cpu_single_env)),
> -                      CPU_INTERRUPT_HALT);
> +    if (level && cpu_single_cpu) {
> +        cpu_interrupt(cpu_single_cpu, CPU_INTERRUPT_HALT);
>      }
>  }
>  
> diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
> index 317f5e4..1aa300b 100644
> --- a/hw/timer/arm_mptimer.c
> +++ b/hw/timer/arm_mptimer.c
> @@ -49,8 +49,6 @@ typedef struct {
>  
>  static inline int get_current_cpu(ARMMPTimerState *s)
>  {
> -    CPUState *cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
> -
>      if (cpu_single_cpu->cpu_index >= s->num_cpu) {
>          hw_error("arm_mptimer: num-cpu %d but this cpu is %d!\n",
>                   s->num_cpu, cpu_single_cpu->cpu_index);
> diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
> index 35bdf85..6760851 100644
> --- a/include/exec/cpu-all.h
> +++ b/include/exec/cpu-all.h
> @@ -20,7 +20,6 @@
>  #define CPU_ALL_H
>  
>  #include "qemu-common.h"
> -#include "qemu/tls.h"
>  #include "exec/cpu-common.h"
>  #include "qemu/thread.h"
>  
> @@ -358,8 +357,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
>  void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
>      GCC_FMT_ATTR(2, 3);
>  extern CPUArchState *first_cpu;
> -DECLARE_TLS(CPUArchState *,cpu_single_env);
> -#define cpu_single_env tls_var(cpu_single_env)
>  
>  /* Flags for use in ENV->INTERRUPT_PENDING.
>  
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 7afc442..0e2e76c 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -24,6 +24,7 @@
>  #include "hw/qdev-core.h"
>  #include "exec/hwaddr.h"
>  #include "qemu/thread.h"
> +#include "qemu/tls.h"
>  #include "qemu/typedefs.h"
>  
>  typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque);
> @@ -156,6 +157,9 @@ struct CPUState {
>      uint32_t halted; /* used by alpha, cris, ppc TCG */
>  };
>  
> +DECLARE_TLS(CPUState *, cpu_single_cpu);
> +#define cpu_single_cpu tls_var(cpu_single_cpu)
> +
>  /**
>   * cpu_paging_enabled:
>   * @cpu: The CPU whose state is to be inspected.
> diff --git a/memory.c b/memory.c
> index 3bc98ad..f960bd0 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -857,9 +857,8 @@ static uint64_t unassigned_mem_read(void *opaque, hwaddr addr,
>  #ifdef DEBUG_UNASSIGNED
>      printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
>  #endif
> -    if (cpu_single_env != NULL) {
> -        cpu_unassigned_access(ENV_GET_CPU(cpu_single_env),
> -                              addr, false, false, 0, size);
> +    if (cpu_single_cpu != NULL) {
> +        cpu_unassigned_access(cpu_single_cpu, addr, false, false, 0, size);
>      }
>      return 0;
>  }
> @@ -870,9 +869,8 @@ static void unassigned_mem_write(void *opaque, hwaddr addr,
>  #ifdef DEBUG_UNASSIGNED
>      printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val);
>  #endif
> -    if (cpu_single_env != NULL) {
> -        cpu_unassigned_access(ENV_GET_CPU(cpu_single_env),
> -                              addr, true, false, 0, size);
> +    if (cpu_single_cpu != NULL) {
> +        cpu_unassigned_access(cpu_single_cpu, addr, true, false, 0, size);
>      }
>  }
>  
> diff --git a/translate-all.c b/translate-all.c
> index df7c697..4177293 100644
> --- a/translate-all.c
> +++ b/translate-all.c
> @@ -999,8 +999,10 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
>                                     int is_cpu_write_access)
>  {
>      TranslationBlock *tb, *tb_next, *saved_tb;
> -    CPUArchState *env = cpu_single_env;
> -    CPUState *cpu = NULL;
> +    CPUState *cpu = cpu_single_cpu;
> +#if defined(TARGET_HAS_PRECISE_SMC) || !defined(CONFIG_USER_ONLY)
> +    CPUArchState *env = NULL;
> +#endif
>      tb_page_addr_t tb_start, tb_end;
>      PageDesc *p;
>      int n;
> @@ -1023,9 +1025,11 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
>          /* build code bitmap */
>          build_page_bitmap(p);
>      }
> -    if (env != NULL) {
> -        cpu = ENV_GET_CPU(env);
> +#if defined(TARGET_HAS_PRECISE_SMC) || !defined(CONFIG_USER_ONLY)
> +    if (cpu != NULL) {
> +        env = cpu->env_ptr;
>      }
> +#endif
>  
>      /* we remove all the TBs in the range [start, end[ */
>      /* XXX: see if in some cases it could be faster to invalidate all
> @@ -1147,8 +1151,8 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr,
>      int n;
>  #ifdef TARGET_HAS_PRECISE_SMC
>      TranslationBlock *current_tb = NULL;
> -    CPUArchState *env = cpu_single_env;
> -    CPUState *cpu = NULL;
> +    CPUState *cpu = cpu_single_cpu;
> +    CPUArchState *env = NULL;
>      int current_tb_modified = 0;
>      target_ulong current_pc = 0;
>      target_ulong current_cs_base = 0;
> @@ -1165,8 +1169,8 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr,
>      if (tb && pc != 0) {
>          current_tb = tb_find_pc(pc);
>      }
> -    if (env != NULL) {
> -        cpu = ENV_GET_CPU(env);
> +    if (cpu != NULL) {
> +        env = cpu->env_ptr;
>      }
>  #endif
>      while (tb != NULL) {
> diff --git a/user-exec.c b/user-exec.c
> index fa7f1f1..aebdf1e 100644
> --- a/user-exec.c
> +++ b/user-exec.c
> @@ -81,6 +81,7 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
>                                      int is_write, sigset_t *old_set,
>                                      void *puc)
>  {
> +    CPUArchState *env;
>      int ret;
>  
>  #if defined(DEBUG_SIGNAL)
> @@ -93,9 +94,9 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
>          return 1;
>      }
>  
> +    env = cpu_single_cpu->env_ptr;
>      /* see if it is an MMU fault */
> -    ret = cpu_handle_mmu_fault(cpu_single_env, address, is_write,
> -                               MMU_USER_IDX);
> +    ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX);
>      if (ret < 0) {
>          return 0; /* not an MMU fault */
>      }
> @@ -103,12 +104,12 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
>          return 1; /* the MMU fault was handled without causing real CPU fault */
>      }
>      /* now we have a real cpu fault */
> -    cpu_restore_state(cpu_single_env, pc);
> +    cpu_restore_state(env, pc);
>  
>      /* we restore the process signal mask as the sigreturn should
>         do it (XXX: use sigsetjmp) */
>      sigprocmask(SIG_SETMASK, old_set, NULL);
> -    exception_action(cpu_single_env);
> +    exception_action(env);
>  
>      /* never comes here */
>      return 1;
> 

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu
  2013-07-15 14:56   ` Paolo Bonzini
@ 2013-07-15 15:20     ` Andreas Färber
  2013-07-15 15:29       ` Paolo Bonzini
  0 siblings, 1 reply; 98+ messages in thread
From: Andreas Färber @ 2013-07-15 15:20 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Peter Maydell, Anthony Liguori, qemu-devel, Alexander Graf,
	Blue Swirl, Hervé Poussineau, Paul Brook, Scott Wood,
	qemu-ppc, Aurelien Jarno, Richard Henderson

Am 15.07.2013 16:56, schrieb Paolo Bonzini:
> Il 16/06/2013 17:57, Andreas Färber ha scritto:
>> Move it to qom/cpu.h.
> 
> Hmm, why move it to qom/cpu.h?  Isn't it an implementation detail that
> there is a current CPU?

We have some ugly include chains - yes, it shouldn't be here forever.
Just like the qemu/log.h situation is pretty unsatisfactory (I wouldve
liked to place log_cpu_state() into qom/cpu.h but it depends in
qemu-common.h and even ignoring that didn't build for all targets
depending on include order inside cpu.h and of cpu.h).
What we need is (a) header(s) that allows use of CPUState type and that
doesn't use CPUArchState or other target-specifics. I believe the
benefits of getting rid of CPUArchState outweigh the choice of qom/cpu.h
here, which has been serving as a dumpbin for some now
CPUState-dependent functions living in exec.c or cpus.c, too, simply
because CPUState is guaranteed to be available there and to separate it
from anything that still needs to be seen through similar to cpu-qom.h
vs. cpu.h. If you have a spontaneous suggestion I'd be all ears.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu
  2013-07-15 15:20     ` Andreas Färber
@ 2013-07-15 15:29       ` Paolo Bonzini
  2013-07-18 10:25         ` Andreas Färber
  0 siblings, 1 reply; 98+ messages in thread
From: Paolo Bonzini @ 2013-07-15 15:29 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Anthony Liguori, qemu-devel, Alexander Graf,
	Blue Swirl, Hervé Poussineau, Paul Brook, Scott Wood,
	qemu-ppc, Aurelien Jarno, Richard Henderson

Il 15/07/2013 17:20, Andreas Färber ha scritto:
> We have some ugly include chains - yes, it shouldn't be here forever.
> Just like the qemu/log.h situation is pretty unsatisfactory (I wouldve
> liked to place log_cpu_state() into qom/cpu.h but it depends in
> qemu-common.h and even ignoring that didn't build for all targets
> depending on include order inside cpu.h and of cpu.h).
> What we need is (a) header(s) that allows use of CPUState type and that
> doesn't use CPUArchState or other target-specifics. I believe the
> benefits of getting rid of CPUArchState outweigh the choice of qom/cpu.h
> here, which has been serving as a dumpbin for some now
> CPUState-dependent functions living in exec.c or cpus.c, too, simply
> because CPUState is guaranteed to be available there and to separate it
> from anything that still needs to be seen through similar to cpu-qom.h
> vs. cpu.h. If you have a spontaneous suggestion I'd be all ears.

I'm not sure why it couldn't have stayed in cpu-all.h, but I must be
missing something. :)

Paolo

^ permalink raw reply	[flat|nested] 98+ messages in thread

* Re: [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu
  2013-07-15 15:29       ` Paolo Bonzini
@ 2013-07-18 10:25         ` Andreas Färber
  0 siblings, 0 replies; 98+ messages in thread
From: Andreas Färber @ 2013-07-18 10:25 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: Peter Maydell, Anthony Liguori, qemu-devel, Alexander Graf,
	Blue Swirl, Hervé Poussineau, Paul Brook, Scott Wood,
	qemu-ppc, Aurelien Jarno, Richard Henderson

Am 15.07.2013 17:29, schrieb Paolo Bonzini:
> Il 15/07/2013 17:20, Andreas Färber ha scritto:
>> We have some ugly include chains - yes, it shouldn't be here forever.
>> Just like the qemu/log.h situation is pretty unsatisfactory (I wouldve
>> liked to place log_cpu_state() into qom/cpu.h but it depends in
>> qemu-common.h and even ignoring that didn't build for all targets
>> depending on include order inside cpu.h and of cpu.h).
>> What we need is (a) header(s) that allows use of CPUState type and that
>> doesn't use CPUArchState or other target-specifics. I believe the
>> benefits of getting rid of CPUArchState outweigh the choice of qom/cpu.h
>> here, which has been serving as a dumpbin for some now
>> CPUState-dependent functions living in exec.c or cpus.c, too, simply
>> because CPUState is guaranteed to be available there and to separate it
>> from anything that still needs to be seen through similar to cpu-qom.h
>> vs. cpu.h. If you have a spontaneous suggestion I'd be all ears.
> 
> I'm not sure why it couldn't have stayed in cpu-all.h, but I must be
> missing something. :)

You're missing TARGET_WORDS_BIGENDIAN on line 39, target_ulong further
down, CPUArchState in cpu_copy() and cpu_abort(), etc.

By placing it in a header that does not have this baggage, some timer
and intc devices in this series were able to drop their dependency on
cpu.h in favor of qom/cpu.h and be built in common-obj-y rather than obj-y.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 98+ messages in thread

end of thread, other threads:[~2013-07-18 10:25 UTC | newest]

Thread overview: 98+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-16 15:57 [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber
2013-06-16 15:57 ` [PATCH qom-cpu v2 01/29] kvm: Change kvm_cpu_synchronize_state() argument to CPUState Andreas Färber
2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
2013-06-17 19:48   ` Richard Henderson
     [not found]   ` <51BF360E.8090402@redhat.com>
2013-06-18 16:36     ` Andreas Färber
2013-06-18 16:36       ` [Qemu-devel] " Andreas Färber
2013-06-16 15:57 ` [PATCH qom-cpu v2 02/29] kvm: Change cpu_synchronize_state() " Andreas Färber
2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
2013-06-17 19:46   ` Richard Henderson
2013-06-17 20:58     ` Andreas Färber
2013-06-17 21:02       ` Richard Henderson
2013-06-17 21:09         ` Andreas Färber
2013-06-18  9:39   ` Igor Mammedov
2013-06-18  9:39     ` [Qemu-devel] " Igor Mammedov
2013-06-21 10:25     ` Andreas Färber
2013-06-21 10:25       ` [Qemu-devel] " Andreas Färber
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 03/29] gdbstub: Simplify find_cpu() Andreas Färber
2013-06-17 19:54   ` Richard Henderson
2013-06-19 17:30     ` Andreas Färber
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 04/29] cpu: Change cpu_exit() argument to CPUState Andreas Färber
2013-06-17 19:59   ` Richard Henderson
2013-06-17 21:00     ` Andreas Färber
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 05/29] cpus: Change cpu_thread_is_idle() " Andreas Färber
2013-06-17 20:00   ` Richard Henderson
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 06/29] cpus: Change qemu_kvm_wait_io_event() " Andreas Färber
2013-06-17 20:02   ` Richard Henderson
2013-06-16 15:57 ` [PATCH qom-cpu v2 07/29] kvm: Change kvm_set_signal_mask() " Andreas Färber
2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
2013-06-17 16:15   ` Paolo Bonzini
2013-06-17 16:15     ` [Qemu-devel] " Paolo Bonzini
2013-06-17 20:03   ` Richard Henderson
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 08/29] cpus: Change qemu_kvm_init_cpu_signals() " Andreas Färber
2013-06-17 20:04   ` Richard Henderson
2013-06-16 15:57 ` [PATCH qom-cpu v2 09/29] cpu: Turn cpu_dump_{state,statistics}() into CPUState hooks Andreas Färber
2013-06-16 15:57   ` [Qemu-devel] [PATCH qom-cpu v2 09/29] cpu: Turn cpu_dump_{state, statistics}() " Andreas Färber
2013-06-17 20:12   ` Richard Henderson
2013-06-16 15:57 ` [PATCH qom-cpu v2 10/29] kvm: Change kvm_handle_internal_error() argument to CPUState Andreas Färber
2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
2013-06-17 16:16   ` Paolo Bonzini
2013-06-17 16:16     ` [Qemu-devel] " Paolo Bonzini
2013-06-17 20:13   ` Richard Henderson
2013-06-17 20:13     ` [Qemu-devel] " Richard Henderson
2013-06-16 15:57 ` [PATCH qom-cpu v2 11/29] kvm: Change kvm_cpu_exec() " Andreas Färber
2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
2013-06-17 16:17   ` Paolo Bonzini
2013-06-17 16:17     ` [Qemu-devel] " Paolo Bonzini
2013-06-17 20:14   ` Richard Henderson
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 12/29] gdbstub: Set gdb_set_stop_cpu() " Andreas Färber
2013-06-17 20:15   ` Richard Henderson
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 13/29] cpus: Change cpu_handle_guest_debug() " Andreas Färber
2013-06-17 20:17   ` Richard Henderson
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 14/29] cpus: Change qemu_kvm_start_vcpu() " Andreas Färber
2013-06-17 20:18   ` Richard Henderson
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 15/29] cpus: Change qemu_dummy_start_vcpu() " Andreas Färber
2013-06-17 20:19   ` Richard Henderson
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 16/29] cpu: Change qemu_init_vcpu() " Andreas Färber
2013-06-17 20:23   ` Richard Henderson
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 17/29] hwaddr: Make hwaddr type usable beyond softmmu Andreas Färber
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 18/29] cpu: Turn cpu_unassigned_access() into a CPUState hook Andreas Färber
2013-06-17 20:34   ` Richard Henderson
2013-06-21 10:31     ` Andreas Färber
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 19/29] cpu: Replace cpu_single_env with CPUState cpu_single_cpu Andreas Färber
2013-06-16 20:49   ` Blue Swirl
2013-06-18 16:52     ` Andreas Färber
2013-06-19 12:59       ` Paolo Bonzini
2013-06-17 20:40   ` Richard Henderson
2013-06-21 10:32     ` Andreas Färber
2013-07-15 14:56   ` Paolo Bonzini
2013-07-15 15:20     ` Andreas Färber
2013-07-15 15:29       ` Paolo Bonzini
2013-07-18 10:25         ` Andreas Färber
2013-06-16 15:57 ` [PATCH qom-cpu v2 20/29] kvm: Change kvm_remove_all_breakpoints() argument to CPUState Andreas Färber
2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
2013-06-17 16:17   ` Paolo Bonzini
2013-06-17 16:17     ` [Qemu-devel] " Paolo Bonzini
2013-06-27 15:58     ` Andreas Färber
2013-06-17 20:41   ` Richard Henderson
2013-06-16 15:57 ` [PATCH qom-cpu v2 21/29] cpu: Make first_cpu and next_cpu CPUState Andreas Färber
2013-06-16 15:57   ` [Qemu-devel] " Andreas Färber
2013-06-17 16:20   ` Paolo Bonzini
2013-06-17 16:20     ` [Qemu-devel] " Paolo Bonzini
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 22/29] linux-user: Change thread_env to CPUState Andreas Färber
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 23/29] bsd-user: " Andreas Färber
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 24/29] cpu: Drop qemu_for_each_cpu() Andreas Färber
2013-06-16 20:26   ` Michael S. Tsirkin
2013-06-16 20:30     ` Peter Maydell
2013-06-16 20:36       ` Michael S. Tsirkin
2013-06-16 20:41     ` Andreas Färber
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 25/29] cpu: Move CPU_INTERRUPT_* to qom/cpu.h Andreas Färber
2013-06-17 20:59   ` Richard Henderson
2013-06-17 21:13     ` Andreas Färber
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 26/29] intc/sh_intc: Build sh_intc only once Andreas Färber
2013-06-17 21:08   ` Richard Henderson
2013-06-17 21:17     ` Andreas Färber
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 27/29] intc/arm_gic: Build arm_gic " Andreas Färber
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 28/29] intc/openpic: Build openpic " Andreas Färber
2013-06-16 15:57 ` [Qemu-devel] [PATCH qom-cpu v2 29/29] timer/arm_mptimer: Build arm_mptimer " Andreas Färber
2013-06-26 14:20 ` [Qemu-devel] [PATCH qom-cpu v2 00/29] QOM CPUState, part 10: CPU loops Andreas Färber

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.