All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10
@ 2013-07-10 14:33 Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 01/43] target-openrisc: Fix typename in openrisc_cpu_class_by_name() Andreas Färber
                   ` (42 more replies)
  0 siblings, 43 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Peter Crosthwaite, Mike Frysinger, Jia Liu,
	Riku Voipio, Alexander Graf, Eduardo Habkost, Stacey Son,
	Max Filippov, Anthony Liguori, Igor Mammedov,
	Andreas Färber, Richard Henderson

Hello Anthony,

This is my current QOM CPU patch queue. Please pull.
Note that this is a signed pull and not for qom-cpu branch as usual!

Thanks,
Andreas

Cc: Anthony Liguori <anthony@codemonkey.ws>

Cc: Richard Henderson <rth@twiddle.net>
Cc: Jia Liu <proljc@gmail.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Alexander Graf <agraf@suse.de>
Cc: Max Filippov <jcmvbkbc@gmail.com>

Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Riku Voipio <riku.voipio@iki.fi>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: Stacey Son <sson@FreeBSD.org>
Cc: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

The following changes since commit dc11549ec213f85f6a024c7df68d349464cd1688:

  Merge remote-tracking branch 'mst/tags/for_anthony' into staging (2013-07-08 08:00:23 -0500)

are available in the git repository at:


  git://github.com/afaerber/qemu-cpu.git tags/qom-cpu-for-anthony

for you to fetch changes up to 91b1df8cf9e1ecaa8679c9ea8713d1e25c28e6c4:

  cpu: Move reset logging to CPUState (2013-07-09 21:33:04 +0200)

----------------------------------------------------------------
QOM CPUState refactorings

* Fix for OpenRISCCPU subclasses
* Fix for gdbstub CPU selection
* Move linux-user CPU functions into new header
* CPUState part 10 refactoring: first_cpu, next_cpu, cpu_single_env et al.
* Fix some targets to consistently inline TCG code generation
* Centrally log CPU reset

----------------------------------------------------------------
Andreas Färber (41):
      Revert "gdbstub: Simplify find_cpu()"
      cpu: Drop unnecessary dynamic casts in *_env_get_cpu()
      kvm: Free current_cpu identifier
      cpu: Replace cpu_single_env with CPUState current_cpu
      kvm: Change kvm_remove_all_breakpoints() argument to CPUState
      linux-user: Clean up do_syscall() Coding Style for TARGET_NR_exit
      cpu: Make first_cpu and next_cpu CPUState
      linux-user: Change thread_env to CPUState
      bsd-user: Change thread_env to CPUState
      intc/arm_gic: Build arm_gic only once
      intc/openpic: Build openpic only once
      timer/arm_mptimer: Build arm_mptimer only once
      target-ppc: Don't overuse ENV_GET_CPU()
      target-s390x: Don't overuse ENV_GET_CPU()
      target-s390x: Change handle_{hypercall,diag}() argument to S390CPU
      target-i386: Don't overuse CPUArchState
      target-cris: gen_intermediate_code_internal() should be inlined
      target-lm32: gen_intermediate_code_internal() should be inlined
      target-microblaze: gen_intermediate_code_internal() should be inlined
      target-moxie: gen_intermediate_code_internal() should be inlined
      target-xtensa: gen_intermediate_code_internal() should be inlined
      target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU
      target-arm: Change gen_intermediate_code_internal() argument to ARMCPU
      target-cris: Change gen_intermediate_code_internal() argument to CRISCPU
      target-i386: Change gen_intermediate_code_internal() argument to X86CPU
      target-lm32: Change gen_intermediate_code_internal() argument to LM32CPU
      target-m68k: Change gen_intermediate_code_internal() argument to M68kCPU
      target-microblaze: Change gen_intermediate_code_internal() argument types
      target-mips: Change gen_intermediate_code_internal() argument to MIPSCPU
      target-ppc: Change gen_intermediate_code_internal() argument to PowerPCCPU
      target-s390x: Change gen_intermediate_code_internal() argument to S390CPU
      target-sh4: Change gen_intermediate_code_internal() argument to SuperHCPU
      target-sparc: Change gen_intermediate_code_internal() argument to SPARCCPU
      target-unicore32: Change gen_intermediate_code_internal() signature
      target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU
      target-i386: Change do_interrupt_all() argument to X86CPU
      target-i386: Change do_smm_enter() argument to X86CPU
      log: Change log_cpu_state[_mask]() argument to CPUState
      target-i386: Change LOG_PCALL_STATE() argument to CPUState
      target-ppc: Change LOG_MMU_STATE() argument to CPUState
      cpu: Move reset logging to CPUState

Dongxue Zhang (1):
      target-openrisc: Fix typename in openrisc_cpu_class_by_name()

Peter Maydell (1):
      linux-user: Move cpu_clone_regs() and cpu_set_tls() into linux-user

 bsd-user/elfload.c                 |   6 +-
 bsd-user/main.c                    |   6 +-
 bsd-user/qemu.h                    |   2 +-
 cpu-exec.c                         |  21 ++---
 cpus.c                             | 167 +++++++++++++++++++------------------
 cputlb.c                           |   4 +-
 dump.c                             |  16 ++--
 exec.c                             |  57 +++++++------
 gdbstub.c                          |  45 ++++++----
 hw/alpha/typhoon.c                 |  16 +---
 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/clock.c                |  12 +--
 hw/i386/kvmvapic.c                 |  19 +++--
 hw/i386/pc.c                       |  28 ++++---
 hw/i386/pc_piix.c                  |   3 +-
 hw/intc/Makefile.objs              |   4 +-
 hw/intc/arm_gic.c                  |   4 +-
 hw/intc/armv7m_nvic.c              |  11 ++-
 hw/intc/openpic.c                  |   9 +-
 hw/intc/sh_intc.c                  |   5 +-
 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/e500.c                      |   5 +-
 hw/ppc/mpc8544_guts.c              |   3 +-
 hw/ppc/ppc.c                       |  12 +--
 hw/ppc/prep.c                      |  12 +--
 hw/ppc/spapr.c                     |  27 +++---
 hw/sparc/sun4m.c                   |   5 +-
 hw/timer/Makefile.objs             |   2 +-
 hw/timer/arm_mptimer.c             |   9 +-
 include/exec/cpu-all.h             |   4 -
 include/exec/cpu-defs.h            |   1 -
 include/hw/ppc/ppc.h               |   2 -
 include/hw/ppc/ppc_e500.h          |   6 ++
 include/qemu/log.h                 |  26 ++++--
 include/qom/cpu.h                  |  10 +++
 include/sysemu/kvm.h               |  10 +--
 kvm-all.c                          |  53 ++++++------
 kvm-stub.c                         |   6 +-
 linux-user/alpha/target_cpu.h      |  36 ++++++++
 linux-user/arm/target_cpu.h        |  35 ++++++++
 linux-user/cris/target_cpu.h       |  36 ++++++++
 linux-user/elfload.c               |  21 +++--
 linux-user/i386/target_cpu.h       |  33 ++++++++
 linux-user/linuxload.c             |   3 +-
 linux-user/m68k/target_cpu.h       |  34 ++++++++
 linux-user/main.c                  |  21 +++--
 linux-user/microblaze/target_cpu.h |  35 ++++++++
 linux-user/mips/target_cpu.h       |  36 ++++++++
 linux-user/mips64/target_cpu.h     |   1 +
 linux-user/openrisc/target_cpu.h   |  33 ++++++++
 linux-user/ppc/target_cpu.h        |  41 +++++++++
 linux-user/qemu.h                  |   3 +-
 linux-user/s390x/target_cpu.h      |  39 +++++++++
 linux-user/sh4/target_cpu.h        |  35 ++++++++
 linux-user/signal.c                |  12 +--
 linux-user/sparc/target_cpu.h      |  36 ++++++++
 linux-user/sparc64/target_cpu.h    |   1 +
 linux-user/syscall.c               |  80 +++++++++---------
 linux-user/unicore32/target_cpu.h  |  27 ++++++
 linux-user/x86_64/target_cpu.h     |   1 +
 memory.c                           |  10 +--
 memory_mapping.c                   |  16 ++--
 monitor.c                          |   4 +-
 qom/cpu.c                          |   8 ++
 target-alpha/cpu-qom.h             |   2 +-
 target-alpha/cpu.h                 |  16 ----
 target-alpha/translate.c           |   9 +-
 target-arm/cpu-qom.h               |   2 +-
 target-arm/cpu.c                   |   5 --
 target-arm/cpu.h                   |  14 ----
 target-arm/translate.c             |   9 +-
 target-cris/cpu-qom.h              |   2 +-
 target-cris/cpu.c                  |   5 --
 target-cris/cpu.h                  |  14 ----
 target-cris/translate.c            |  11 +--
 target-i386/arch_dump.c            |  17 ++--
 target-i386/cpu-qom.h              |   2 +-
 target-i386/cpu.c                  |   6 +-
 target-i386/cpu.h                  |  11 +--
 target-i386/helper.c               |  15 ++--
 target-i386/kvm.c                  |   8 +-
 target-i386/misc_helper.c          |   2 +-
 target-i386/seg_helper.c           |  20 +++--
 target-i386/smm_helper.c           |  10 ++-
 target-i386/translate.c            |   9 +-
 target-lm32/cpu-qom.h              |   2 +-
 target-lm32/cpu.c                  |   5 --
 target-lm32/cpu.h                  |  14 ----
 target-lm32/helper.c               |   4 +-
 target-lm32/translate.c            |  10 ++-
 target-m68k/cpu-qom.h              |   2 +-
 target-m68k/cpu.c                  |   5 --
 target-m68k/cpu.h                  |   9 --
 target-m68k/translate.c            |   9 +-
 target-microblaze/cpu-qom.h        |   2 +-
 target-microblaze/cpu.c            |   5 --
 target-microblaze/cpu.h            |  14 ----
 target-microblaze/helper.c         |  12 +--
 target-microblaze/translate.c      |  13 +--
 target-mips/cpu-qom.h              |   2 +-
 target-mips/cpu.c                  |   5 --
 target-mips/cpu.h                  |  13 ---
 target-mips/helper.c               |   2 +-
 target-mips/op_helper.c            |  25 +++---
 target-mips/translate.c            |   9 +-
 target-moxie/cpu.c                 |   5 --
 target-moxie/cpu.h                 |   2 +-
 target-moxie/translate.c           |   2 +-
 target-openrisc/cpu.c              |   9 +-
 target-openrisc/cpu.h              |  12 +--
 target-openrisc/translate.c        |   2 +-
 target-ppc/cpu-qom.h               |   2 +-
 target-ppc/cpu.h                   |  20 -----
 target-ppc/excp_helper.c           |   9 +-
 target-ppc/kvm.c                   |   2 +-
 target-ppc/mmu-hash32.c            |   4 +-
 target-ppc/mmu-hash64.c            |   4 +-
 target-ppc/mmu_helper.c            |   8 +-
 target-ppc/translate.c             |   9 +-
 target-ppc/translate_init.c        |   5 --
 target-s390x/cpu-qom.h             |   2 +-
 target-s390x/cpu.c                 |   5 --
 target-s390x/cpu.h                 |  16 ----
 target-s390x/kvm.c                 |  14 ++--
 target-s390x/translate.c           |   9 +-
 target-sh4/cpu-qom.h               |   2 +-
 target-sh4/cpu.c                   |   5 --
 target-sh4/cpu.h                   |  14 ----
 target-sh4/helper.c                |   2 +-
 target-sh4/translate.c             |   9 +-
 target-sparc/cpu-qom.h             |   2 +-
 target-sparc/cpu.c                 |   5 --
 target-sparc/cpu.h                 |  12 ---
 target-sparc/int32_helper.c        |   2 +-
 target-sparc/int64_helper.c        |   2 +-
 target-sparc/translate.c           |  10 ++-
 target-unicore32/cpu-qom.h         |   2 +-
 target-unicore32/cpu.h             |  13 ---
 target-unicore32/translate.c       |   9 +-
 target-xtensa/cpu-qom.h            |   2 +-
 target-xtensa/translate.c          |  10 ++-
 translate-all.c                    |  32 ++++---
 user-exec.c                        |   9 +-
 153 files changed, 1141 insertions(+), 832 deletions(-)
 create mode 100644 include/hw/ppc/ppc_e500.h
 create mode 100644 linux-user/alpha/target_cpu.h
 create mode 100644 linux-user/arm/target_cpu.h
 create mode 100644 linux-user/cris/target_cpu.h
 create mode 100644 linux-user/i386/target_cpu.h
 create mode 100644 linux-user/m68k/target_cpu.h
 create mode 100644 linux-user/microblaze/target_cpu.h
 create mode 100644 linux-user/mips/target_cpu.h
 create mode 100644 linux-user/mips64/target_cpu.h
 create mode 100644 linux-user/openrisc/target_cpu.h
 create mode 100644 linux-user/ppc/target_cpu.h
 create mode 100644 linux-user/s390x/target_cpu.h
 create mode 100644 linux-user/sh4/target_cpu.h
 create mode 100644 linux-user/sparc/target_cpu.h
 create mode 100644 linux-user/sparc64/target_cpu.h
 create mode 100644 linux-user/unicore32/target_cpu.h
 create mode 100644 linux-user/x86_64/target_cpu.h

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

* [Qemu-devel] [PULL 01/43] target-openrisc: Fix typename in openrisc_cpu_class_by_name()
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 02/43] Revert "gdbstub: Simplify find_cpu()" Andreas Färber
                   ` (41 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jia Liu, Dongxue Zhang, qemu-stable, Andreas Färber

From: Dongxue Zhang <elta.era@gmail.com>

Commit 478032a93d908e59085c1ac56f10979942e7dc4f (target-openrisc:
Rename CPU subtypes) suffixed CPU sub-types with "-or32-cpu" but forgot
to update openrisc_cpu_class_by_name(), so that it was still looking for
the types without suffix.

Make target-openrisc running OK by adding the suffix to the model name.

This means it is no longer possible to use -cpu or1200-or32-cpu or
-cpu any-or32-cpu though.

Cc: qemu-stable@nongnu.org
Signed-off-by: Dongxue Zhang <elta.era@gmail.com>
Tested-by: Jia Liu <proljc@gmail.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-openrisc/cpu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index fd90d37..d38c28b 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -96,12 +96,14 @@ static void openrisc_cpu_initfn(Object *obj)
 static ObjectClass *openrisc_cpu_class_by_name(const char *cpu_model)
 {
     ObjectClass *oc;
+    char *typename;
 
     if (cpu_model == NULL) {
         return NULL;
     }
 
-    oc = object_class_by_name(cpu_model);
+    typename = g_strdup_printf("%s-" TYPE_OPENRISC_CPU, cpu_model);
+    oc = object_class_by_name(typename);
     if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_OPENRISC_CPU) ||
                        object_class_is_abstract(oc))) {
         return NULL;
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 02/43] Revert "gdbstub: Simplify find_cpu()"
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 01/43] target-openrisc: Fix typename in openrisc_cpu_class_by_name() Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 03/43] linux-user: Move cpu_clone_regs() and cpu_set_tls() into linux-user Andreas Färber
                   ` (40 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

This reverts commit c52a6b67c1d7c6fc9fb2e3ba988d7b978e1487d3, which
replaced cpu_index() with cpu_index field, leading to deviation from
thread ID for NTPL and off-by-one otherwise.

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

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

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

* [Qemu-devel] [PULL 03/43] linux-user: Move cpu_clone_regs() and cpu_set_tls() into linux-user
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 01/43] target-openrisc: Fix typename in openrisc_cpu_class_by_name() Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 02/43] Revert "gdbstub: Simplify find_cpu()" Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 04/43] cpu: Drop unnecessary dynamic casts in *_env_get_cpu() Andreas Färber
                   ` (39 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Jia Liu, Riku Voipio, Alexander Graf, Blue Swirl,
	Michael Walle, open list:PowerPC, Paul Brook, Edgar E. Iglesias,
	Guan Xuetao, Andreas Färber, Aurelien Jarno,
	Richard Henderson

From: Peter Maydell <peter.maydell@linaro.org>

The functions cpu_clone_regs() and cpu_set_tls() are not purely CPU
related -- they are specific to the TLS ABI for a a particular OS.
Move them into the linux-user/ tree where they belong.

target-lm32 had entirely unused implementations, since it has no
linux-user target; just drop them.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Acked-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 linux-user/alpha/target_cpu.h      | 36 +++++++++++++++++++++++++++++++++
 linux-user/arm/target_cpu.h        | 35 ++++++++++++++++++++++++++++++++
 linux-user/cris/target_cpu.h       | 36 +++++++++++++++++++++++++++++++++
 linux-user/i386/target_cpu.h       | 33 ++++++++++++++++++++++++++++++
 linux-user/m68k/target_cpu.h       | 34 +++++++++++++++++++++++++++++++
 linux-user/microblaze/target_cpu.h | 35 ++++++++++++++++++++++++++++++++
 linux-user/mips/target_cpu.h       | 36 +++++++++++++++++++++++++++++++++
 linux-user/mips64/target_cpu.h     |  1 +
 linux-user/openrisc/target_cpu.h   | 33 ++++++++++++++++++++++++++++++
 linux-user/ppc/target_cpu.h        | 41 ++++++++++++++++++++++++++++++++++++++
 linux-user/qemu.h                  |  1 +
 linux-user/s390x/target_cpu.h      | 39 ++++++++++++++++++++++++++++++++++++
 linux-user/sh4/target_cpu.h        | 35 ++++++++++++++++++++++++++++++++
 linux-user/sparc/target_cpu.h      | 36 +++++++++++++++++++++++++++++++++
 linux-user/sparc64/target_cpu.h    |  1 +
 linux-user/unicore32/target_cpu.h  | 27 +++++++++++++++++++++++++
 linux-user/x86_64/target_cpu.h     |  1 +
 target-alpha/cpu.h                 | 16 ---------------
 target-arm/cpu.h                   | 14 -------------
 target-cris/cpu.h                  | 14 -------------
 target-i386/cpu.h                  |  9 ---------
 target-lm32/cpu.h                  | 14 -------------
 target-m68k/cpu.h                  |  9 ---------
 target-microblaze/cpu.h            | 14 -------------
 target-mips/cpu.h                  | 13 ------------
 target-openrisc/cpu.h              | 10 ----------
 target-ppc/cpu.h                   | 20 -------------------
 target-s390x/cpu.h                 | 16 ---------------
 target-sh4/cpu.h                   | 14 -------------
 target-sparc/cpu.h                 | 12 -----------
 target-unicore32/cpu.h             | 13 ------------
 31 files changed, 460 insertions(+), 188 deletions(-)
 create mode 100644 linux-user/alpha/target_cpu.h
 create mode 100644 linux-user/arm/target_cpu.h
 create mode 100644 linux-user/cris/target_cpu.h
 create mode 100644 linux-user/i386/target_cpu.h
 create mode 100644 linux-user/m68k/target_cpu.h
 create mode 100644 linux-user/microblaze/target_cpu.h
 create mode 100644 linux-user/mips/target_cpu.h
 create mode 100644 linux-user/mips64/target_cpu.h
 create mode 100644 linux-user/openrisc/target_cpu.h
 create mode 100644 linux-user/ppc/target_cpu.h
 create mode 100644 linux-user/s390x/target_cpu.h
 create mode 100644 linux-user/sh4/target_cpu.h
 create mode 100644 linux-user/sparc/target_cpu.h
 create mode 100644 linux-user/sparc64/target_cpu.h
 create mode 100644 linux-user/unicore32/target_cpu.h
 create mode 100644 linux-user/x86_64/target_cpu.h

diff --git a/linux-user/alpha/target_cpu.h b/linux-user/alpha/target_cpu.h
new file mode 100644
index 0000000..4256245
--- /dev/null
+++ b/linux-user/alpha/target_cpu.h
@@ -0,0 +1,36 @@
+/*
+ * Alpha specific CPU ABI and functions for linux-user
+ *
+ *  Copyright (c) 2007 Jocelyn Mayer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUAlphaState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->ir[IR_SP] = newsp;
+    }
+    env->ir[IR_V0] = 0;
+    env->ir[IR_A3] = 0;
+}
+
+static inline void cpu_set_tls(CPUAlphaState *env, target_ulong newtls)
+{
+    env->unique = newtls;
+}
+
+#endif
diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h
new file mode 100644
index 0000000..ed323c0
--- /dev/null
+++ b/linux-user/arm/target_cpu.h
@@ -0,0 +1,35 @@
+/*
+ * ARM specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->regs[13] = newsp;
+    }
+    env->regs[0] = 0;
+}
+
+static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
+{
+    env->cp15.c13_tls2 = newtls;
+}
+
+#endif
diff --git a/linux-user/cris/target_cpu.h b/linux-user/cris/target_cpu.h
new file mode 100644
index 0000000..4d787e5
--- /dev/null
+++ b/linux-user/cris/target_cpu.h
@@ -0,0 +1,36 @@
+/*
+ * CRIS specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2007 AXIS Communications AB
+ * Written by Edgar E. Iglesias
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUCRISState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->regs[14] = newsp;
+    }
+    env->regs[10] = 0;
+}
+
+static inline void cpu_set_tls(CPUCRISState *env, target_ulong newtls)
+{
+    env->pregs[PR_PID] = (env->pregs[PR_PID] & 0xff) | newtls;
+}
+
+#endif
diff --git a/linux-user/i386/target_cpu.h b/linux-user/i386/target_cpu.h
new file mode 100644
index 0000000..abcac79
--- /dev/null
+++ b/linux-user/i386/target_cpu.h
@@ -0,0 +1,33 @@
+/*
+ * i386 specific CPU ABI and functions for linux-user
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->regs[R_ESP] = newsp;
+    }
+    env->regs[R_EAX] = 0;
+}
+
+/* TODO: need to implement cpu_set_tls() */
+
+#endif
diff --git a/linux-user/m68k/target_cpu.h b/linux-user/m68k/target_cpu.h
new file mode 100644
index 0000000..8a2a305
--- /dev/null
+++ b/linux-user/m68k/target_cpu.h
@@ -0,0 +1,34 @@
+/*
+ * m68k specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2005-2007 CodeSourcery
+ * Written by Paul Brook
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUM68KState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->aregs[7] = newsp;
+    }
+    env->dregs[0] = 0;
+}
+
+/* TODO: need to implement cpu_set_tls() */
+
+#endif
diff --git a/linux-user/microblaze/target_cpu.h b/linux-user/microblaze/target_cpu.h
new file mode 100644
index 0000000..c6386ea
--- /dev/null
+++ b/linux-user/microblaze/target_cpu.h
@@ -0,0 +1,35 @@
+/*
+ * MicroBlaze specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2009 Edgar E. Iglesias
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUMBState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->regs[R_SP] = newsp;
+    }
+    env->regs[3] = 0;
+}
+
+static inline void cpu_set_tls(CPUMBState *env, target_ulong newtls)
+{
+    env->regs[21] = newtls;
+}
+
+#endif
diff --git a/linux-user/mips/target_cpu.h b/linux-user/mips/target_cpu.h
new file mode 100644
index 0000000..ba8e9eb
--- /dev/null
+++ b/linux-user/mips/target_cpu.h
@@ -0,0 +1,36 @@
+/*
+ * MIPS specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2004-2005 Jocelyn Mayer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUMIPSState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->active_tc.gpr[29] = newsp;
+    }
+    env->active_tc.gpr[7] = 0;
+    env->active_tc.gpr[2] = 0;
+}
+
+static inline void cpu_set_tls(CPUMIPSState *env, target_ulong newtls)
+{
+    env->tls_value = newtls;
+}
+
+#endif
diff --git a/linux-user/mips64/target_cpu.h b/linux-user/mips64/target_cpu.h
new file mode 100644
index 0000000..fa36407
--- /dev/null
+++ b/linux-user/mips64/target_cpu.h
@@ -0,0 +1 @@
+#include "../mips/target_cpu.h"
diff --git a/linux-user/openrisc/target_cpu.h b/linux-user/openrisc/target_cpu.h
new file mode 100644
index 0000000..501fb81
--- /dev/null
+++ b/linux-user/openrisc/target_cpu.h
@@ -0,0 +1,33 @@
+/*
+ * OpenRISC specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->gpr[1] = newsp;
+    }
+    env->gpr[2] = 0;
+}
+
+/* TODO: need to implement cpu_set_tls() */
+
+#endif
diff --git a/linux-user/ppc/target_cpu.h b/linux-user/ppc/target_cpu.h
new file mode 100644
index 0000000..9cc0c3b
--- /dev/null
+++ b/linux-user/ppc/target_cpu.h
@@ -0,0 +1,41 @@
+/*
+ * PowerPC specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2003-2007 Jocelyn Mayer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->gpr[1] = newsp;
+    }
+    env->gpr[3] = 0;
+}
+
+static inline void cpu_set_tls(CPUPPCState *env, target_ulong newtls)
+{
+#if defined(TARGET_PPC64)
+    /* The kernel checks TIF_32BIT here; we don't support loading 32-bit
+       binaries on PPC64 yet. */
+    env->gpr[13] = newtls;
+#else
+    env->gpr[2] = newtls;
+#endif
+}
+
+#endif
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index b10e957..20d171c 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -16,6 +16,7 @@
 #include "exec/user/thunk.h"
 #include "syscall_defs.h"
 #include "syscall.h"
+#include "target_cpu.h"
 #include "target_signal.h"
 #include "exec/gdbstub.h"
 #include "qemu/queue.h"
diff --git a/linux-user/s390x/target_cpu.h b/linux-user/s390x/target_cpu.h
new file mode 100644
index 0000000..f10abe8
--- /dev/null
+++ b/linux-user/s390x/target_cpu.h
@@ -0,0 +1,39 @@
+/*
+ * S/390 specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2009 Ulrich Hecht
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Contributions after 2012-10-29 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ *
+ * You should have received a copy of the GNU (Lesser) General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUS390XState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->regs[15] = newsp;
+    }
+    env->regs[2] = 0;
+}
+
+static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls)
+{
+    env->aregs[0] = newtls >> 32;
+    env->aregs[1] = newtls & 0xffffffffULL;
+}
+
+#endif
diff --git a/linux-user/sh4/target_cpu.h b/linux-user/sh4/target_cpu.h
new file mode 100644
index 0000000..141856f
--- /dev/null
+++ b/linux-user/sh4/target_cpu.h
@@ -0,0 +1,35 @@
+/*
+ * SH4 specific CPU ABI and functions for linux-user
+ *
+ * Copyright (c) 2005 Samuel Tardieu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUSH4State *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->gregs[15] = newsp;
+    }
+    env->gregs[0] = 0;
+}
+
+static inline void cpu_set_tls(CPUSH4State *env, target_ulong newtls)
+{
+  env->gbr = newtls;
+}
+
+#endif
diff --git a/linux-user/sparc/target_cpu.h b/linux-user/sparc/target_cpu.h
new file mode 100644
index 0000000..5a620a2
--- /dev/null
+++ b/linux-user/sparc/target_cpu.h
@@ -0,0 +1,36 @@
+/*
+ * SPARC specific CPU ABI and functions for linux-user
+ *
+ * Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
+ * Copyright (C) 2003-2005 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUSPARCState *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->regwptr[22] = newsp;
+    }
+    env->regwptr[0] = 0;
+    /* FIXME: Do we also need to clear CF?  */
+    /* XXXXX */
+    printf("HELPME: %s:%d\n", __FILE__, __LINE__);
+}
+
+/* TODO: need to implement cpu_set_tls() */
+
+#endif
diff --git a/linux-user/sparc64/target_cpu.h b/linux-user/sparc64/target_cpu.h
new file mode 100644
index 0000000..b22263d
--- /dev/null
+++ b/linux-user/sparc64/target_cpu.h
@@ -0,0 +1 @@
+#include "../sparc/target_cpu.h"
diff --git a/linux-user/unicore32/target_cpu.h b/linux-user/unicore32/target_cpu.h
new file mode 100644
index 0000000..fb79087
--- /dev/null
+++ b/linux-user/unicore32/target_cpu.h
@@ -0,0 +1,27 @@
+/*
+ * UniCore32 specific CPU ABI and functions for linux-user
+ *
+ * Copyright (C) 2010-2012 Guan Xuetao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation, or (at your option) any
+ * later version. See the COPYING file in the top-level directory.
+ */
+#ifndef TARGET_CPU_H
+#define TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUUniCore32State *env, target_ulong newsp)
+{
+    if (newsp) {
+        env->regs[29] = newsp;
+    }
+    env->regs[0] = 0;
+}
+
+static inline void cpu_set_tls(CPUUniCore32State *env, target_ulong newtls)
+{
+    env->regs[16] = newtls;
+}
+
+#endif
diff --git a/linux-user/x86_64/target_cpu.h b/linux-user/x86_64/target_cpu.h
new file mode 100644
index 0000000..9ec7cbb
--- /dev/null
+++ b/linux-user/x86_64/target_cpu.h
@@ -0,0 +1 @@
+#include "../i386/target_cpu.h"
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 01f4ebb..066f032 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -498,22 +498,6 @@ static inline void cpu_get_tb_cpu_state(CPUAlphaState *env, target_ulong *pc,
     *pflags = flags;
 }
 
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUAlphaState *env, target_ulong newsp)
-{
-    if (newsp) {
-        env->ir[IR_SP] = newsp;
-    }
-    env->ir[IR_V0] = 0;
-    env->ir[IR_A3] = 0;
-}
-
-static inline void cpu_set_tls(CPUAlphaState *env, target_ulong newtls)
-{
-    env->unique = newtls;
-}
-#endif
-
 static inline bool cpu_has_work(CPUState *cpu)
 {
     /* Here we are checking to see if the CPU should wake up from HALT.
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index abcc0b4..1369604 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -249,11 +249,6 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
                               int mmu_idx);
 #define cpu_handle_mmu_fault cpu_arm_handle_mmu_fault
 
-static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
-{
-  env->cp15.c13_tls2 = newtls;
-}
-
 #define CPSR_M (0x1f)
 #define CPSR_T (1 << 5)
 #define CPSR_F (1 << 6)
@@ -734,15 +729,6 @@ static inline int cpu_mmu_index (CPUARMState *env)
     return (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0;
 }
 
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
-{
-    if (newsp)
-        env->regs[13] = newsp;
-    env->regs[0] = 0;
-}
-#endif
-
 #include "exec/cpu-all.h"
 
 /* Bit usage in the TB flags field: */
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index dbd7d36..c12a8ca 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -247,20 +247,6 @@ int cpu_cris_handle_mmu_fault(CPUCRISState *env, target_ulong address, int rw,
                               int mmu_idx);
 #define cpu_handle_mmu_fault cpu_cris_handle_mmu_fault
 
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUCRISState *env, target_ulong newsp)
-{
-    if (newsp)
-        env->regs[14] = newsp;
-    env->regs[10] = 0;
-}
-#endif
-
-static inline void cpu_set_tls(CPUCRISState *env, target_ulong newtls)
-{
-	env->pregs[PR_PID] = (env->pregs[PR_PID] & 0xff) | newtls;
-}
-
 /* Support function regs.  */
 #define SFR_RW_GC_CFG      0][0
 #define SFR_RW_MM_CFG      env->pregs[PR_SRS]][0
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 62e3547..2849672 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1125,15 +1125,6 @@ static inline target_long lshift(target_long x, int n)
 /* translate.c */
 void optimize_flags_init(void);
 
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp)
-{
-    if (newsp)
-        env->regs[R_ESP] = newsp;
-    env->regs[R_EAX] = 0;
-}
-#endif
-
 #include "exec/cpu-all.h"
 #include "svm.h"
 
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index bfb9150..856bdc7 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -215,20 +215,6 @@ int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw,
                               int mmu_idx);
 #define cpu_handle_mmu_fault cpu_lm32_handle_mmu_fault
 
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPULM32State *env, target_ulong newsp)
-{
-    if (newsp) {
-        env->regs[R_SP] = newsp;
-    }
-    env->regs[R_R1] = 0;
-}
-#endif
-
-static inline void cpu_set_tls(CPULM32State *env, target_ulong newtls)
-{
-}
-
 #include "exec/cpu-all.h"
 
 static inline void cpu_get_tb_cpu_state(CPULM32State *env, target_ulong *pc,
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index c90c40c..9fdf89e 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -241,15 +241,6 @@ int cpu_m68k_handle_mmu_fault(CPUM68KState *env, target_ulong address, int rw,
                               int mmu_idx);
 #define cpu_handle_mmu_fault cpu_m68k_handle_mmu_fault
 
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUM68KState *env, target_ulong newsp)
-{
-    if (newsp)
-        env->aregs[7] = newsp;
-    env->dregs[0] = 0;
-}
-#endif
-
 #include "exec/cpu-all.h"
 
 static inline void cpu_get_tb_cpu_state(CPUM68KState *env, target_ulong *pc,
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 75ae5ba..6c35475 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -331,20 +331,6 @@ int cpu_mb_handle_mmu_fault(CPUMBState *env, target_ulong address, int rw,
                             int mmu_idx);
 #define cpu_handle_mmu_fault cpu_mb_handle_mmu_fault
 
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUMBState *env, target_ulong newsp)
-{
-    if (newsp)
-        env->regs[R_SP] = newsp;
-    env->regs[3] = 0;
-}
-#endif
-
-static inline void cpu_set_tls(CPUMBState *env, target_ulong newtls)
-{
-    env->regs[21] = newtls;
-}
-
 static inline int cpu_interrupts_enabled(CPUMBState *env)
 {
     return env->sregs[SR_MSR] & MSR_IE;
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index fa0f0d1..7ffd2e3 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -521,14 +521,6 @@ static inline int cpu_mmu_index (CPUMIPSState *env)
     return env->hflags & MIPS_HFLAG_KSU;
 }
 
-static inline void cpu_clone_regs(CPUMIPSState *env, target_ulong newsp)
-{
-    if (newsp)
-        env->active_tc.gpr[29] = newsp;
-    env->active_tc.gpr[7] = 0;
-    env->active_tc.gpr[2] = 0;
-}
-
 static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
 {
     int32_t pending;
@@ -679,11 +671,6 @@ static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
     *flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
 }
 
-static inline void cpu_set_tls(CPUMIPSState *env, target_ulong newtls)
-{
-    env->tls_value = newtls;
-}
-
 static inline int mips_vpe_active(CPUMIPSState *env)
 {
     int active = 1;
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 80a82df..b016f57 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -394,16 +394,6 @@ static inline CPUOpenRISCState *cpu_init(const char *cpu_model)
     return NULL;
 }
 
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp)
-{
-    if (newsp) {
-        env->gpr[1] = newsp;
-    }
-    env->gpr[2] = 0;
-}
-#endif
-
 #include "exec/cpu-all.h"
 
 static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 0ede077..7a7b1bf 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1188,15 +1188,6 @@ static inline int cpu_mmu_index (CPUPPCState *env)
     return env->mmu_idx;
 }
 
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUPPCState *env, target_ulong newsp)
-{
-    if (newsp)
-        env->gpr[1] = newsp;
-    env->gpr[3] = 0;
-}
-#endif
-
 #include "exec/cpu-all.h"
 
 /*****************************************************************************/
@@ -2036,17 +2027,6 @@ static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
     *flags = env->hflags;
 }
 
-static inline void cpu_set_tls(CPUPPCState *env, target_ulong newtls)
-{
-#if defined(TARGET_PPC64)
-    /* The kernel checks TIF_32BIT here; we don't support loading 32-bit
-       binaries on PPC64 yet. */
-    env->gpr[13] = newtls;
-#else
-    env->gpr[2] = newtls;
-#endif
-}
-
 #if !defined(CONFIG_USER_ONLY)
 static inline int booke206_tlbm_id(CPUPPCState *env, ppcmas_tlb_t *tlbm)
 {
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 741c4e4..6462688 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -149,16 +149,6 @@ typedef struct CPUS390XState {
 
 #include "cpu-qom.h"
 
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUS390XState *env, target_ulong newsp)
-{
-    if (newsp) {
-        env->regs[15] = newsp;
-    }
-    env->regs[2] = 0;
-}
-#endif
-
 /* distinguish between 24 bit and 31 bit addressing */
 #define HIGH_ORDER_BIT 0x80000000
 
@@ -515,12 +505,6 @@ static inline bool css_present(uint8_t cssid)
 }
 #endif
 
-static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls)
-{
-    env->aregs[0] = newtls >> 32;
-    env->aregs[1] = newtls & 0xffffffffULL;
-}
-
 #define cpu_init(model) (&cpu_s390x_init(model)->env)
 #define cpu_exec cpu_s390x_exec
 #define cpu_gen_code cpu_s390x_gen_code
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index fd7da92..c8df18b 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -220,11 +220,6 @@ void cpu_sh4_write_mmaped_utlb_data(CPUSH4State *s, hwaddr addr,
 
 int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr);
 
-static inline void cpu_set_tls(CPUSH4State *env, target_ulong newtls)
-{
-  env->gbr = newtls;
-}
-
 void cpu_load_tlb(CPUSH4State * env);
 
 static inline CPUSH4State *cpu_init(const char *cpu_model)
@@ -250,15 +245,6 @@ static inline int cpu_mmu_index (CPUSH4State *env)
     return (env->sr & SR_MD) == 0 ? 1 : 0;
 }
 
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUSH4State *env, target_ulong newsp)
-{
-    if (newsp)
-        env->gregs[15] = newsp;
-    env->gregs[0] = 0;
-}
-#endif
-
 #include "exec/cpu-all.h"
 
 /* Memory access type */
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 021eb157..41b014a 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -690,18 +690,6 @@ static inline int cpu_pil_allowed(CPUSPARCState *env1, int pil)
 #endif
 }
 
-#if defined(CONFIG_USER_ONLY)
-static inline void cpu_clone_regs(CPUSPARCState *env, target_ulong newsp)
-{
-    if (newsp)
-        env->regwptr[22] = newsp;
-    env->regwptr[0] = 0;
-    /* FIXME: Do we also need to clear CF?  */
-    /* XXXXX */
-    printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
-}
-#endif
-
 #include "exec/cpu-all.h"
 
 #ifdef TARGET_SPARC64
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index 5b2b9d1..d4be525 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -142,19 +142,6 @@ static inline int cpu_mmu_index(CPUUniCore32State *env)
     return (env->uncached_asr & ASR_M) == ASR_MODE_USER ? 1 : 0;
 }
 
-static inline void cpu_clone_regs(CPUUniCore32State *env, target_ulong newsp)
-{
-    if (newsp) {
-        env->regs[29] = newsp;
-    }
-    env->regs[0] = 0;
-}
-
-static inline void cpu_set_tls(CPUUniCore32State *env, target_ulong newtls)
-{
-    env->regs[16] = newtls;
-}
-
 #include "exec/cpu-all.h"
 #include "cpu-qom.h"
 #include "exec/exec-all.h"
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 04/43] cpu: Drop unnecessary dynamic casts in *_env_get_cpu()
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (2 preceding siblings ...)
  2013-07-10 14:33 ` [Qemu-devel] [PULL 03/43] linux-user: Move cpu_clone_regs() and cpu_set_tls() into linux-user Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33   ` [Qemu-devel] " Andreas Färber
                   ` (38 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Jia Liu, 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

A transition from CPUFooState to FooCPU can be considered safe,
just like FooCPU::env access in the opposite direction.
The only benefit of the FOO_CPU() casts would be protection against
bogus CPUFooState pointers, but then surrounding code would likely
break, too.

This should slightly improve interrupt etc. performance when going from
CPUFooState to FooCPU.
For any additional CPU() casts see 3556c233d931ad5ffa46a35cb25cfc057732ebb8
(qom: allow turning cast debugging off).

Reported-by: Anthony Liguori <aliguori@us.ibm.com>
Acked-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-alpha/cpu-qom.h      | 2 +-
 target-arm/cpu-qom.h        | 2 +-
 target-cris/cpu-qom.h       | 2 +-
 target-i386/cpu-qom.h       | 2 +-
 target-lm32/cpu-qom.h       | 2 +-
 target-m68k/cpu-qom.h       | 2 +-
 target-microblaze/cpu-qom.h | 2 +-
 target-mips/cpu-qom.h       | 2 +-
 target-moxie/cpu.h          | 2 +-
 target-openrisc/cpu.h       | 2 +-
 target-ppc/cpu-qom.h        | 2 +-
 target-s390x/cpu-qom.h      | 2 +-
 target-sh4/cpu-qom.h        | 2 +-
 target-sparc/cpu-qom.h      | 2 +-
 target-unicore32/cpu-qom.h  | 2 +-
 target-xtensa/cpu-qom.h     | 2 +-
 16 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h
index 94e4a54..60125b1 100644
--- a/target-alpha/cpu-qom.h
+++ b/target-alpha/cpu-qom.h
@@ -67,7 +67,7 @@ typedef struct AlphaCPU {
 
 static inline AlphaCPU *alpha_env_get_cpu(CPUAlphaState *env)
 {
-    return ALPHA_CPU(container_of(env, AlphaCPU, env));
+    return container_of(env, AlphaCPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(alpha_env_get_cpu(e))
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index ef6261f..48ba605 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -127,7 +127,7 @@ typedef struct ARMCPU {
 
 static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
 {
-    return ARM_CPU(container_of(env, ARMCPU, env));
+    return container_of(env, ARMCPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(arm_env_get_cpu(e))
diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h
index e08bdb1..af7d14d 100644
--- a/target-cris/cpu-qom.h
+++ b/target-cris/cpu-qom.h
@@ -66,7 +66,7 @@ typedef struct CRISCPU {
 
 static inline CRISCPU *cris_env_get_cpu(CPUCRISState *env)
 {
-    return CRIS_CPU(container_of(env, CRISCPU, env));
+    return container_of(env, CRISCPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(cris_env_get_cpu(e))
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index b7c70d6..7e55e5f 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -72,7 +72,7 @@ typedef struct X86CPU {
 
 static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
 {
-    return X86_CPU(container_of(env, X86CPU, env));
+    return container_of(env, X86CPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(x86_env_get_cpu(e))
diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h
index 5ef884b..e3bb619 100644
--- a/target-lm32/cpu-qom.h
+++ b/target-lm32/cpu-qom.h
@@ -64,7 +64,7 @@ typedef struct LM32CPU {
 
 static inline LM32CPU *lm32_env_get_cpu(CPULM32State *env)
 {
-    return LM32_CPU(container_of(env, LM32CPU, env));
+    return container_of(env, LM32CPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(lm32_env_get_cpu(e))
diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h
index 2436c13..858bf30 100644
--- a/target-m68k/cpu-qom.h
+++ b/target-m68k/cpu-qom.h
@@ -63,7 +63,7 @@ typedef struct M68kCPU {
 
 static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env)
 {
-    return M68K_CPU(container_of(env, M68kCPU, env));
+    return container_of(env, M68kCPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(m68k_env_get_cpu(e))
diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h
index 3e9c206..ec2b989 100644
--- a/target-microblaze/cpu-qom.h
+++ b/target-microblaze/cpu-qom.h
@@ -64,7 +64,7 @@ typedef struct MicroBlazeCPU {
 
 static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
 {
-    return MICROBLAZE_CPU(container_of(env, MicroBlazeCPU, env));
+    return container_of(env, MicroBlazeCPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(mb_env_get_cpu(e))
diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h
index a7ff9e6..654744a 100644
--- a/target-mips/cpu-qom.h
+++ b/target-mips/cpu-qom.h
@@ -67,7 +67,7 @@ typedef struct MIPSCPU {
 
 static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
 {
-    return MIPS_CPU(container_of(env, MIPSCPU, env));
+    return container_of(env, MIPSCPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(mips_env_get_cpu(e))
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index 374b24a..72d02c2 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -106,7 +106,7 @@ typedef struct MoxieCPU {
 
 static inline MoxieCPU *moxie_env_get_cpu(CPUMoxieState *env)
 {
-    return MOXIE_CPU(container_of(env, MoxieCPU, env));
+    return container_of(env, MoxieCPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(moxie_env_get_cpu(e))
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index b016f57..0aff8f2 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -335,7 +335,7 @@ typedef struct OpenRISCCPU {
 
 static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env)
 {
-    return OPENRISC_CPU(container_of(env, OpenRISCCPU, env));
+    return container_of(env, OpenRISCCPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(openrisc_env_get_cpu(e))
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 84ba105..7132599 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -91,7 +91,7 @@ typedef struct PowerPCCPU {
 
 static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
 {
-    return POWERPC_CPU(container_of(env, PowerPCCPU, env));
+    return container_of(env, PowerPCCPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(ppc_env_get_cpu(e))
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index ec32d21..4c091e3 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -64,7 +64,7 @@ typedef struct S390CPU {
 
 static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
 {
-    return S390_CPU(container_of(env, S390CPU, env));
+    return container_of(env, S390CPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(s390_env_get_cpu(e))
diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h
index 01d1637..c229a9a 100644
--- a/target-sh4/cpu-qom.h
+++ b/target-sh4/cpu-qom.h
@@ -76,7 +76,7 @@ typedef struct SuperHCPU {
 
 static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env)
 {
-    return SUPERH_CPU(container_of(env, SuperHCPU, env));
+    return container_of(env, SuperHCPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(sh_env_get_cpu(e))
diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h
index 97c1ec7..033a5b5 100644
--- a/target-sparc/cpu-qom.h
+++ b/target-sparc/cpu-qom.h
@@ -68,7 +68,7 @@ typedef struct SPARCCPU {
 
 static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
 {
-    return SPARC_CPU(container_of(env, SPARCCPU, env));
+    return container_of(env, SPARCCPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(sparc_env_get_cpu(e))
diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h
index 7eec448..350d480 100644
--- a/target-unicore32/cpu-qom.h
+++ b/target-unicore32/cpu-qom.h
@@ -53,7 +53,7 @@ typedef struct UniCore32CPU {
 
 static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env)
 {
-    return UNICORE32_CPU(container_of(env, UniCore32CPU, env));
+    return container_of(env, UniCore32CPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(uc32_env_get_cpu(e))
diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h
index 30506cf..31e7498 100644
--- a/target-xtensa/cpu-qom.h
+++ b/target-xtensa/cpu-qom.h
@@ -73,7 +73,7 @@ typedef struct XtensaCPU {
 
 static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
 {
-    return XTENSA_CPU(container_of(env, XtensaCPU, env));
+    return container_of(env, XtensaCPU, env);
 }
 
 #define ENV_GET_CPU(e) CPU(xtensa_env_get_cpu(e))
-- 
1.8.1.4

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

* [PULL 05/43] kvm: Free current_cpu identifier
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
@ 2013-07-10 14:33   ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 02/43] Revert "gdbstub: Simplify find_cpu()" Andreas Färber
                     ` (41 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Andreas Färber, Gleb Natapov, Paolo Bonzini, open list:Overall

Since CPU loops are done as last step in kvm_{insert,remove}_breakpoint()
and kvm_remove_all_breakpoints(), we do not need to distinguish between
invoking CPU and iterated CPUs and can thereby free the identifier for
use as a global variable.

Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 include/sysemu/kvm.h | 10 +++++-----
 kvm-all.c            | 39 +++++++++++++++++----------------------
 kvm-stub.c           |  6 +++---
 3 files changed, 25 insertions(+), 30 deletions(-)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index a14cfe9..7596aca 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -169,11 +169,11 @@ void *kvm_arch_ram_alloc(ram_addr_t size);
 void kvm_setup_guest_memory(void *start, size_t size);
 void kvm_flush_coalesced_mmio_buffer(void);
 
-int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type);
-int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type);
-void kvm_remove_all_breakpoints(CPUArchState *current_env);
+void kvm_remove_all_breakpoints(CPUArchState *env);
 int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
 #ifndef _WIN32
 int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset);
@@ -252,9 +252,9 @@ struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *cpu,
 
 int kvm_sw_breakpoints_active(CPUState *cpu);
 
-int kvm_arch_insert_sw_breakpoint(CPUState *current_cpu,
+int kvm_arch_insert_sw_breakpoint(CPUState *cpu,
                                   struct kvm_sw_breakpoint *bp);
-int kvm_arch_remove_sw_breakpoint(CPUState *current_cpu,
+int kvm_arch_remove_sw_breakpoint(CPUState *cpu,
                                   struct kvm_sw_breakpoint *bp);
 int kvm_arch_insert_hw_breakpoint(target_ulong addr,
                                   target_ulong len, int type);
diff --git a/kvm-all.c b/kvm-all.c
index de658de..ed13d57 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1903,16 +1903,15 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return data.err;
 }
 
-int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
-    CPUState *current_cpu = ENV_GET_CPU(current_env);
+    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp;
-    CPUArchState *env;
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
-        bp = kvm_find_sw_breakpoint(current_cpu, addr);
+        bp = kvm_find_sw_breakpoint(cpu, addr);
         if (bp) {
             bp->use_count++;
             return 0;
@@ -1925,14 +1924,13 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
 
         bp->pc = addr;
         bp->use_count = 1;
-        err = kvm_arch_insert_sw_breakpoint(current_cpu, bp);
+        err = kvm_arch_insert_sw_breakpoint(cpu, bp);
         if (err) {
             g_free(bp);
             return err;
         }
 
-        QTAILQ_INSERT_HEAD(&current_cpu->kvm_state->kvm_sw_breakpoints,
-                          bp, entry);
+        QTAILQ_INSERT_HEAD(&cpu->kvm_state->kvm_sw_breakpoints, bp, entry);
     } else {
         err = kvm_arch_insert_hw_breakpoint(addr, len, type);
         if (err) {
@@ -1949,16 +1947,15 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
     return 0;
 }
 
-int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
-    CPUState *current_cpu = ENV_GET_CPU(current_env);
+    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp;
-    CPUArchState *env;
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
-        bp = kvm_find_sw_breakpoint(current_cpu, addr);
+        bp = kvm_find_sw_breakpoint(cpu, addr);
         if (!bp) {
             return -ENOENT;
         }
@@ -1968,12 +1965,12 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
             return 0;
         }
 
-        err = kvm_arch_remove_sw_breakpoint(current_cpu, bp);
+        err = kvm_arch_remove_sw_breakpoint(cpu, bp);
         if (err) {
             return err;
         }
 
-        QTAILQ_REMOVE(&current_cpu->kvm_state->kvm_sw_breakpoints, bp, entry);
+        QTAILQ_REMOVE(&cpu->kvm_state->kvm_sw_breakpoints, bp, entry);
         g_free(bp);
     } else {
         err = kvm_arch_remove_hw_breakpoint(addr, len, type);
@@ -1991,16 +1988,14 @@ 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(CPUArchState *env)
 {
-    CPUState *current_cpu = ENV_GET_CPU(current_env);
+    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp, *next;
-    KVMState *s = current_cpu->kvm_state;
-    CPUArchState *env;
-    CPUState *cpu;
+    KVMState *s = cpu->kvm_state;
 
     QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
-        if (kvm_arch_remove_sw_breakpoint(current_cpu, bp) != 0) {
+        if (kvm_arch_remove_sw_breakpoint(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);
@@ -2026,19 +2021,19 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return -EINVAL;
 }
 
-int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *current_env)
+void kvm_remove_all_breakpoints(CPUArchState *env)
 {
 }
 #endif /* !KVM_CAP_SET_GUEST_DEBUG */
diff --git a/kvm-stub.c b/kvm-stub.c
index dec7a83..583c636 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -83,19 +83,19 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return -ENOSYS;
 }
 
-int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *current_env)
+void kvm_remove_all_breakpoints(CPUArchState *env)
 {
 }
 
-- 
1.8.1.4


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

* [Qemu-devel] [PULL 05/43] kvm: Free current_cpu identifier
@ 2013-07-10 14:33   ` Andreas Färber
  0 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Andreas Färber, Gleb Natapov, open list:Overall

Since CPU loops are done as last step in kvm_{insert,remove}_breakpoint()
and kvm_remove_all_breakpoints(), we do not need to distinguish between
invoking CPU and iterated CPUs and can thereby free the identifier for
use as a global variable.

Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 include/sysemu/kvm.h | 10 +++++-----
 kvm-all.c            | 39 +++++++++++++++++----------------------
 kvm-stub.c           |  6 +++---
 3 files changed, 25 insertions(+), 30 deletions(-)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index a14cfe9..7596aca 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -169,11 +169,11 @@ void *kvm_arch_ram_alloc(ram_addr_t size);
 void kvm_setup_guest_memory(void *start, size_t size);
 void kvm_flush_coalesced_mmio_buffer(void);
 
-int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type);
-int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type);
-void kvm_remove_all_breakpoints(CPUArchState *current_env);
+void kvm_remove_all_breakpoints(CPUArchState *env);
 int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
 #ifndef _WIN32
 int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset);
@@ -252,9 +252,9 @@ struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *cpu,
 
 int kvm_sw_breakpoints_active(CPUState *cpu);
 
-int kvm_arch_insert_sw_breakpoint(CPUState *current_cpu,
+int kvm_arch_insert_sw_breakpoint(CPUState *cpu,
                                   struct kvm_sw_breakpoint *bp);
-int kvm_arch_remove_sw_breakpoint(CPUState *current_cpu,
+int kvm_arch_remove_sw_breakpoint(CPUState *cpu,
                                   struct kvm_sw_breakpoint *bp);
 int kvm_arch_insert_hw_breakpoint(target_ulong addr,
                                   target_ulong len, int type);
diff --git a/kvm-all.c b/kvm-all.c
index de658de..ed13d57 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1903,16 +1903,15 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return data.err;
 }
 
-int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
-    CPUState *current_cpu = ENV_GET_CPU(current_env);
+    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp;
-    CPUArchState *env;
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
-        bp = kvm_find_sw_breakpoint(current_cpu, addr);
+        bp = kvm_find_sw_breakpoint(cpu, addr);
         if (bp) {
             bp->use_count++;
             return 0;
@@ -1925,14 +1924,13 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
 
         bp->pc = addr;
         bp->use_count = 1;
-        err = kvm_arch_insert_sw_breakpoint(current_cpu, bp);
+        err = kvm_arch_insert_sw_breakpoint(cpu, bp);
         if (err) {
             g_free(bp);
             return err;
         }
 
-        QTAILQ_INSERT_HEAD(&current_cpu->kvm_state->kvm_sw_breakpoints,
-                          bp, entry);
+        QTAILQ_INSERT_HEAD(&cpu->kvm_state->kvm_sw_breakpoints, bp, entry);
     } else {
         err = kvm_arch_insert_hw_breakpoint(addr, len, type);
         if (err) {
@@ -1949,16 +1947,15 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
     return 0;
 }
 
-int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
-    CPUState *current_cpu = ENV_GET_CPU(current_env);
+    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp;
-    CPUArchState *env;
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
-        bp = kvm_find_sw_breakpoint(current_cpu, addr);
+        bp = kvm_find_sw_breakpoint(cpu, addr);
         if (!bp) {
             return -ENOENT;
         }
@@ -1968,12 +1965,12 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
             return 0;
         }
 
-        err = kvm_arch_remove_sw_breakpoint(current_cpu, bp);
+        err = kvm_arch_remove_sw_breakpoint(cpu, bp);
         if (err) {
             return err;
         }
 
-        QTAILQ_REMOVE(&current_cpu->kvm_state->kvm_sw_breakpoints, bp, entry);
+        QTAILQ_REMOVE(&cpu->kvm_state->kvm_sw_breakpoints, bp, entry);
         g_free(bp);
     } else {
         err = kvm_arch_remove_hw_breakpoint(addr, len, type);
@@ -1991,16 +1988,14 @@ 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(CPUArchState *env)
 {
-    CPUState *current_cpu = ENV_GET_CPU(current_env);
+    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp, *next;
-    KVMState *s = current_cpu->kvm_state;
-    CPUArchState *env;
-    CPUState *cpu;
+    KVMState *s = cpu->kvm_state;
 
     QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
-        if (kvm_arch_remove_sw_breakpoint(current_cpu, bp) != 0) {
+        if (kvm_arch_remove_sw_breakpoint(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);
@@ -2026,19 +2021,19 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return -EINVAL;
 }
 
-int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *current_env)
+void kvm_remove_all_breakpoints(CPUArchState *env)
 {
 }
 #endif /* !KVM_CAP_SET_GUEST_DEBUG */
diff --git a/kvm-stub.c b/kvm-stub.c
index dec7a83..583c636 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -83,19 +83,19 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return -ENOSYS;
 }
 
-int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *current_env)
+void kvm_remove_all_breakpoints(CPUArchState *env)
 {
 }
 
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 06/43] cpu: Replace cpu_single_env with CPUState current_cpu
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (4 preceding siblings ...)
  2013-07-10 14:33   ` [Qemu-devel] " Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33   ` [Qemu-devel] " Andreas Färber
                   ` (36 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 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                  | 41 ++++++++++++++++++++---------------------
 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       |  7 ++-----
 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  |  8 +++-----
 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, 120 insertions(+), 115 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index ec46380..503b103 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;
+    current_cpu = cpu;
 
-    /* As long as cpu_single_env is null, up to the assignment just above,
+    /* As long as current_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 current_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 = current_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 current_cpu outside cpu_exec() */
+    current_cpu = NULL;
     return ret;
 }
diff --git a/cpus.c b/cpus.c
index 20958e5..e9bfa71 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 = current_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 (current_cpu) {
+        cpu_exit(current_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 = current_cpu;
 
         qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex);
-        cpu_single_env = self_env;
+        current_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;
+    current_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;
+    current_cpu = cpu;
     while (1) {
-        cpu_single_env = NULL;
+        current_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;
+        current_cpu = cpu;
         qemu_wait_io_event_common(cpu);
     }
 
@@ -894,12 +895,11 @@ 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(current_cpu);
 
-    if (!cpu_single_cpu->thread_kicked) {
-        qemu_cpu_kick_thread(cpu_single_cpu);
-        cpu_single_cpu->thread_kicked = true;
+    if (!current_cpu->thread_kicked) {
+        qemu_cpu_kick_thread(current_cpu);
+        current_cpu->thread_kicked = true;
     }
 #else
     abort();
@@ -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 current_cpu && qemu_cpu_is_self(current_cpu);
 }
 
 void qemu_mutex_lock_iothread(void)
@@ -1069,11 +1069,10 @@ 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);
-        cpu_single_cpu->stop = false;
-        cpu_single_cpu->stopped = true;
-        cpu_exit(cpu_single_cpu);
+    if (current_cpu) {
+        current_cpu->stop = false;
+        current_cpu->stopped = true;
+        cpu_exit(current_cpu);
         qemu_cond_signal(&qemu_pause_cond);
     }
 }
diff --git a/exec.c b/exec.c
index 03fdf7e..9ca80cc 100644
--- a/exec.c
+++ b/exec.c
@@ -72,7 +72,7 @@ static MemoryRegion io_mem_unassigned;
 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 *, current_cpu);
 /* 0 = Do not count executed instructions.
    1 = Precise instruction counting.
    2 = Adaptive rate instruction counting.  */
@@ -1472,8 +1472,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 = current_cpu->env_ptr;
+        tlb_set_dirty(env, env->mem_io_vaddr);
+    }
 }
 
 static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
@@ -1491,7 +1493,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 = current_cpu->env_ptr;
     target_ulong pc, cs_base;
     target_ulong vaddr;
     CPUWatchpoint *wp;
@@ -1930,7 +1932,7 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
         if (is_write) {
             if (!memory_access_is_direct(mr, is_write)) {
                 l = memory_access_size(mr, l, addr1);
-                /* XXX: could force cpu_single_env to NULL to avoid
+                /* XXX: could force current_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 63cc2cb..1c3ac8e 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 = current_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,7 +195,6 @@ 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);
         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(current_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) {
@@ -465,7 +459,7 @@ static void cchip_write(void *opaque, hwaddr addr,
         break;
 
     default:
-        cpu_unassigned_access(cpu_single_cpu, addr, true, false, 0, size);
+        cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
         return;
     }
 }
@@ -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(current_cpu, addr, true, false, 0, size);
         return;
     }
 }
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 5a22654..3c520d7 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(current_cpu, CPU_INTERRUPT_HALT);
 
         goto message;
 
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 9850a85..e13678f 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -624,11 +624,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 = current_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 e00f9dc..5224256 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -886,8 +886,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 (current_cpu) {
+        X86CPU *cpu = X86_CPU(current_cpu);
+        return cpu->env.apic_state;
     } else {
         return NULL;
     }
@@ -1176,10 +1177,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 = current_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 b59df06..237d1d6 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 current_cpu->cpu_index;
     }
     return 0;
 }
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 2a57f77..178344b 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(current_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(current_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(current_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 937e292..d984dba 100644
--- a/hw/intc/openpic.c
+++ b/hw/intc/openpic.c
@@ -180,14 +180,11 @@ static int output_to_inttgt(int output)
 
 static int get_current_cpu(void)
 {
-    CPUState *cpu_single_cpu;
-
-    if (!cpu_single_env) {
+    if (!current_cpu) {
         return -1;
     }
 
-    cpu_single_cpu = ENV_GET_CPU(cpu_single_env);
-    return cpu_single_cpu->cpu_index;
+    return current_cpu->cpu_index;
 }
 
 static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index 03e44d5..9e305d2 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -250,10 +250,10 @@ static void network_init (PCIBus *pci_bus)
 
 static void cpu_request_exit(void *opaque, int irq, int level)
 {
-    CPUMIPSState *env = cpu_single_env;
+    CPUState *cpu = current_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 3eac63b..31e138b 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 = current_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 ceadc72..7e56121 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 = current_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 7463776..0b5a564 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 = current_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(current_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(current_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(current_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(current_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(current_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 2e2f2eb..a10abe9 100644
--- a/hw/ppc/mpc8544_guts.c
+++ b/hw/ppc/mpc8544_guts.c
@@ -68,7 +68,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(current_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 7b2559d..d07dd01 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 = current_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 90b7b60..7a0c1ab 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 && current_cpu) {
+        cpu_interrupt(current_cpu, CPU_INTERRUPT_HALT);
     }
 }
 
diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
index d23462d..fbc69c9 100644
--- a/hw/timer/arm_mptimer.c
+++ b/hw/timer/arm_mptimer.c
@@ -49,13 +49,11 @@ 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) {
+    if (current_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);
+                 s->num_cpu, current_cpu->cpu_index);
     }
-    return cpu_single_cpu->cpu_index;
+    return current_cpu->cpu_index;
 }
 
 static inline void timerblock_update_irq(TimerBlock *tb)
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 7cb5e54..d7fc186 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 *, current_cpu);
+#define current_cpu tls_var(current_cpu)
+
 /**
  * cpu_paging_enabled:
  * @cpu: The CPU whose state is to be inspected.
diff --git a/memory.c b/memory.c
index 35553b5..c8f9a2b 100644
--- a/memory.c
+++ b/memory.c
@@ -838,9 +838,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 (current_cpu != NULL) {
+        cpu_unassigned_access(current_cpu, addr, false, false, 0, size);
     }
     return 0;
 }
@@ -851,9 +850,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 (current_cpu != NULL) {
+        cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
     }
 }
 
diff --git a/translate-all.c b/translate-all.c
index 9acb2b1..02f8e5e 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 = current_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 = current_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..26cde7c 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 = current_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] 53+ messages in thread

* [PULL 07/43] kvm: Change kvm_remove_all_breakpoints() argument to CPUState
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
@ 2013-07-10 14:33   ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 02/43] Revert "gdbstub: Simplify find_cpu()" Andreas Färber
                     ` (41 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Andreas Färber, Gleb Natapov, Paolo Bonzini, open list:Overall

Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c            | 2 +-
 include/sysemu/kvm.h | 2 +-
 kvm-all.c            | 6 +++---
 kvm-stub.c           | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 9ae6576..f7d9f13 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 7596aca..1e08a85 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -173,7 +173,7 @@ int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type);
 int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type);
-void kvm_remove_all_breakpoints(CPUArchState *env);
+void kvm_remove_all_breakpoints(CPUState *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 ed13d57..2c14ef3 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1988,11 +1988,11 @@ int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
     return 0;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *env)
+void kvm_remove_all_breakpoints(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp, *next;
     KVMState *s = cpu->kvm_state;
+    CPUArchState *env;
 
     QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
         if (kvm_arch_remove_sw_breakpoint(cpu, bp) != 0) {
@@ -2033,7 +2033,7 @@ int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *env)
+void kvm_remove_all_breakpoints(CPUState *cpu)
 {
 }
 #endif /* !KVM_CAP_SET_GUEST_DEBUG */
diff --git a/kvm-stub.c b/kvm-stub.c
index 583c636..370c837 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -95,7 +95,7 @@ int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *env)
+void kvm_remove_all_breakpoints(CPUState *cpu)
 {
 }
 
-- 
1.8.1.4


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

* [Qemu-devel] [PULL 07/43] kvm: Change kvm_remove_all_breakpoints() argument to CPUState
@ 2013-07-10 14:33   ` Andreas Färber
  0 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Andreas Färber, Gleb Natapov, open list:Overall

Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 gdbstub.c            | 2 +-
 include/sysemu/kvm.h | 2 +-
 kvm-all.c            | 6 +++---
 kvm-stub.c           | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 9ae6576..f7d9f13 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 7596aca..1e08a85 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -173,7 +173,7 @@ int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type);
 int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type);
-void kvm_remove_all_breakpoints(CPUArchState *env);
+void kvm_remove_all_breakpoints(CPUState *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 ed13d57..2c14ef3 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1988,11 +1988,11 @@ int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
     return 0;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *env)
+void kvm_remove_all_breakpoints(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp, *next;
     KVMState *s = cpu->kvm_state;
+    CPUArchState *env;
 
     QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
         if (kvm_arch_remove_sw_breakpoint(cpu, bp) != 0) {
@@ -2033,7 +2033,7 @@ int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *env)
+void kvm_remove_all_breakpoints(CPUState *cpu)
 {
 }
 #endif /* !KVM_CAP_SET_GUEST_DEBUG */
diff --git a/kvm-stub.c b/kvm-stub.c
index 583c636..370c837 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -95,7 +95,7 @@ int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *env)
+void kvm_remove_all_breakpoints(CPUState *cpu)
 {
 }
 
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 08/43] linux-user: Clean up do_syscall() Coding Style for TARGET_NR_exit
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (6 preceding siblings ...)
  2013-07-10 14:33   ` [Qemu-devel] " Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33   ` [Qemu-devel] " Andreas Färber
                   ` (34 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio, Andreas Färber

In particular fix 6-/10-char indentation.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 linux-user/syscall.c | 73 ++++++++++++++++++++++++++--------------------------
 1 file changed, 37 insertions(+), 36 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index cdd0c28..a2125fa 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5044,42 +5044,43 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     switch(num) {
     case TARGET_NR_exit:
 #ifdef CONFIG_USE_NPTL
-      /* In old applications this may be used to implement _exit(2).
-         However in threaded applictions it is used for thread termination,
-         and _exit_group is used for application termination.
-         Do thread termination if we have more then one thread.  */
-      /* FIXME: This probably breaks if a signal arrives.  We should probably
-         be disabling signals.  */
-      if (first_cpu->next_cpu) {
-          TaskState *ts;
-          CPUArchState **lastp;
-          CPUArchState *p;
-
-          cpu_list_lock();
-          lastp = &first_cpu;
-          p = first_cpu;
-          while (p && p != (CPUArchState *)cpu_env) {
-              lastp = &p->next_cpu;
-              p = p->next_cpu;
-          }
-          /* If we didn't find the CPU for this thread then something is
-             horribly wrong.  */
-          if (!p)
-              abort();
-          /* Remove the CPU from the list.  */
-          *lastp = p->next_cpu;
-          cpu_list_unlock();
-          ts = ((CPUArchState *)cpu_env)->opaque;
-          if (ts->child_tidptr) {
-              put_user_u32(0, ts->child_tidptr);
-              sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
-                        NULL, NULL, 0);
-          }
-          thread_env = NULL;
-          object_unref(OBJECT(ENV_GET_CPU(cpu_env)));
-          g_free(ts);
-          pthread_exit(NULL);
-      }
+        /* In old applications this may be used to implement _exit(2).
+           However in threaded applictions it is used for thread termination,
+           and _exit_group is used for application termination.
+           Do thread termination if we have more then one thread.  */
+        /* FIXME: This probably breaks if a signal arrives.  We should probably
+           be disabling signals.  */
+        if (first_cpu->next_cpu) {
+            TaskState *ts;
+            CPUArchState **lastp;
+            CPUArchState *p;
+
+            cpu_list_lock();
+            lastp = &first_cpu;
+            p = first_cpu;
+            while (p && p != (CPUArchState *)cpu_env) {
+                lastp = &p->next_cpu;
+                p = p->next_cpu;
+            }
+            /* If we didn't find the CPU for this thread then something is
+               horribly wrong.  */
+            if (!p) {
+                abort();
+            }
+            /* Remove the CPU from the list.  */
+            *lastp = p->next_cpu;
+            cpu_list_unlock();
+            ts = ((CPUArchState *)cpu_env)->opaque;
+            if (ts->child_tidptr) {
+                put_user_u32(0, ts->child_tidptr);
+                sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
+                          NULL, NULL, 0);
+            }
+            thread_env = NULL;
+            object_unref(OBJECT(ENV_GET_CPU(cpu_env)));
+            g_free(ts);
+            pthread_exit(NULL);
+        }
 #endif
 #ifdef TARGET_GPROF
         _mcleanup();
-- 
1.8.1.4

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

* [PULL 09/43] cpu: Make first_cpu and next_cpu CPUState
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
@ 2013-07-10 14:33   ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 02/43] Revert "gdbstub: Simplify find_cpu()" Andreas Färber
                     ` (41 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 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, Scott Wood, Andreas Färber,
	Gleb Natapov, Paolo Bonzini, Riku Voipio, Luiz Capitulino,
	Marcelo Tosatti, open list:e500

Move next_cpu from CPU_COMMON to CPUState.
Move first_cpu variable to qom/cpu.h.

gdbstub needs to use CPUState::env_ptr for now.
cpu_copy() no longer needs to save and restore cpu_next.

Acked-by: Paolo Bonzini <pbonzini@redhat.com>
[AF: Rebased, simplified cpu_copy()]
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c                    | 126 ++++++++++++++++++++++++----------------------
 cputlb.c                  |   4 +-
 dump.c                    |  16 +++---
 exec.c                    |  43 ++++++++--------
 gdbstub.c                 |  39 ++++++++------
 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/e500.c             |   5 +-
 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                 |  16 +++---
 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 +++--
 39 files changed, 266 insertions(+), 234 deletions(-)

diff --git a/cpus.c b/cpus.c
index e9bfa71..f141428 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 828007c..977c0ca 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -186,11 +186,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 c812cfa..6a3a72a 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 9ca80cc..61b094a 100644
--- a/exec.c
+++ b/exec.c
@@ -69,7 +69,7 @@ static MemoryRegion io_mem_unassigned;
 
 #endif
 
-CPUArchState *first_cpu;
+CPUState *first_cpu;
 /* current CPU in the current thread. It is only valid inside
    cpu_exec() */
 DEFINE_TLS(CPUState *, current_cpu);
@@ -351,27 +351,26 @@ 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;
     }
 }
 
@@ -379,17 +378,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;
@@ -399,7 +398,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
@@ -638,7 +637,6 @@ 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;
 #if defined(TARGET_HAS_ICE)
     CPUBreakpoint *bp;
     CPUWatchpoint *wp;
@@ -646,9 +644,6 @@ CPUArchState *cpu_copy(CPUArchState *env)
 
     memcpy(new_env, env, sizeof(CPUArchState));
 
-    /* Preserve chaining. */
-    new_env->next_cpu = next_cpu;
-
     /* Clone all break/watchpoints.
        Note: Once we support ptrace with hw-debug register access, make sure
        BP_CPU break/watchpoints are handled correctly on clone. */
@@ -1757,12 +1752,14 @@ static void core_commit(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 f7d9f13..0ee82a9 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);
@@ -2071,13 +2080,11 @@ 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);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         if (cpu_index(cpu) == thread_id) {
-            return env;
+            return cpu->env_ptr;
         }
     }
 
@@ -2394,7 +2401,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:
@@ -2402,7 +2409,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;
@@ -2869,8 +2876,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;
 
@@ -3054,8 +3061,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 7c0090f..2b33444 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -333,7 +333,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) {
@@ -351,7 +351,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;
@@ -476,9 +476,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 de6c98a..3a2fb4c 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 b596256..3060f48 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -331,7 +331,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 710413e..fd18b60 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 0dc0871..3444823 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 98e5ca5..1022d67 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -33,7 +33,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;
 
@@ -53,8 +53,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));
@@ -124,9 +124,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 e13678f..ccd089a 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);
     }
 }
 
@@ -719,8 +721,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)
@@ -743,7 +746,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 5224256..c5d8570 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 {
@@ -1274,8 +1278,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 01323a9..b58c255 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -229,8 +229,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 f397950..55c76e4 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 b49be4d..d1921aa 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 7e56121..de87241 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/e500.c b/hw/ppc/e500.c
index 69837a5..9600599 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -500,7 +500,6 @@ static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
                                           qemu_irq **irqs)
 {
     DeviceState *dev;
-    CPUPPCState *env;
     CPUState *cs;
     int r;
 
@@ -512,9 +511,7 @@ static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
         return NULL;
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cs = ENV_GET_CPU(env);
-
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
         if (kvm_openpic_connect_vcpu(dev, cs)) {
             fprintf(stderr, "%s: failed to connect vcpu to irqchip\n",
                     __func__);
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 d07dd01..19f2442 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -605,8 +605,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));
@@ -651,7 +652,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];
 
     portio_list_init(port_list, NULL, prep_portio_list, sysctrl, "prep");
     portio_list_add(port_list, get_system_io(), 0x0);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index c040794..e46aad3 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 d7fc186..a08a8ab 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 *, current_cpu);
 #define current_cpu tls_var(current_cpu)
 
diff --git a/kvm-all.c b/kvm-all.c
index 2c14ef3..c130705 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1938,7 +1938,9 @@ int kvm_insert_breakpoint(CPUArchState *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;
@@ -1979,7 +1981,9 @@ int kvm_remove_breakpoint(CPUArchState *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;
@@ -1992,13 +1996,11 @@ void kvm_remove_all_breakpoints(CPUState *cpu)
 {
     struct kvm_sw_breakpoint *bp, *next;
     KVMState *s = cpu->kvm_state;
-    CPUArchState *env;
 
     QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
         if (kvm_arch_remove_sw_breakpoint(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;
                 }
@@ -2009,7 +2011,9 @@ void kvm_remove_all_breakpoints(CPUState *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 af82db8..564bed6 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 a2125fa..4c96f4f 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 4b557b3..935ef63 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) == NULL ||
-            !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 e95ad4a..b0099e1 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1579,7 +1579,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 02f8e5e..e8683d2 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] 53+ messages in thread

* [Qemu-devel] [PULL 09/43] cpu: Make first_cpu and next_cpu CPUState
@ 2013-07-10 14:33   ` Andreas Färber
  0 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Evgeny Voevodin, Luiz Capitulino,
	Peter Crosthwaite, Edgar E. Iglesias, Igor Mitsyanko,
	Gleb Natapov, Alexander Graf, Andreas Färber, Maksim Kozlov,
	Riku Voipio, Paul Brook, open list:Overall, Scott Wood,
	Anthony Liguori, Mark Langsdorf, Marcelo Tosatti, open list:e500,
	Dmitry Solodkiy, Paolo Bonzini, Andreas Färber,
	Aurelien Jarno

Move next_cpu from CPU_COMMON to CPUState.
Move first_cpu variable to qom/cpu.h.

gdbstub needs to use CPUState::env_ptr for now.
cpu_copy() no longer needs to save and restore cpu_next.

Acked-by: Paolo Bonzini <pbonzini@redhat.com>
[AF: Rebased, simplified cpu_copy()]
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpus.c                    | 126 ++++++++++++++++++++++++----------------------
 cputlb.c                  |   4 +-
 dump.c                    |  16 +++---
 exec.c                    |  43 ++++++++--------
 gdbstub.c                 |  39 ++++++++------
 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/e500.c             |   5 +-
 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                 |  16 +++---
 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 +++--
 39 files changed, 266 insertions(+), 234 deletions(-)

diff --git a/cpus.c b/cpus.c
index e9bfa71..f141428 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 828007c..977c0ca 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -186,11 +186,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 c812cfa..6a3a72a 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 9ca80cc..61b094a 100644
--- a/exec.c
+++ b/exec.c
@@ -69,7 +69,7 @@ static MemoryRegion io_mem_unassigned;
 
 #endif
 
-CPUArchState *first_cpu;
+CPUState *first_cpu;
 /* current CPU in the current thread. It is only valid inside
    cpu_exec() */
 DEFINE_TLS(CPUState *, current_cpu);
@@ -351,27 +351,26 @@ 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;
     }
 }
 
@@ -379,17 +378,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;
@@ -399,7 +398,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
@@ -638,7 +637,6 @@ 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;
 #if defined(TARGET_HAS_ICE)
     CPUBreakpoint *bp;
     CPUWatchpoint *wp;
@@ -646,9 +644,6 @@ CPUArchState *cpu_copy(CPUArchState *env)
 
     memcpy(new_env, env, sizeof(CPUArchState));
 
-    /* Preserve chaining. */
-    new_env->next_cpu = next_cpu;
-
     /* Clone all break/watchpoints.
        Note: Once we support ptrace with hw-debug register access, make sure
        BP_CPU break/watchpoints are handled correctly on clone. */
@@ -1757,12 +1752,14 @@ static void core_commit(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 f7d9f13..0ee82a9 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);
@@ -2071,13 +2080,11 @@ 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);
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
         if (cpu_index(cpu) == thread_id) {
-            return env;
+            return cpu->env_ptr;
         }
     }
 
@@ -2394,7 +2401,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:
@@ -2402,7 +2409,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;
@@ -2869,8 +2876,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;
 
@@ -3054,8 +3061,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 7c0090f..2b33444 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -333,7 +333,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) {
@@ -351,7 +351,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;
@@ -476,9 +476,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 de6c98a..3a2fb4c 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 b596256..3060f48 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -331,7 +331,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 710413e..fd18b60 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 0dc0871..3444823 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 98e5ca5..1022d67 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -33,7 +33,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;
 
@@ -53,8 +53,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));
@@ -124,9 +124,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 e13678f..ccd089a 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);
     }
 }
 
@@ -719,8 +721,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)
@@ -743,7 +746,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 5224256..c5d8570 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 {
@@ -1274,8 +1278,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 01323a9..b58c255 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -229,8 +229,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 f397950..55c76e4 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 b49be4d..d1921aa 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 7e56121..de87241 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/e500.c b/hw/ppc/e500.c
index 69837a5..9600599 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -500,7 +500,6 @@ static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
                                           qemu_irq **irqs)
 {
     DeviceState *dev;
-    CPUPPCState *env;
     CPUState *cs;
     int r;
 
@@ -512,9 +511,7 @@ static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
         return NULL;
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        cs = ENV_GET_CPU(env);
-
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
         if (kvm_openpic_connect_vcpu(dev, cs)) {
             fprintf(stderr, "%s: failed to connect vcpu to irqchip\n",
                     __func__);
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 d07dd01..19f2442 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -605,8 +605,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));
@@ -651,7 +652,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];
 
     portio_list_init(port_list, NULL, prep_portio_list, sysctrl, "prep");
     portio_list_add(port_list, get_system_io(), 0x0);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index c040794..e46aad3 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 d7fc186..a08a8ab 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 *, current_cpu);
 #define current_cpu tls_var(current_cpu)
 
diff --git a/kvm-all.c b/kvm-all.c
index 2c14ef3..c130705 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1938,7 +1938,9 @@ int kvm_insert_breakpoint(CPUArchState *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;
@@ -1979,7 +1981,9 @@ int kvm_remove_breakpoint(CPUArchState *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;
@@ -1992,13 +1996,11 @@ void kvm_remove_all_breakpoints(CPUState *cpu)
 {
     struct kvm_sw_breakpoint *bp, *next;
     KVMState *s = cpu->kvm_state;
-    CPUArchState *env;
 
     QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
         if (kvm_arch_remove_sw_breakpoint(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;
                 }
@@ -2009,7 +2011,9 @@ void kvm_remove_all_breakpoints(CPUState *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 af82db8..564bed6 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 a2125fa..4c96f4f 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 4b557b3..935ef63 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) == NULL ||
-            !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 e95ad4a..b0099e1 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1579,7 +1579,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 02f8e5e..e8683d2 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] 53+ messages in thread

* [Qemu-devel] [PULL 10/43] linux-user: Change thread_env to CPUState
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (8 preceding siblings ...)
  2013-07-10 14:33   ` [Qemu-devel] " Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 11/43] bsd-user: " Andreas Färber
                   ` (32 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 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 564bed6..67ea9ba 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 20d171c..6569608 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -198,7 +198,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 4c96f4f..433d3ba 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);
@@ -5079,7 +5079,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] 53+ messages in thread

* [Qemu-devel] [PULL 11/43] bsd-user: Change thread_env to CPUState
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (9 preceding siblings ...)
  2013-07-10 14:33 ` [Qemu-devel] [PULL 10/43] linux-user: Change thread_env to CPUState Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 12/43] intc/arm_gic: Build arm_gic only once Andreas Färber
                   ` (31 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 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 75dbd7f..1e92552 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] 53+ messages in thread

* [Qemu-devel] [PULL 12/43] intc/arm_gic: Build arm_gic only once
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (10 preceding siblings ...)
  2013-07-10 14:33 ` [Qemu-devel] [PULL 11/43] bsd-user: " Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 13/43] intc/openpic: Build openpic " Andreas Färber
                   ` (30 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Since current_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 2ba49d0..e8f9267 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -10,9 +10,9 @@ 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
 
 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 237d1d6..8e34004 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] 53+ messages in thread

* [Qemu-devel] [PULL 13/43] intc/openpic: Build openpic only once
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (11 preceding siblings ...)
  2013-07-10 14:33 ` [Qemu-devel] [PULL 12/43] intc/arm_gic: Build arm_gic only once Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 14/43] timer/arm_mptimer: Build arm_mptimer " Andreas Färber
                   ` (29 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: open list:PowerPC, Andreas Färber, Alexander Graf

Since current_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.

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 e8f9267..86f9d5b 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -11,6 +11,7 @@ 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_OPENPIC) += openpic.o
 
 obj-$(CONFIG_APIC) += apic.o apic_common.o
 obj-$(CONFIG_ARM_GIC_KVM) += arm_gic_kvm.o
@@ -19,6 +20,5 @@ 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
 obj-$(CONFIG_OPENPIC_KVM) += openpic_kvm.o
 obj-$(CONFIG_SH4) += sh_intc.o
diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c
index d984dba..7df72f4 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 dfcad25..132ab97 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] 53+ messages in thread

* [Qemu-devel] [PULL 14/43] timer/arm_mptimer: Build arm_mptimer only once
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (12 preceding siblings ...)
  2013-07-10 14:33 ` [Qemu-devel] [PULL 13/43] intc/openpic: Build openpic " Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 15/43] target-ppc: Don't overuse ENV_GET_CPU() Andreas Färber
                   ` (28 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Since current_cpu is CPUState it no longer depends on CPUARMState.

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 fbc69c9..0ceb240 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] 53+ messages in thread

* [Qemu-devel] [PULL 15/43] target-ppc: Don't overuse ENV_GET_CPU()
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (13 preceding siblings ...)
  2013-07-10 14:33 ` [Qemu-devel] [PULL 14/43] timer/arm_mptimer: Build arm_mptimer " Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33   ` [Qemu-devel] " Andreas Färber
                   ` (27 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: open list:PowerPC, Andreas Färber, Alexander Graf

Commit b632a148b677b773ff155f9de840b37a653567b9 (target-ppc: QOM method
dispatch for MMU fault handling) introduced a use of ENV_GET_CPU()
inside target-ppc/ code. Use ppc_env_get_cpu() instead.

Purely cosmetic, non-functional change to aid in locating and removing
ENV_GET_CPU() usages.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-ppc/mmu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 385b67a..e4e111c 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -2890,7 +2890,7 @@ void helper_booke206_tlbflush(CPUPPCState *env, uint32_t type)
 void tlb_fill(CPUPPCState *env, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
+    CPUState *cpu = CPU(ppc_env_get_cpu(env));
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
     int ret;
 
-- 
1.8.1.4

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

* [PULL 16/43] target-s390x: Don't overuse ENV_GET_CPU()
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
@ 2013-07-10 14:33   ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 02/43] Revert "gdbstub: Simplify find_cpu()" Andreas Färber
                     ` (41 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Andreas Färber, Jason J. Herne, Alexander Graf,
	Richard Henderson, Gleb Natapov, Paolo Bonzini,
	open list:Overall

Commit 3474b679486caa8f6448bae974e131370f360c13 (Utilize selective
runtime reg sync for hot code paths) introduced two uses of
ENV_GET_CPU() inside target-s390x/ KVM code. In one case we can use a
direct CPU() cast instead.

Cc: Jason J. Herne <jjherne@us.ibm.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-s390x/kvm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 42f758f..af499cf 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -469,7 +469,7 @@ static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run,
     int r = 0;
     int no_cc = 0;
     CPUS390XState *env = &cpu->env;
-    CPUState *cs = ENV_GET_CPU(env);
+    CPUState *cs = CPU(cpu);
 
     if (ipa0 != 0xb2) {
         /* Not handled for now. */
-- 
1.8.1.4


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

* [Qemu-devel] [PULL 16/43] target-s390x: Don't overuse ENV_GET_CPU()
@ 2013-07-10 14:33   ` Andreas Färber
  0 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: open list:Overall, Gleb Natapov, Alexander Graf, Jason J. Herne,
	Paolo Bonzini, Andreas Färber, Richard Henderson

Commit 3474b679486caa8f6448bae974e131370f360c13 (Utilize selective
runtime reg sync for hot code paths) introduced two uses of
ENV_GET_CPU() inside target-s390x/ KVM code. In one case we can use a
direct CPU() cast instead.

Cc: Jason J. Herne <jjherne@us.ibm.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-s390x/kvm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 42f758f..af499cf 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -469,7 +469,7 @@ static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run,
     int r = 0;
     int no_cc = 0;
     CPUS390XState *env = &cpu->env;
-    CPUState *cs = ENV_GET_CPU(env);
+    CPUState *cs = CPU(cpu);
 
     if (ipa0 != 0xb2) {
         /* Not handled for now. */
-- 
1.8.1.4

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

* [PULL 17/43] target-s390x: Change handle_{hypercall,diag}() argument to S390CPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
@ 2013-07-10 14:33   ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 02/43] Revert "gdbstub: Simplify find_cpu()" Andreas Färber
                     ` (41 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Andreas Färber, Jason J. Herne, Alexander Graf,
	Richard Henderson, Gleb Natapov, Paolo Bonzini,
	open list:Overall

This allows to get rid of the last remaining ENV_GET_CPU() in
target-s390x/ by using CPU() cast directly on the argument.

Cc: Jason J. Herne <jjherne@us.ibm.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-s390x/kvm.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index af499cf..60e94f8 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -607,9 +607,10 @@ static int handle_priv(S390CPU *cpu, struct kvm_run *run,
     return r;
 }
 
-static int handle_hypercall(CPUS390XState *env, struct kvm_run *run)
+static int handle_hypercall(S390CPU *cpu, struct kvm_run *run)
 {
-    CPUState *cs = ENV_GET_CPU(env);
+    CPUState *cs = CPU(cpu);
+    CPUS390XState *env = &cpu->env;
 
     kvm_s390_get_registers_partial(cs);
     cs->kvm_vcpu_dirty = true;
@@ -618,13 +619,13 @@ static int handle_hypercall(CPUS390XState *env, struct kvm_run *run)
     return 0;
 }
 
-static int handle_diag(CPUS390XState *env, struct kvm_run *run, int ipb_code)
+static int handle_diag(S390CPU *cpu, struct kvm_run *run, int ipb_code)
 {
     int r = 0;
 
     switch (ipb_code) {
         case DIAG_KVM_HYPERCALL:
-            r = handle_hypercall(env, run);
+            r = handle_hypercall(cpu, run);
             break;
         case DIAG_KVM_BREAKPOINT:
             sleep(10);
@@ -735,7 +736,6 @@ out:
 
 static int handle_instruction(S390CPU *cpu, struct kvm_run *run)
 {
-    CPUS390XState *env = &cpu->env;
     unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
     uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
     int ipb_code = (run->s390_sieic.ipb & 0x0fff0000) >> 16;
@@ -749,7 +749,7 @@ static int handle_instruction(S390CPU *cpu, struct kvm_run *run)
         r = handle_priv(cpu, run, ipa0 >> 8, ipa1);
         break;
     case IPA0_DIAG:
-        r = handle_diag(env, run, ipb_code);
+        r = handle_diag(cpu, run, ipb_code);
         break;
     case IPA0_SIGP:
         r = handle_sigp(cpu, run, ipa1);
-- 
1.8.1.4


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

* [Qemu-devel] [PULL 17/43] target-s390x: Change handle_{hypercall, diag}() argument to S390CPU
@ 2013-07-10 14:33   ` Andreas Färber
  0 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: open list:Overall, Gleb Natapov, Alexander Graf, Jason J. Herne,
	Paolo Bonzini, Andreas Färber, Richard Henderson

This allows to get rid of the last remaining ENV_GET_CPU() in
target-s390x/ by using CPU() cast directly on the argument.

Cc: Jason J. Herne <jjherne@us.ibm.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-s390x/kvm.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index af499cf..60e94f8 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -607,9 +607,10 @@ static int handle_priv(S390CPU *cpu, struct kvm_run *run,
     return r;
 }
 
-static int handle_hypercall(CPUS390XState *env, struct kvm_run *run)
+static int handle_hypercall(S390CPU *cpu, struct kvm_run *run)
 {
-    CPUState *cs = ENV_GET_CPU(env);
+    CPUState *cs = CPU(cpu);
+    CPUS390XState *env = &cpu->env;
 
     kvm_s390_get_registers_partial(cs);
     cs->kvm_vcpu_dirty = true;
@@ -618,13 +619,13 @@ static int handle_hypercall(CPUS390XState *env, struct kvm_run *run)
     return 0;
 }
 
-static int handle_diag(CPUS390XState *env, struct kvm_run *run, int ipb_code)
+static int handle_diag(S390CPU *cpu, struct kvm_run *run, int ipb_code)
 {
     int r = 0;
 
     switch (ipb_code) {
         case DIAG_KVM_HYPERCALL:
-            r = handle_hypercall(env, run);
+            r = handle_hypercall(cpu, run);
             break;
         case DIAG_KVM_BREAKPOINT:
             sleep(10);
@@ -735,7 +736,6 @@ out:
 
 static int handle_instruction(S390CPU *cpu, struct kvm_run *run)
 {
-    CPUS390XState *env = &cpu->env;
     unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
     uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
     int ipb_code = (run->s390_sieic.ipb & 0x0fff0000) >> 16;
@@ -749,7 +749,7 @@ static int handle_instruction(S390CPU *cpu, struct kvm_run *run)
         r = handle_priv(cpu, run, ipa0 >> 8, ipa1);
         break;
     case IPA0_DIAG:
-        r = handle_diag(env, run, ipb_code);
+        r = handle_diag(cpu, run, ipb_code);
         break;
     case IPA0_SIGP:
         r = handle_sigp(cpu, run, ipa1);
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 18/43] target-i386: Don't overuse CPUArchState
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (16 preceding siblings ...)
  2013-07-10 14:33   ` [Qemu-devel] [PULL 17/43] target-s390x: Change handle_{hypercall, diag}() " Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 19/43] target-cris: gen_intermediate_code_internal() should be inlined Andreas Färber
                   ` (24 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Use CPUX86State instead in dump support code.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-i386/arch_dump.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
index d133228..10dc228 100644
--- a/target-i386/arch_dump.c
+++ b/target-i386/arch_dump.c
@@ -35,7 +35,7 @@ typedef struct {
 } x86_64_elf_prstatus;
 
 static int x86_64_write_elf64_note(WriteCoreDumpFunction f,
-                                   CPUArchState *env, int id,
+                                   CPUX86State *env, int id,
                                    void *opaque)
 {
     x86_64_user_regs_struct regs;
@@ -119,7 +119,7 @@ typedef struct {
     char pad3[4];
 } x86_elf_prstatus;
 
-static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUArchState *env,
+static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUX86State *env,
                                   int id)
 {
     memset(prstatus, 0, sizeof(x86_elf_prstatus));
@@ -144,7 +144,7 @@ static void x86_fill_elf_prstatus(x86_elf_prstatus *prstatus, CPUArchState *env,
     prstatus->pid = id;
 }
 
-static int x86_write_elf64_note(WriteCoreDumpFunction f, CPUArchState *env,
+static int x86_write_elf64_note(WriteCoreDumpFunction f, CPUX86State *env,
                                 int id, void *opaque)
 {
     x86_elf_prstatus prstatus;
@@ -274,7 +274,7 @@ static void copy_segment(QEMUCPUSegment *d, SegmentCache *s)
     d->base = s->base;
 }
 
-static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env)
+static void qemu_get_cpustate(QEMUCPUState *s, CPUX86State *env)
 {
     memset(s, 0, sizeof(QEMUCPUState));
 
@@ -321,7 +321,7 @@ static void qemu_get_cpustate(QEMUCPUState *s, CPUArchState *env)
 }
 
 static inline int cpu_write_qemu_note(WriteCoreDumpFunction f,
-                                      CPUArchState *env,
+                                      CPUX86State *env,
                                       void *opaque,
                                       int type)
 {
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 19/43] target-cris: gen_intermediate_code_internal() should be inlined
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (17 preceding siblings ...)
  2013-07-10 14:33 ` [Qemu-devel] [PULL 18/43] target-i386: Don't overuse CPUArchState Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 20/43] target-lm32: " Andreas Färber
                   ` (23 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Edgar E. Iglesias, Andreas Färber, qemu-stable

Cc: qemu-stable@nongnu.org
Reported-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-cris/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-cris/translate.c b/target-cris/translate.c
index 09d0d2b..ee9ae22 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3161,7 +3161,7 @@ static void check_breakpoint(CPUCRISState *env, DisasContext *dc)
  */
 
 /* generate intermediate code for basic block 'tb'.  */
-static void
+static inline void
 gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
                                int search_pc)
 {
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 20/43] target-lm32: gen_intermediate_code_internal() should be inlined
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (18 preceding siblings ...)
  2013-07-10 14:33 ` [Qemu-devel] [PULL 19/43] target-cris: gen_intermediate_code_internal() should be inlined Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 21/43] target-microblaze: " Andreas Färber
                   ` (22 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle, Andreas Färber, qemu-stable

Cc: qemu-stable@nongnu.org
Reported-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Acked-by: Michael Walle <michael@walle.cc>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-lm32/translate.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 227a801..7d82dc7 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1011,8 +1011,9 @@ static void check_breakpoint(CPULM32State *env, DisasContext *dc)
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-static void gen_intermediate_code_internal(CPULM32State *env,
-        TranslationBlock *tb, int search_pc)
+static inline
+void gen_intermediate_code_internal(CPULM32State *env,
+                                    TranslationBlock *tb, int search_pc)
 {
     struct DisasContext ctx, *dc = &ctx;
     uint16_t *gen_opc_end;
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 21/43] target-microblaze: gen_intermediate_code_internal() should be inlined
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (19 preceding siblings ...)
  2013-07-10 14:33 ` [Qemu-devel] [PULL 20/43] target-lm32: " Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:33 ` [Qemu-devel] [PULL 22/43] target-moxie: " Andreas Färber
                   ` (21 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Edgar E. Iglesias, Andreas Färber, qemu-stable

Cc: qemu-stable@nongnu.org
Reported-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-microblaze/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 54f439f..27da4bf 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1737,7 +1737,7 @@ static void check_breakpoint(CPUMBState *env, DisasContext *dc)
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-static void
+static inline void
 gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
                                int search_pc)
 {
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 22/43] target-moxie: gen_intermediate_code_internal() should be inlined
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (20 preceding siblings ...)
  2013-07-10 14:33 ` [Qemu-devel] [PULL 21/43] target-microblaze: " Andreas Färber
@ 2013-07-10 14:33 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 23/43] target-xtensa: " Andreas Färber
                   ` (20 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:33 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Green, Andreas Färber, qemu-stable

Cc: qemu-stable@nongnu.org
Reported-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-moxie/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-moxie/translate.c b/target-moxie/translate.c
index b0ae38a..664d359 100644
--- a/target-moxie/translate.c
+++ b/target-moxie/translate.c
@@ -820,7 +820,7 @@ static int decode_opc(MoxieCPU *cpu, DisasContext *ctx)
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-static void
+static inline void
 gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
                                bool search_pc)
 {
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 23/43] target-xtensa: gen_intermediate_code_internal() should be inlined
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (21 preceding siblings ...)
  2013-07-10 14:33 ` [Qemu-devel] [PULL 22/43] target-moxie: " Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 24/43] target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU Andreas Färber
                   ` (19 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Max Filippov, Andreas Färber, qemu-stable

Cc: qemu-stable@nongnu.org
Reported-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-xtensa/translate.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index dcb90a5..e384812 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2875,8 +2875,9 @@ static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
     }
 }
 
-static void gen_intermediate_code_internal(
-        CPUXtensaState *env, TranslationBlock *tb, int search_pc)
+static inline
+void gen_intermediate_code_internal(CPUXtensaState *env,
+                                    TranslationBlock *tb, int search_pc)
 {
     DisasContext dc;
     int insn_count = 0;
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 24/43] target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (22 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 23/43] target-xtensa: " Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 25/43] target-arm: Change gen_intermediate_code_internal() argument to ARMCPU Andreas Färber
                   ` (18 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber, Richard Henderson

Also use bool argument while at it.

Prepares for moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-alpha/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 4db16db..dd7f0fb 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3375,10 +3375,11 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
     return ret;
 }
 
-static inline void gen_intermediate_code_internal(CPUAlphaState *env,
+static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
                                                   TranslationBlock *tb,
-                                                  int search_pc)
+                                                  bool search_pc)
 {
+    CPUAlphaState *env = &cpu->env;
     DisasContext ctx, *ctxp = &ctx;
     target_ulong pc_start;
     uint32_t insn;
@@ -3502,12 +3503,12 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env,
 
 void gen_intermediate_code (CPUAlphaState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(alpha_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc (CPUAlphaState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(alpha_env_get_cpu(env), tb, true);
 }
 
 void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb, int pc_pos)
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 25/43] target-arm: Change gen_intermediate_code_internal() argument to ARMCPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (23 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 24/43] target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 26/43] target-cris: Change gen_intermediate_code_internal() argument to CRISCPU Andreas Färber
                   ` (17 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Andreas Färber, Paul Brook

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-arm/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index af2aef2..9310c58 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9796,10 +9796,11 @@ undef:
 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
    basic block 'tb'. If search_pc is TRUE, also generate PC
    information for each intermediate instruction. */
-static inline void gen_intermediate_code_internal(CPUARMState *env,
+static inline void gen_intermediate_code_internal(ARMCPU *cpu,
                                                   TranslationBlock *tb,
-                                                  int search_pc)
+                                                  bool search_pc)
 {
+    CPUARMState *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     CPUBreakpoint *bp;
     uint16_t *gen_opc_end;
@@ -10072,12 +10073,12 @@ done_generating:
 
 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
 }
 
 static const char *cpu_mode_names[16] = {
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 26/43] target-cris: Change gen_intermediate_code_internal() argument to CRISCPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (24 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 25/43] target-arm: Change gen_intermediate_code_internal() argument to ARMCPU Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 27/43] target-i386: Change gen_intermediate_code_internal() argument to X86CPU Andreas Färber
                   ` (16 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Edgar E. Iglesias, Andreas Färber

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-cris/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-cris/translate.c b/target-cris/translate.c
index ee9ae22..1de9743 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3162,9 +3162,10 @@ static void check_breakpoint(CPUCRISState *env, DisasContext *dc)
 
 /* generate intermediate code for basic block 'tb'.  */
 static inline void
-gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
-                               int search_pc)
+gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
+                               bool search_pc)
 {
+    CPUCRISState *env = &cpu->env;
     uint16_t *gen_opc_end;
     uint32_t pc_start;
     unsigned int insn_len;
@@ -3419,12 +3420,12 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
 
 void gen_intermediate_code (CPUCRISState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(cris_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc (CPUCRISState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(cris_env_get_cpu(env), tb, true);
 }
 
 void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 27/43] target-i386: Change gen_intermediate_code_internal() argument to X86CPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (25 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 26/43] target-cris: Change gen_intermediate_code_internal() argument to CRISCPU Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 28/43] target-lm32: Change gen_intermediate_code_internal() argument to LM32CPU Andreas Färber
                   ` (15 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-i386/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-i386/translate.c b/target-i386/translate.c
index 14b0298..6550c27 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -8251,10 +8251,11 @@ void optimize_flags_init(void)
 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
    basic block 'tb'. If search_pc is TRUE, also generate PC
    information for each intermediate instruction. */
-static inline void gen_intermediate_code_internal(CPUX86State *env,
+static inline void gen_intermediate_code_internal(X86CPU *cpu,
                                                   TranslationBlock *tb,
-                                                  int search_pc)
+                                                  bool search_pc)
 {
+    CPUX86State *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     target_ulong pc_ptr;
     uint16_t *gen_opc_end;
@@ -8428,12 +8429,12 @@ static inline void gen_intermediate_code_internal(CPUX86State *env,
 
 void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(x86_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUX86State *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(x86_env_get_cpu(env), tb, true);
 }
 
 void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos)
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 28/43] target-lm32: Change gen_intermediate_code_internal() argument to LM32CPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (26 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 27/43] target-i386: Change gen_intermediate_code_internal() argument to X86CPU Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 29/43] target-m68k: Change gen_intermediate_code_internal() argument to M68kCPU Andreas Färber
                   ` (14 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Michael Walle, Andreas Färber

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-lm32/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 7d82dc7..ed12f50 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -1012,9 +1012,10 @@ static void check_breakpoint(CPULM32State *env, DisasContext *dc)
 
 /* generate intermediate code for basic block 'tb'.  */
 static inline
-void gen_intermediate_code_internal(CPULM32State *env,
-                                    TranslationBlock *tb, int search_pc)
+void gen_intermediate_code_internal(LM32CPU *cpu,
+                                    TranslationBlock *tb, bool search_pc)
 {
+    CPULM32State *env = &cpu->env;
     struct DisasContext ctx, *dc = &ctx;
     uint16_t *gen_opc_end;
     uint32_t pc_start;
@@ -1134,12 +1135,12 @@ void gen_intermediate_code_internal(CPULM32State *env,
 
 void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(lm32_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPULM32State *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(lm32_env_get_cpu(env), tb, true);
 }
 
 void lm32_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 29/43] target-m68k: Change gen_intermediate_code_internal() argument to M68kCPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (27 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 28/43] target-lm32: Change gen_intermediate_code_internal() argument to LM32CPU Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 30/43] target-microblaze: Change gen_intermediate_code_internal() argument types Andreas Färber
                   ` (13 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber, Paul Brook

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-m68k/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 3752094..2d73af5 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -2971,9 +2971,10 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
 
 /* generate intermediate code for basic block 'tb'.  */
 static inline void
-gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
-                               int search_pc)
+gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
+                               bool search_pc)
 {
+    CPUM68KState *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     uint16_t *gen_opc_end;
     CPUBreakpoint *bp;
@@ -3096,12 +3097,12 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
 
 void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(m68k_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUM68KState *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(m68k_env_get_cpu(env), tb, true);
 }
 
 void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 30/43] target-microblaze: Change gen_intermediate_code_internal() argument types
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (28 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 29/43] target-m68k: Change gen_intermediate_code_internal() argument to M68kCPU Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 31/43] target-mips: Change gen_intermediate_code_internal() argument to MIPSCPU Andreas Färber
                   ` (12 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Edgar E. Iglesias, Andreas Färber

Use MicroBlazeCPU and bool.

Prepares for changing log_cpu_state() argument to CPUState and for
moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-microblaze/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 27da4bf..b5cb141 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1738,9 +1738,10 @@ static void check_breakpoint(CPUMBState *env, DisasContext *dc)
 
 /* generate intermediate code for basic block 'tb'.  */
 static inline void
-gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
-                               int search_pc)
+gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
+                               bool search_pc)
 {
+    CPUMBState *env = &cpu->env;
     uint16_t *gen_opc_end;
     uint32_t pc_start;
     int j, lj;
@@ -1941,12 +1942,12 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
 
 void gen_intermediate_code (CPUMBState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(mb_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc (CPUMBState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(mb_env_get_cpu(env), tb, true);
 }
 
 void mb_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 31/43] target-mips: Change gen_intermediate_code_internal() argument to MIPSCPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (29 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 30/43] target-microblaze: Change gen_intermediate_code_internal() argument types Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 32/43] target-ppc: Change gen_intermediate_code_internal() argument to PowerPCCPU Andreas Färber
                   ` (11 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber, Aurelien Jarno

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-mips/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 160c0c0..8246c20 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -15540,9 +15540,10 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
 }
 
 static inline void
-gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
-                                int search_pc)
+gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
+                               bool search_pc)
 {
+    CPUMIPSState *env = &cpu->env;
     DisasContext ctx;
     target_ulong pc_start;
     uint16_t *gen_opc_end;
@@ -15698,12 +15699,12 @@ done_generating:
 
 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
 }
 
 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 32/43] target-ppc: Change gen_intermediate_code_internal() argument to PowerPCCPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (30 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 31/43] target-mips: Change gen_intermediate_code_internal() argument to MIPSCPU Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 33/43] target-s390x: Change gen_intermediate_code_internal() argument to S390CPU Andreas Färber
                   ` (10 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: open list:PowerPC, Andreas Färber, Alexander Graf

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-ppc/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 3643863..eb96272 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9726,10 +9726,11 @@ void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
 }
 
 /*****************************************************************************/
-static inline void gen_intermediate_code_internal(CPUPPCState *env,
+static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
                                                   TranslationBlock *tb,
-                                                  int search_pc)
+                                                  bool search_pc)
 {
+    CPUPPCState *env = &cpu->env;
     DisasContext ctx, *ctxp = &ctx;
     opc_handler_t **table, *handler;
     target_ulong pc_start;
@@ -9917,12 +9918,12 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env,
 
 void gen_intermediate_code (CPUPPCState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(ppc_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc (CPUPPCState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(ppc_env_get_cpu(env), tb, true);
 }
 
 void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb, int pc_pos)
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 33/43] target-s390x: Change gen_intermediate_code_internal() argument to S390CPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (31 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 32/43] target-ppc: Change gen_intermediate_code_internal() argument to PowerPCCPU Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 34/43] target-sh4: Change gen_intermediate_code_internal() argument to SuperHCPU Andreas Färber
                   ` (9 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alexander Graf, Andreas Färber, Richard Henderson

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-s390x/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index cd9880e..cba7b87 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -4736,10 +4736,11 @@ static ExitStatus translate_one(CPUS390XState *env, DisasContext *s)
     return ret;
 }
 
-static inline void gen_intermediate_code_internal(CPUS390XState *env,
+static inline void gen_intermediate_code_internal(S390CPU *cpu,
                                                   TranslationBlock *tb,
-                                                  int search_pc)
+                                                  bool search_pc)
 {
+    CPUS390XState *env = &cpu->env;
     DisasContext dc;
     target_ulong pc_start;
     uint64_t next_page_start;
@@ -4872,12 +4873,12 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env,
 
 void gen_intermediate_code (CPUS390XState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(s390_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc (CPUS390XState *env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(s390_env_get_cpu(env), tb, true);
 }
 
 void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb, int pc_pos)
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 34/43] target-sh4: Change gen_intermediate_code_internal() argument to SuperHCPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (32 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 33/43] target-s390x: Change gen_intermediate_code_internal() argument to S390CPU Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 35/43] target-sparc: Change gen_intermediate_code_internal() argument to SPARCCPU Andreas Färber
                   ` (8 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber, Aurelien Jarno

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-sh4/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 292c9e9..2fbe668 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -1846,9 +1846,10 @@ static void decode_opc(DisasContext * ctx)
 }
 
 static inline void
-gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
-                               int search_pc)
+gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
+                               bool search_pc)
 {
+    CPUSH4State *env = &cpu->env;
     DisasContext ctx;
     target_ulong pc_start;
     static uint16_t *gen_opc_end;
@@ -1969,12 +1970,12 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
 
 void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(sh_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUSH4State * env, struct TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(sh_env_get_cpu(env), tb, true);
 }
 
 void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb, int pc_pos)
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 35/43] target-sparc: Change gen_intermediate_code_internal() argument to SPARCCPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (33 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 34/43] target-sh4: Change gen_intermediate_code_internal() argument to SuperHCPU Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 36/43] target-unicore32: Change gen_intermediate_code_internal() signature Andreas Färber
                   ` (7 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Blue Swirl, Andreas Färber

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-sparc/translate.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index eb6e800..5e771e5 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -5219,9 +5219,11 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
     }
 }
 
-static inline void gen_intermediate_code_internal(TranslationBlock * tb,
-                                                  int spc, CPUSPARCState *env)
+static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
+                                                  TranslationBlock *tb,
+                                                  bool spc)
 {
+    CPUSPARCState *env = &cpu->env;
     target_ulong pc_start, last_pc;
     uint16_t *gen_opc_end;
     DisasContext dc1, *dc = &dc1;
@@ -5347,12 +5349,12 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
 
 void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
 {
-    gen_intermediate_code_internal(tb, 0, env);
+    gen_intermediate_code_internal(sparc_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
 {
-    gen_intermediate_code_internal(tb, 1, env);
+    gen_intermediate_code_internal(sparc_env_get_cpu(env), tb, true);
 }
 
 void gen_intermediate_code_init(CPUSPARCState *env)
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 36/43] target-unicore32: Change gen_intermediate_code_internal() signature
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (34 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 35/43] target-sparc: Change gen_intermediate_code_internal() argument to SPARCCPU Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 37/43] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU Andreas Färber
                   ` (6 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Guan Xuetao, Andreas Färber

Use UniCore32CPU and bool.

Prepares for moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-unicore32/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index e1fe4e6..d85185d 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -1876,9 +1876,10 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
    basic block 'tb'. If search_pc is TRUE, also generate PC
    information for each intermediate instruction. */
-static inline void gen_intermediate_code_internal(CPUUniCore32State *env,
-        TranslationBlock *tb, int search_pc)
+static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
+        TranslationBlock *tb, bool search_pc)
 {
+    CPUUniCore32State *env = &cpu->env;
     DisasContext dc1, *dc = &dc1;
     CPUBreakpoint *bp;
     uint16_t *gen_opc_end;
@@ -2065,12 +2066,12 @@ done_generating:
 
 void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(uc32_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUUniCore32State *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(uc32_env_get_cpu(env), tb, true);
 }
 
 static const char *cpu_mode_names[16] = {
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 37/43] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (35 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 36/43] target-unicore32: Change gen_intermediate_code_internal() signature Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 38/43] target-i386: Change do_interrupt_all() argument to X86CPU Andreas Färber
                   ` (5 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Max Filippov, Andreas Färber

Also use bool type while at it.

Prepares for moving singlestep_enabled field to CPUState.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-xtensa/translate.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index e384812..e4cf828 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2876,9 +2876,10 @@ static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc)
 }
 
 static inline
-void gen_intermediate_code_internal(CPUXtensaState *env,
-                                    TranslationBlock *tb, int search_pc)
+void gen_intermediate_code_internal(XtensaCPU *cpu,
+                                    TranslationBlock *tb, bool search_pc)
 {
+    CPUXtensaState *env = &cpu->env;
     DisasContext dc;
     int insn_count = 0;
     int j, lj = -1;
@@ -3007,12 +3008,12 @@ void gen_intermediate_code_internal(CPUXtensaState *env,
 
 void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(xtensa_env_get_cpu(env), tb, false);
 }
 
 void gen_intermediate_code_pc(CPUXtensaState *env, TranslationBlock *tb)
 {
-    gen_intermediate_code_internal(env, tb, 1);
+    gen_intermediate_code_internal(xtensa_env_get_cpu(env), tb, true);
 }
 
 void xtensa_cpu_dump_state(CPUState *cs, FILE *f,
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 38/43] target-i386: Change do_interrupt_all() argument to X86CPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (36 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 37/43] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 39/43] target-i386: Change do_smm_enter() " Andreas Färber
                   ` (4 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Prepares for log_cpu_state() changing argument to CPUState.

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

diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 9c799e1..92caa84 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -1160,9 +1160,11 @@ static void handle_even_inj(CPUX86State *env, int intno, int is_int,
  * the int instruction. next_eip is the env->eip value AFTER the interrupt
  * instruction. It is only relevant if is_int is TRUE.
  */
-static void do_interrupt_all(CPUX86State *env, int intno, int is_int,
+static void do_interrupt_all(X86CPU *cpu, int intno, int is_int,
                              int error_code, target_ulong next_eip, int is_hw)
 {
+    CPUX86State *env = &cpu->env;
+
     if (qemu_loglevel_mask(CPU_LOG_INT)) {
         if ((env->cr[0] & CR0_PE_MASK)) {
             static int count;
@@ -1252,7 +1254,7 @@ void x86_cpu_do_interrupt(CPUState *cs)
     /* simulate a real cpu exception. On i386, it can
        trigger new exceptions, but we do not handle
        double or triple faults yet. */
-    do_interrupt_all(env, env->exception_index,
+    do_interrupt_all(cpu, env->exception_index,
                      env->exception_is_int,
                      env->error_code,
                      env->exception_next_eip, 0);
@@ -1263,7 +1265,7 @@ void x86_cpu_do_interrupt(CPUState *cs)
 
 void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw)
 {
-    do_interrupt_all(env, intno, 0, 0, 0, is_hw);
+    do_interrupt_all(x86_env_get_cpu(env), intno, 0, 0, 0, is_hw);
 }
 
 void helper_enter_level(CPUX86State *env, int level, int data32,
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 39/43] target-i386: Change do_smm_enter() argument to X86CPU
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (37 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 38/43] target-i386: Change do_interrupt_all() argument to X86CPU Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 40/43] log: Change log_cpu_state[_mask]() argument to CPUState Andreas Färber
                   ` (3 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Prepares for log_cpu_state_mask() changing argument to CPUState.

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

diff --git a/cpu-exec.c b/cpu-exec.c
index 503b103..58a0674 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -331,7 +331,7 @@ int cpu_exec(CPUArchState *env)
                             cpu_svm_check_intercept_param(env, SVM_EXIT_SMI,
                                                           0);
                             cpu->interrupt_request &= ~CPU_INTERRUPT_SMI;
-                            do_smm_enter(env);
+                            do_smm_enter(x86_env_get_cpu(env));
                             next_tb = 0;
                         } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
                                    !(env->hflags2 & HF2_NMI_MASK)) {
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 2849672..2d005b3 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1220,7 +1220,7 @@ void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1);
 /* seg_helper.c */
 void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw);
 
-void do_smm_enter(CPUX86State *env1);
+void do_smm_enter(X86CPU *cpu);
 
 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access);
 
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 2489573..78abe5b 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -24,7 +24,7 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void do_smm_enter(CPUX86State *env)
+void do_smm_enter(X86CPU *cpu)
 {
 }
 
@@ -40,8 +40,9 @@ void helper_rsm(CPUX86State *env)
 #define SMM_REVISION_ID 0x00020000
 #endif
 
-void do_smm_enter(CPUX86State *env)
+void do_smm_enter(X86CPU *cpu)
 {
+    CPUX86State *env = &cpu->env;
     target_ulong sm_state;
     SegmentCache *dt;
     int i, offset;
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 40/43] log: Change log_cpu_state[_mask]() argument to CPUState
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (38 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 39/43] target-i386: Change do_smm_enter() " Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 41/43] target-i386: Change LOG_PCALL_STATE() " Andreas Färber
                   ` (2 subsequent siblings)
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Jia Liu, Anthony Green, Riku Voipio,
	Alexander Graf, Blue Swirl, Michael Walle, open list:PowerPC,
	Paul Brook, Edgar E. Iglesias, Andreas Färber,
	Aurelien Jarno, Richard Henderson

Since commit 878096eeb278a8ac1ccd6667af73e026f29b4cf5 (cpu: Turn
cpu_dump_{state,statistics}() into CPUState hooks) CPUArchState is no
longer needed.

Add documentation and make the functions available through qemu/log.h
outside NEED_CPU_H to allow use in qom/cpu.c. Moving them to qom/cpu.h
was not yet possible due to convoluted include paths, so that some
devices grow an implicit and unneeded dependency on qom/cpu.h for now.

Acked-by: Michael Walle <michael@walle.cc> (for lm32)
Reviewed-by: Richard Henderson <rth@twiddle.net>
[AF: Simplified mb_cpu_do_interrupt() and do_interrupt_all() changes]
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 cpu-exec.c                    |  6 +++---
 exec.c                        |  2 +-
 include/qemu/log.h            | 26 +++++++++++++++++++++-----
 linux-user/main.c             |  5 +++--
 target-arm/cpu.c              |  2 +-
 target-cris/cpu.c             |  2 +-
 target-i386/cpu.c             |  2 +-
 target-i386/seg_helper.c      |  4 ++--
 target-i386/smm_helper.c      |  5 +++--
 target-lm32/cpu.c             |  2 +-
 target-lm32/helper.c          |  4 ++--
 target-m68k/cpu.c             |  2 +-
 target-microblaze/cpu.c       |  2 +-
 target-microblaze/helper.c    | 12 ++++++------
 target-microblaze/translate.c |  2 +-
 target-mips/cpu.c             |  2 +-
 target-mips/helper.c          |  2 +-
 target-moxie/cpu.c            |  2 +-
 target-openrisc/cpu.c         |  2 +-
 target-openrisc/translate.c   |  2 +-
 target-ppc/mmu-hash32.c       |  2 +-
 target-ppc/mmu-hash64.c       |  2 +-
 target-ppc/mmu_helper.c       |  2 +-
 target-ppc/translate_init.c   |  2 +-
 target-s390x/cpu.c            |  2 +-
 target-sh4/cpu.c              |  2 +-
 target-sh4/helper.c           |  2 +-
 target-sparc/cpu.c            |  2 +-
 target-sparc/int32_helper.c   |  2 +-
 target-sparc/int64_helper.c   |  2 +-
 30 files changed, 63 insertions(+), 45 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 58a0674..6c784a7 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -577,15 +577,15 @@ int cpu_exec(CPUArchState *env)
                 if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
                     /* restore flags in standard format */
 #if defined(TARGET_I386)
-                    log_cpu_state(env, CPU_DUMP_CCOP);
+                    log_cpu_state(cpu, CPU_DUMP_CCOP);
 #elif defined(TARGET_M68K)
                     cpu_m68k_flush_flags(env, env->cc_op);
                     env->cc_op = CC_OP_FLAGS;
                     env->sr = (env->sr & 0xffe0)
                               | env->cc_dest | (env->cc_x << 4);
-                    log_cpu_state(env, 0);
+                    log_cpu_state(cpu, 0);
 #else
-                    log_cpu_state(env, 0);
+                    log_cpu_state(cpu, 0);
 #endif
                 }
 #endif /* DEBUG_DISAS */
diff --git a/exec.c b/exec.c
index 61b094a..f01e3b6 100644
--- a/exec.c
+++ b/exec.c
@@ -617,7 +617,7 @@ void cpu_abort(CPUArchState *env, const char *fmt, ...)
         qemu_log("qemu: fatal: ");
         qemu_log_vprintf(fmt, ap2);
         qemu_log("\n");
-        log_cpu_state(env, CPU_DUMP_FPU | CPU_DUMP_CCOP);
+        log_cpu_state(cpu, CPU_DUMP_FPU | CPU_DUMP_CCOP);
         qemu_log_flush();
         qemu_log_close();
     }
diff --git a/include/qemu/log.h b/include/qemu/log.h
index a9cf214..d515424 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -5,6 +5,7 @@
 #include <stdbool.h>
 #include <stdio.h>
 #include "qemu/compiler.h"
+#include "qom/cpu.h"
 #ifdef NEED_CPU_H
 #include "disas/disas.h"
 #endif
@@ -70,22 +71,37 @@ void GCC_FMT_ATTR(2, 3) qemu_log_mask(int mask, const char *fmt, ...);
 
 /* Special cases: */
 
-#ifdef NEED_CPU_H
 /* cpu_dump_state() logging functions: */
-static inline void log_cpu_state(CPUArchState *env1, int flags)
+/**
+ * log_cpu_state:
+ * @cpu: The CPU whose state is to be logged.
+ * @flags: Flags what to log.
+ *
+ * Logs the output of cpu_dump_state().
+ */
+static inline void log_cpu_state(CPUState *cpu, int flags)
 {
     if (qemu_log_enabled()) {
-        cpu_dump_state(ENV_GET_CPU(env1), qemu_logfile, fprintf, flags);
+        cpu_dump_state(cpu, qemu_logfile, fprintf, flags);
     }
 }
 
-static inline void log_cpu_state_mask(int mask, CPUArchState *env1, int flags)
+/**
+ * log_cpu_state_mask:
+ * @mask: Mask when to log.
+ * @cpu: The CPU whose state is to be logged.
+ * @flags: Flags what to log.
+ *
+ * Logs the output of cpu_dump_state() if loglevel includes @mask.
+ */
+static inline void log_cpu_state_mask(int mask, CPUState *cpu, int flags)
 {
     if (qemu_loglevel & mask) {
-        log_cpu_state(env1, flags);
+        log_cpu_state(cpu, flags);
     }
 }
 
+#ifdef NEED_CPU_H
 /* disas() and target_disas() to qemu_logfile: */
 static inline void log_target_disas(CPUArchState *env, target_ulong start,
                                     target_ulong len, int flags)
diff --git a/linux-user/main.c b/linux-user/main.c
index 67ea9ba..7f15d3d 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1302,11 +1302,12 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
 
 #define EXCP_DUMP(env, fmt, ...)                                        \
 do {                                                                    \
+    CPUState *cs = ENV_GET_CPU(env);                                    \
     fprintf(stderr, fmt , ## __VA_ARGS__);                              \
-    cpu_dump_state(ENV_GET_CPU(env), stderr, fprintf, 0);               \
+    cpu_dump_state(cs, stderr, fprintf, 0);                             \
     qemu_log(fmt, ## __VA_ARGS__);                                      \
     if (qemu_log_enabled()) {                                           \
-        log_cpu_state(env, 0);                                          \
+        log_cpu_state(cs, 0);                                           \
     }                                                                   \
 } while (0)
 
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 1bc227e..84974a9 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -65,7 +65,7 @@ static void arm_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     acc->parent_reset(s);
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index 6a3bdf0..f6c4f3f 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -36,7 +36,7 @@ static void cris_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     ccc->parent_reset(s);
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index b7416fe..82a451b 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2177,7 +2177,7 @@ static void x86_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, CPU_DUMP_FPU | CPU_DUMP_CCOP);
+        log_cpu_state(s, CPU_DUMP_FPU | CPU_DUMP_CCOP);
     }
 
     xcc->parent_reset(s);
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 92caa84..fc7ffad 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -31,7 +31,7 @@
 #ifdef DEBUG_PCALL
 # define LOG_PCALL(...) qemu_log_mask(CPU_LOG_PCALL, ## __VA_ARGS__)
 # define LOG_PCALL_STATE(env)                                  \
-    log_cpu_state_mask(CPU_LOG_PCALL, (env), CPU_DUMP_CCOP)
+    log_cpu_state_mask(CPU_LOG_PCALL, CPU(x86_env_get_cpu(env)), CPU_DUMP_CCOP)
 #else
 # define LOG_PCALL(...) do { } while (0)
 # define LOG_PCALL_STATE(env) do { } while (0)
@@ -1182,7 +1182,7 @@ static void do_interrupt_all(X86CPU *cpu, int intno, int is_int,
                 qemu_log(" env->regs[R_EAX]=" TARGET_FMT_lx, env->regs[R_EAX]);
             }
             qemu_log("\n");
-            log_cpu_state(env, CPU_DUMP_CCOP);
+            log_cpu_state(CPU(cpu), CPU_DUMP_CCOP);
 #if 0
             {
                 int i;
diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c
index 78abe5b..6cb4551 100644
--- a/target-i386/smm_helper.c
+++ b/target-i386/smm_helper.c
@@ -48,7 +48,7 @@ void do_smm_enter(X86CPU *cpu)
     int i, offset;
 
     qemu_log_mask(CPU_LOG_INT, "SMM: enter\n");
-    log_cpu_state_mask(CPU_LOG_INT, env, CPU_DUMP_CCOP);
+    log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);
 
     env->hflags |= HF_SMM_MASK;
     cpu_smm_update(env);
@@ -180,6 +180,7 @@ void do_smm_enter(X86CPU *cpu)
 
 void helper_rsm(CPUX86State *env)
 {
+    X86CPU *cpu = x86_env_get_cpu(env);
     target_ulong sm_state;
     int i, offset;
     uint32_t val;
@@ -296,7 +297,7 @@ void helper_rsm(CPUX86State *env)
     cpu_smm_update(env);
 
     qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n");
-    log_cpu_state_mask(CPU_LOG_INT, env, CPU_DUMP_CCOP);
+    log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP);
 }
 
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 02f8436..6e44d45 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -31,7 +31,7 @@ static void lm32_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     lcc->parent_reset(s);
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 03fa5fb..615b44e 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -70,7 +70,7 @@ void lm32_cpu_do_interrupt(CPUState *cs)
         } else {
             env->pc = env->eba + (env->exception_index * 32);
         }
-        log_cpu_state_mask(CPU_LOG_INT, env, 0);
+        log_cpu_state_mask(CPU_LOG_INT, cs, 0);
         break;
     case EXCP_BREAKPOINT:
     case EXCP_WATCHPOINT:
@@ -79,7 +79,7 @@ void lm32_cpu_do_interrupt(CPUState *cs)
         env->ie |= (env->ie & IE_IE) ? IE_BIE : 0;
         env->ie &= ~IE_IE;
         env->pc = env->deba + (env->exception_index * 32);
-        log_cpu_state_mask(CPU_LOG_INT, env, 0);
+        log_cpu_state_mask(CPU_LOG_INT, cs, 0);
         break;
     default:
         cpu_abort(env, "unhandled exception type=%d\n",
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 799869f..c9ac30f 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -37,7 +37,7 @@ static void m68k_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     mcc->parent_reset(s);
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index a0fcdf4..d93519e 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -35,7 +35,7 @@ static void mb_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     mcc->parent_reset(s);
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index 01d4bbf..c6c96d4 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -152,7 +152,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
                           "hw exception at pc=%x ear=%x esr=%x iflags=%x\n",
                           env->sregs[SR_PC], env->sregs[SR_EAR],
                           env->sregs[SR_ESR], env->iflags);
-            log_cpu_state_mask(CPU_LOG_INT, env, 0);
+            log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             env->iflags &= ~(IMM_FLAG | D_FLAG);
             env->sregs[SR_PC] = cpu->base_vectors + 0x20;
             break;
@@ -175,7 +175,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
                                   "bimm exception at pc=%x iflags=%x\n",
                                   env->sregs[SR_PC], env->iflags);
                     env->regs[17] -= 4;
-                    log_cpu_state_mask(CPU_LOG_INT, env, 0);
+                    log_cpu_state_mask(CPU_LOG_INT, cs, 0);
                 }
             } else if (env->iflags & IMM_FLAG) {
                 D(qemu_log("IMM_FLAG set at exception\n"));
@@ -192,7 +192,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             qemu_log_mask(CPU_LOG_INT,
                           "exception at pc=%x ear=%x iflags=%x\n",
                           env->sregs[SR_PC], env->sregs[SR_EAR], env->iflags);
-            log_cpu_state_mask(CPU_LOG_INT, env, 0);
+            log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             env->iflags &= ~(IMM_FLAG | D_FLAG);
             env->sregs[SR_PC] = cpu->base_vectors + 0x20;
             break;
@@ -222,7 +222,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
                          env->sregs[SR_PC], env->sregs[SR_MSR], t, env->iflags,
                          sym);
 
-                    log_cpu_state(env, 0);
+                    log_cpu_state(cs, 0);
                 }
             }
 #endif
@@ -236,7 +236,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
 
             env->regs[14] = env->sregs[SR_PC];
             env->sregs[SR_PC] = cpu->base_vectors + 0x10;
-            //log_cpu_state_mask(CPU_LOG_INT, env, 0);
+            //log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             break;
 
         case EXCP_BREAK:
@@ -247,7 +247,7 @@ void mb_cpu_do_interrupt(CPUState *cs)
             qemu_log_mask(CPU_LOG_INT,
                         "break at pc=%x msr=%x %x iflags=%x\n",
                         env->sregs[SR_PC], env->sregs[SR_MSR], t, env->iflags);
-            log_cpu_state_mask(CPU_LOG_INT, env, 0);
+            log_cpu_state_mask(CPU_LOG_INT, cs, 0);
             env->sregs[SR_MSR] &= ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM);
             env->sregs[SR_MSR] |= t;
             env->sregs[SR_MSR] |= MSR_BIP;
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index b5cb141..eba255b 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1777,7 +1777,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
 #if !SIM_COMPAT
         qemu_log("--------------\n");
-        log_cpu_state(env, 0);
+        log_cpu_state(CPU(cpu), 0);
 #endif
     }
 
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index b61e207..cab9572 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -31,7 +31,7 @@ static void mips_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     mcc->parent_reset(s);
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 36929dd..6983b92 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -276,7 +276,7 @@ int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
     int ret = 0;
 
 #if 0
-    log_cpu_state(env, 0);
+    log_cpu_state(CPU(mips_env_get_cpu(env)), 0);
 #endif
     qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d\n",
               __func__, env->active_tc.PC, address, rw, mmu_idx);
diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
index f3c0d22..7314d4b 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -30,7 +30,7 @@ static void moxie_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     mcc->parent_reset(s);
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index d38c28b..0dc60c9 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -28,7 +28,7 @@ static void openrisc_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(&cpu->env, 0);
+        log_cpu_state(s, 0);
     }
 
     occ->parent_reset(s);
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index c59fd02..f222834 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1684,7 +1684,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
     dc->singlestep_enabled = cpu->env.singlestep_enabled;
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("-----------------------------------------\n");
-        log_cpu_state(&cpu->env, 0);
+        log_cpu_state(CPU(cpu), 0);
     }
 
     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
index f6adf22..b5ebe07 100644
--- a/target-ppc/mmu-hash32.c
+++ b/target-ppc/mmu-hash32.c
@@ -29,7 +29,7 @@
 
 #ifdef DEBUG_MMU
 #  define LOG_MMU(...) qemu_log(__VA_ARGS__)
-#  define LOG_MMU_STATE(env) log_cpu_state((env), 0)
+#  define LOG_MMU_STATE(env) log_cpu_state(CPU(ppc_env_get_cpu(env)), 0)
 #else
 #  define LOG_MMU(...) do { } while (0)
 #  define LOG_MMU_STATE(...) do { } while (0)
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 5c67ec3..759cef3 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -28,7 +28,7 @@
 
 #ifdef DEBUG_MMU
 #  define LOG_MMU(...) qemu_log(__VA_ARGS__)
-#  define LOG_MMU_STATE(env) log_cpu_state((env), 0)
+#  define LOG_MMU_STATE(env) log_cpu_state(CPU(ppc_env_get_cpu(env)), 0)
 #else
 #  define LOG_MMU(...) do { } while (0)
 #  define LOG_MMU_STATE(...) do { } while (0)
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index e4e111c..413e95b 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -32,7 +32,7 @@
 
 #ifdef DEBUG_MMU
 #  define LOG_MMU(...) qemu_log(__VA_ARGS__)
-#  define LOG_MMU_STATE(env) log_cpu_state((env), 0)
+#  define LOG_MMU_STATE(env) log_cpu_state(CPU(ppc_env_get_cpu(env)), 0)
 #else
 #  define LOG_MMU(...) do { } while (0)
 #  define LOG_MMU_STATE(...) do { } while (0)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 50e0ee5..43eec67 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8173,7 +8173,7 @@ static void ppc_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     pcc->parent_reset(s);
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index c3697cd..732d393 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -67,7 +67,7 @@ static void s390_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     s390_del_running_cpu(cpu);
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index e739156..653acec 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -33,7 +33,7 @@ static void superh_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     scc->parent_reset(s);
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index ce10ca8..cb6a2d2 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -159,7 +159,7 @@ void superh_cpu_do_interrupt(CPUState *cs)
 	}
 	qemu_log("exception 0x%03x [%s] raised\n",
 		  irq_vector, expname);
-	log_cpu_state(env, 0);
+        log_cpu_state(cs, 0);
     }
 
     env->ssr = env->sr;
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 65ae6f7..4cbb206 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -32,7 +32,7 @@ static void sparc_cpu_reset(CPUState *s)
 
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(env, 0);
+        log_cpu_state(s, 0);
     }
 
     scc->parent_reset(s);
diff --git a/target-sparc/int32_helper.c b/target-sparc/int32_helper.c
index 7221460..d532238 100644
--- a/target-sparc/int32_helper.c
+++ b/target-sparc/int32_helper.c
@@ -86,7 +86,7 @@ void sparc_cpu_do_interrupt(CPUState *cs)
         }
 
         qemu_log("%6d: %s (v=%02x)\n", count, name, intno);
-        log_cpu_state(env, 0);
+        log_cpu_state(cs, 0);
 #if 0
         {
             int i;
diff --git a/target-sparc/int64_helper.c b/target-sparc/int64_helper.c
index f411884..bf7dd86 100644
--- a/target-sparc/int64_helper.c
+++ b/target-sparc/int64_helper.c
@@ -92,7 +92,7 @@ void sparc_cpu_do_interrupt(CPUState *cs)
         }
 
         qemu_log("%6d: %s (v=%04x)\n", count, name, intno);
-        log_cpu_state(env, 0);
+        log_cpu_state(cs, 0);
 #if 0
         {
             int i;
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 41/43] target-i386: Change LOG_PCALL_STATE() argument to CPUState
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (39 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 40/43] log: Change log_cpu_state[_mask]() argument to CPUState Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 42/43] target-ppc: Change LOG_MMU_STATE() " Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 43/43] cpu: Move reset logging " Andreas Färber
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: Andreas Färber

Since log_cpu_state_mask() argument was changed to CPUState,
CPUArchState is no longer needed.

Choose CPUState rather than X86CPU to not hide type mismatches with CPU().

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-i386/seg_helper.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index fc7ffad..e789102 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -30,11 +30,11 @@
 
 #ifdef DEBUG_PCALL
 # define LOG_PCALL(...) qemu_log_mask(CPU_LOG_PCALL, ## __VA_ARGS__)
-# define LOG_PCALL_STATE(env)                                  \
-    log_cpu_state_mask(CPU_LOG_PCALL, CPU(x86_env_get_cpu(env)), CPU_DUMP_CCOP)
+# define LOG_PCALL_STATE(cpu)                                  \
+    log_cpu_state_mask(CPU_LOG_PCALL, (cpu), CPU_DUMP_CCOP)
 #else
 # define LOG_PCALL(...) do { } while (0)
-# define LOG_PCALL_STATE(env) do { } while (0)
+# define LOG_PCALL_STATE(cpu) do { } while (0)
 #endif
 
 /* return non zero if error */
@@ -1686,7 +1686,7 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip,
 
     next_eip = env->eip + next_eip_addend;
     LOG_PCALL("lcall %04x:%08x s=%d\n", new_cs, (uint32_t)new_eip, shift);
-    LOG_PCALL_STATE(env);
+    LOG_PCALL_STATE(CPU(x86_env_get_cpu(env)));
     if ((new_cs & 0xfffc) == 0) {
         raise_exception_err(env, EXCP0D_GPF, 0);
     }
@@ -2020,7 +2020,7 @@ static inline void helper_ret_protected(CPUX86State *env, int shift,
     }
     LOG_PCALL("lret new %04x:" TARGET_FMT_lx " s=%d addend=0x%x\n",
               new_cs, new_eip, shift, addend);
-    LOG_PCALL_STATE(env);
+    LOG_PCALL_STATE(CPU(x86_env_get_cpu(env)));
     if ((new_cs & 0xfffc) == 0) {
         raise_exception_err(env, EXCP0D_GPF, new_cs & 0xfffc);
     }
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 42/43] target-ppc: Change LOG_MMU_STATE() argument to CPUState
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (40 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 41/43] target-i386: Change LOG_PCALL_STATE() " Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  2013-07-10 14:34 ` [Qemu-devel] [PULL 43/43] cpu: Move reset logging " Andreas Färber
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: open list:PowerPC, Andreas Färber, Alexander Graf

Choose CPUState rather than PowerPCCPU since doing a CPU() cast on the
macro argument would hide type mismatches.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 target-ppc/mmu-hash32.c | 4 ++--
 target-ppc/mmu-hash64.c | 4 ++--
 target-ppc/mmu_helper.c | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
index b5ebe07..6a77dc4 100644
--- a/target-ppc/mmu-hash32.c
+++ b/target-ppc/mmu-hash32.c
@@ -29,10 +29,10 @@
 
 #ifdef DEBUG_MMU
 #  define LOG_MMU(...) qemu_log(__VA_ARGS__)
-#  define LOG_MMU_STATE(env) log_cpu_state(CPU(ppc_env_get_cpu(env)), 0)
+#  define LOG_MMU_STATE(cpu) log_cpu_state((cpu), 0)
 #else
 #  define LOG_MMU(...) do { } while (0)
-#  define LOG_MMU_STATE(...) do { } while (0)
+#  define LOG_MMU_STATE(cpu) do { } while (0)
 #endif
 
 #ifdef DEBUG_BATS
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 759cef3..67fc1b5 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -28,10 +28,10 @@
 
 #ifdef DEBUG_MMU
 #  define LOG_MMU(...) qemu_log(__VA_ARGS__)
-#  define LOG_MMU_STATE(env) log_cpu_state(CPU(ppc_env_get_cpu(env)), 0)
+#  define LOG_MMU_STATE(cpu) log_cpu_state((cpu), 0)
 #else
 #  define LOG_MMU(...) do { } while (0)
-#  define LOG_MMU_STATE(...) do { } while (0)
+#  define LOG_MMU_STATE(cpu) do { } while (0)
 #endif
 
 #ifdef DEBUG_SLB
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 413e95b..77102c4 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -32,10 +32,10 @@
 
 #ifdef DEBUG_MMU
 #  define LOG_MMU(...) qemu_log(__VA_ARGS__)
-#  define LOG_MMU_STATE(env) log_cpu_state(CPU(ppc_env_get_cpu(env)), 0)
+#  define LOG_MMU_STATE(cpu) log_cpu_state((cpu), 0)
 #else
 #  define LOG_MMU(...) do { } while (0)
-#  define LOG_MMU_STATE(...) do { } while (0)
+#  define LOG_MMU_STATE(cpu) do { } while (0)
 #endif
 
 #ifdef DEBUG_SOFTWARE_TLB
@@ -1508,7 +1508,7 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
                      mmu_idx, TARGET_PAGE_SIZE);
         ret = 0;
     } else if (ret < 0) {
-        LOG_MMU_STATE(env);
+        LOG_MMU_STATE(CPU(ppc_env_get_cpu(env)));
         if (access_type == ACCESS_CODE) {
             switch (ret) {
             case -1:
-- 
1.8.1.4

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

* [Qemu-devel] [PULL 43/43] cpu: Move reset logging to CPUState
  2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
                   ` (41 preceding siblings ...)
  2013-07-10 14:34 ` [Qemu-devel] [PULL 42/43] target-ppc: Change LOG_MMU_STATE() " Andreas Färber
@ 2013-07-10 14:34 ` Andreas Färber
  42 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-10 14:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Jia Liu, Anthony Green, Alexander Graf,
	Blue Swirl, Michael Walle, open list:PowerPC, Paul Brook,
	Edgar E. Iglesias, Andreas Färber, Aurelien Jarno,
	Richard Henderson

x86 was using additional CPU_DUMP_* flags, so make that configurable in
CPUClass::reset_dump_flags.

This adds reset logging for alpha, unicore32 and xtensa.

Acked-by: Michael Walle <michael@walle.cc> (for lm32)
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 include/qom/cpu.h           | 2 ++
 qom/cpu.c                   | 8 ++++++++
 target-arm/cpu.c            | 5 -----
 target-cris/cpu.c           | 5 -----
 target-i386/cpu.c           | 6 +-----
 target-lm32/cpu.c           | 5 -----
 target-m68k/cpu.c           | 5 -----
 target-microblaze/cpu.c     | 5 -----
 target-mips/cpu.c           | 5 -----
 target-moxie/cpu.c          | 5 -----
 target-openrisc/cpu.c       | 5 -----
 target-ppc/translate_init.c | 5 -----
 target-s390x/cpu.c          | 5 -----
 target-sh4/cpu.c            | 5 -----
 target-sparc/cpu.c          | 5 -----
 15 files changed, 11 insertions(+), 65 deletions(-)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index a08a8ab..147c256 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -53,6 +53,7 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
  * @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.
+ * @reset_dump_flags: #CPUDumpFlags to use for reset logging.
  * @do_interrupt: Callback for interrupt handling.
  * @do_unassigned_access: Callback for unassigned access handling.
  * @dump_state: Callback for dumping state.
@@ -72,6 +73,7 @@ typedef struct CPUClass {
     ObjectClass *(*class_by_name)(const char *cpu_model);
 
     void (*reset)(CPUState *cpu);
+    int reset_dump_flags;
     void (*do_interrupt)(CPUState *cpu);
     CPUUnassignedAccess do_unassigned_access;
     void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
diff --git a/qom/cpu.c b/qom/cpu.c
index ee8f632..5c45ab5 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -22,6 +22,7 @@
 #include "qom/cpu.h"
 #include "sysemu/kvm.h"
 #include "qemu/notify.h"
+#include "qemu/log.h"
 #include "sysemu/sysemu.h"
 
 typedef struct CPUExistsArgs {
@@ -187,6 +188,13 @@ void cpu_reset(CPUState *cpu)
 
 static void cpu_common_reset(CPUState *cpu)
 {
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+        qemu_log("CPU Reset (CPU %d)\n", cpu->cpu_index);
+        log_cpu_state(cpu, cc->reset_dump_flags);
+    }
+
     cpu->exit_request = 0;
     cpu->interrupt_request = 0;
     cpu->current_tb = NULL;
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 84974a9..be26acc 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -63,11 +63,6 @@ static void arm_cpu_reset(CPUState *s)
     ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu);
     CPUARMState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     acc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUARMState, breakpoints));
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index f6c4f3f..2abb57f 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -34,11 +34,6 @@ static void cris_cpu_reset(CPUState *s)
     CPUCRISState *env = &cpu->env;
     uint32_t vr;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     ccc->parent_reset(s);
 
     vr = env->pregs[PR_VR];
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 82a451b..e3f75a8 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2175,11 +2175,6 @@ static void x86_cpu_reset(CPUState *s)
     CPUX86State *env = &cpu->env;
     int i;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, CPU_DUMP_FPU | CPU_DUMP_CCOP);
-    }
-
     xcc->parent_reset(s);
 
 
@@ -2523,6 +2518,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
 
     xcc->parent_reset = cc->reset;
     cc->reset = x86_cpu_reset;
+    cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
 
     cc->do_interrupt = x86_cpu_do_interrupt;
     cc->dump_state = x86_cpu_dump_state;
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 6e44d45..04327ac 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -29,11 +29,6 @@ static void lm32_cpu_reset(CPUState *s)
     LM32CPUClass *lcc = LM32_CPU_GET_CLASS(cpu);
     CPULM32State *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     lcc->parent_reset(s);
 
     /* reset cpu state */
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index c9ac30f..1b6ef66 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -35,11 +35,6 @@ static void m68k_cpu_reset(CPUState *s)
     M68kCPUClass *mcc = M68K_CPU_GET_CLASS(cpu);
     CPUM68KState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     mcc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUM68KState, breakpoints));
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index d93519e..dce1c7e 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -33,11 +33,6 @@ static void mb_cpu_reset(CPUState *s)
     MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(cpu);
     CPUMBState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     mcc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUMBState, breakpoints));
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index cab9572..60a3faf 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -29,11 +29,6 @@ static void mips_cpu_reset(CPUState *s)
     MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(cpu);
     CPUMIPSState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     mcc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUMIPSState, breakpoints));
diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
index 7314d4b..92ca594 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -28,11 +28,6 @@ static void moxie_cpu_reset(CPUState *s)
     MoxieCPUClass *mcc = MOXIE_CPU_GET_CLASS(cpu);
     CPUMoxieState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     mcc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUMoxieState, breakpoints));
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index 0dc60c9..6d40f1b 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -26,11 +26,6 @@ static void openrisc_cpu_reset(CPUState *s)
     OpenRISCCPU *cpu = OPENRISC_CPU(s);
     OpenRISCCPUClass *occ = OPENRISC_CPU_GET_CLASS(cpu);
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     occ->parent_reset(s);
 
     memset(&cpu->env, 0, offsetof(CPUOpenRISCState, breakpoints));
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 43eec67..b62f04a 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8171,11 +8171,6 @@ static void ppc_cpu_reset(CPUState *s)
     CPUPPCState *env = &cpu->env;
     target_ulong msr;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     pcc->parent_reset(s);
 
     msr = (target_ulong)0;
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 732d393..1ef2fc0 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -65,11 +65,6 @@ static void s390_cpu_reset(CPUState *s)
     S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
     CPUS390XState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     s390_del_running_cpu(cpu);
 
     scc->parent_reset(s);
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index 653acec..03487eb 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -31,11 +31,6 @@ static void superh_cpu_reset(CPUState *s)
     SuperHCPUClass *scc = SUPERH_CPU_GET_CLASS(cpu);
     CPUSH4State *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     scc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUSH4State, breakpoints));
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 4cbb206..87c3a50 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -30,11 +30,6 @@ static void sparc_cpu_reset(CPUState *s)
     SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(cpu);
     CPUSPARCState *env = &cpu->env;
 
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", s->cpu_index);
-        log_cpu_state(s, 0);
-    }
-
     scc->parent_reset(s);
 
     memset(env, 0, offsetof(CPUSPARCState, breakpoints));
-- 
1.8.1.4

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

* Re: [PULL 09/43] cpu: Make first_cpu and next_cpu CPUState
  2013-07-10 14:33   ` [Qemu-devel] " Andreas Färber
@ 2013-07-11  9:14     ` TeLeMan
  -1 siblings, 0 replies; 53+ messages in thread
From: TeLeMan @ 2013-07-11  9:14 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Gleb Natapov, qemu-devel, Luiz Capitulino,
	Peter Crosthwaite, Edgar E. Iglesias, Igor Mitsyanko,
	Evgeny Voevodin, Alexander Graf, Andreas Färber,
	Maksim Kozlov, Riku Voipio, Paul Brook, open list:Overall,
	Scott Wood, Anthony Liguori, Mark Langsdorf, Marcelo Tosatti,
	open list:e500, Dmitry Solodkiy, Paolo Bonzini

On Wed, Jul 10, 2013 at 10:33 PM, Andreas Färber <afaerber@suse.de> wrote:
> Move next_cpu from CPU_COMMON to CPUState.
> Move first_cpu variable to qom/cpu.h.
>
> gdbstub needs to use CPUState::env_ptr for now.
> cpu_copy() no longer needs to save and restore cpu_next.
>
> Acked-by: Paolo Bonzini <pbonzini@redhat.com>
> [AF: Rebased, simplified cpu_copy()]
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c                    | 126 ++++++++++++++++++++++++----------------------
>  cputlb.c                  |   4 +-
>  dump.c                    |  16 +++---
>  exec.c                    |  43 ++++++++--------
>  gdbstub.c                 |  39 ++++++++------
>  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/e500.c             |   5 +-
>  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                 |  16 +++---
>  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 +++--
>  39 files changed, 266 insertions(+), 234 deletions(-)
>
> diff --git a/cpus.c b/cpus.c
> index e9bfa71..f141428 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 828007c..977c0ca 100644
> --- a/cputlb.c
> +++ b/cputlb.c
> @@ -186,11 +186,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 c812cfa..6a3a72a 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 9ca80cc..61b094a 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -69,7 +69,7 @@ static MemoryRegion io_mem_unassigned;
>
>  #endif
>
> -CPUArchState *first_cpu;
> +CPUState *first_cpu;
>  /* current CPU in the current thread. It is only valid inside
>     cpu_exec() */
>  DEFINE_TLS(CPUState *, current_cpu);
> @@ -351,27 +351,26 @@ 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;
>      }
>  }
>
> @@ -379,17 +378,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;
> @@ -399,7 +398,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
> @@ -638,7 +637,6 @@ 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;
>  #if defined(TARGET_HAS_ICE)
>      CPUBreakpoint *bp;
>      CPUWatchpoint *wp;
> @@ -646,9 +644,6 @@ CPUArchState *cpu_copy(CPUArchState *env)
>
>      memcpy(new_env, env, sizeof(CPUArchState));
>
> -    /* Preserve chaining. */
> -    new_env->next_cpu = next_cpu;
> -
>      /* Clone all break/watchpoints.
>         Note: Once we support ptrace with hw-debug register access, make sure
>         BP_CPU break/watchpoints are handled correctly on clone. */
> @@ -1757,12 +1752,14 @@ static void core_commit(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 f7d9f13..0ee82a9 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);
> @@ -2071,13 +2080,11 @@ 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);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          if (cpu_index(cpu) == thread_id) {
> -            return env;
> +            return cpu->env_ptr;
>          }
>      }
>
> @@ -2394,7 +2401,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:
> @@ -2402,7 +2409,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;
next_cpu may be NULL.

>              } else
>                  put_packet(s, "l");
>              break;
> @@ -2869,8 +2876,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;
>
> @@ -3054,8 +3061,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 7c0090f..2b33444 100644
> --- a/hw/arm/boot.c
> +++ b/hw/arm/boot.c
> @@ -333,7 +333,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) {
> @@ -351,7 +351,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;
> @@ -476,9 +476,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 de6c98a..3a2fb4c 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 b596256..3060f48 100644
> --- a/hw/arm/realview.c
> +++ b/hw/arm/realview.c
> @@ -331,7 +331,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 710413e..fd18b60 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 0dc0871..3444823 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 98e5ca5..1022d67 100644
> --- a/hw/i386/kvm/clock.c
> +++ b/hw/i386/kvm/clock.c
> @@ -33,7 +33,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;
>
> @@ -53,8 +53,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));
> @@ -124,9 +124,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 e13678f..ccd089a 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);
>      }
>  }
>
> @@ -719,8 +721,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)
> @@ -743,7 +746,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 5224256..c5d8570 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 {
> @@ -1274,8 +1278,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 01323a9..b58c255 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -229,8 +229,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 f397950..55c76e4 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 b49be4d..d1921aa 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 7e56121..de87241 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/e500.c b/hw/ppc/e500.c
> index 69837a5..9600599 100644
> --- a/hw/ppc/e500.c
> +++ b/hw/ppc/e500.c
> @@ -500,7 +500,6 @@ static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
>                                            qemu_irq **irqs)
>  {
>      DeviceState *dev;
> -    CPUPPCState *env;
>      CPUState *cs;
>      int r;
>
> @@ -512,9 +511,7 @@ static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
>          return NULL;
>      }
>
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cs = ENV_GET_CPU(env);
> -
> +    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
>          if (kvm_openpic_connect_vcpu(dev, cs)) {
>              fprintf(stderr, "%s: failed to connect vcpu to irqchip\n",
>                      __func__);
> 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 d07dd01..19f2442 100644
> --- a/hw/ppc/prep.c
> +++ b/hw/ppc/prep.c
> @@ -605,8 +605,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));
> @@ -651,7 +652,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];
>
>      portio_list_init(port_list, NULL, prep_portio_list, sysctrl, "prep");
>      portio_list_add(port_list, get_system_io(), 0x0);
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index c040794..e46aad3 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 d7fc186..a08a8ab 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 *, current_cpu);
>  #define current_cpu tls_var(current_cpu)
>
> diff --git a/kvm-all.c b/kvm-all.c
> index 2c14ef3..c130705 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1938,7 +1938,9 @@ int kvm_insert_breakpoint(CPUArchState *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;
> @@ -1979,7 +1981,9 @@ int kvm_remove_breakpoint(CPUArchState *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;
> @@ -1992,13 +1996,11 @@ void kvm_remove_all_breakpoints(CPUState *cpu)
>  {
>      struct kvm_sw_breakpoint *bp, *next;
>      KVMState *s = cpu->kvm_state;
> -    CPUArchState *env;
>
>      QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
>          if (kvm_arch_remove_sw_breakpoint(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;
>                  }
> @@ -2009,7 +2011,9 @@ void kvm_remove_all_breakpoints(CPUState *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 af82db8..564bed6 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 a2125fa..4c96f4f 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 4b557b3..935ef63 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) == NULL ||
> -            !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 e95ad4a..b0099e1 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -1579,7 +1579,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 02f8e5e..e8683d2 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	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PULL 09/43] cpu: Make first_cpu and next_cpu CPUState
@ 2013-07-11  9:14     ` TeLeMan
  0 siblings, 0 replies; 53+ messages in thread
From: TeLeMan @ 2013-07-11  9:14 UTC (permalink / raw)
  To: Andreas Färber
  Cc: Peter Maydell, Gleb Natapov, qemu-devel, Luiz Capitulino,
	Peter Crosthwaite, Edgar E. Iglesias, Igor Mitsyanko,
	Evgeny Voevodin, Alexander Graf, Andreas Färber,
	Maksim Kozlov, Riku Voipio, Paul Brook, open list:Overall,
	Scott Wood, Anthony Liguori, Mark Langsdorf, Marcelo Tosatti,
	open list:e500, Dmitry Solodkiy, Paolo Bonzini, Aurelien Jarno

On Wed, Jul 10, 2013 at 10:33 PM, Andreas Färber <afaerber@suse.de> wrote:
> Move next_cpu from CPU_COMMON to CPUState.
> Move first_cpu variable to qom/cpu.h.
>
> gdbstub needs to use CPUState::env_ptr for now.
> cpu_copy() no longer needs to save and restore cpu_next.
>
> Acked-by: Paolo Bonzini <pbonzini@redhat.com>
> [AF: Rebased, simplified cpu_copy()]
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
>  cpus.c                    | 126 ++++++++++++++++++++++++----------------------
>  cputlb.c                  |   4 +-
>  dump.c                    |  16 +++---
>  exec.c                    |  43 ++++++++--------
>  gdbstub.c                 |  39 ++++++++------
>  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/e500.c             |   5 +-
>  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                 |  16 +++---
>  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 +++--
>  39 files changed, 266 insertions(+), 234 deletions(-)
>
> diff --git a/cpus.c b/cpus.c
> index e9bfa71..f141428 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 828007c..977c0ca 100644
> --- a/cputlb.c
> +++ b/cputlb.c
> @@ -186,11 +186,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 c812cfa..6a3a72a 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 9ca80cc..61b094a 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -69,7 +69,7 @@ static MemoryRegion io_mem_unassigned;
>
>  #endif
>
> -CPUArchState *first_cpu;
> +CPUState *first_cpu;
>  /* current CPU in the current thread. It is only valid inside
>     cpu_exec() */
>  DEFINE_TLS(CPUState *, current_cpu);
> @@ -351,27 +351,26 @@ 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;
>      }
>  }
>
> @@ -379,17 +378,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;
> @@ -399,7 +398,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
> @@ -638,7 +637,6 @@ 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;
>  #if defined(TARGET_HAS_ICE)
>      CPUBreakpoint *bp;
>      CPUWatchpoint *wp;
> @@ -646,9 +644,6 @@ CPUArchState *cpu_copy(CPUArchState *env)
>
>      memcpy(new_env, env, sizeof(CPUArchState));
>
> -    /* Preserve chaining. */
> -    new_env->next_cpu = next_cpu;
> -
>      /* Clone all break/watchpoints.
>         Note: Once we support ptrace with hw-debug register access, make sure
>         BP_CPU break/watchpoints are handled correctly on clone. */
> @@ -1757,12 +1752,14 @@ static void core_commit(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 f7d9f13..0ee82a9 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);
> @@ -2071,13 +2080,11 @@ 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);
> +    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
>          if (cpu_index(cpu) == thread_id) {
> -            return env;
> +            return cpu->env_ptr;
>          }
>      }
>
> @@ -2394,7 +2401,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:
> @@ -2402,7 +2409,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;
next_cpu may be NULL.

>              } else
>                  put_packet(s, "l");
>              break;
> @@ -2869,8 +2876,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;
>
> @@ -3054,8 +3061,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 7c0090f..2b33444 100644
> --- a/hw/arm/boot.c
> +++ b/hw/arm/boot.c
> @@ -333,7 +333,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) {
> @@ -351,7 +351,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;
> @@ -476,9 +476,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 de6c98a..3a2fb4c 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 b596256..3060f48 100644
> --- a/hw/arm/realview.c
> +++ b/hw/arm/realview.c
> @@ -331,7 +331,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 710413e..fd18b60 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 0dc0871..3444823 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 98e5ca5..1022d67 100644
> --- a/hw/i386/kvm/clock.c
> +++ b/hw/i386/kvm/clock.c
> @@ -33,7 +33,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;
>
> @@ -53,8 +53,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));
> @@ -124,9 +124,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 e13678f..ccd089a 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);
>      }
>  }
>
> @@ -719,8 +721,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)
> @@ -743,7 +746,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 5224256..c5d8570 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 {
> @@ -1274,8 +1278,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 01323a9..b58c255 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -229,8 +229,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 f397950..55c76e4 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 b49be4d..d1921aa 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 7e56121..de87241 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/e500.c b/hw/ppc/e500.c
> index 69837a5..9600599 100644
> --- a/hw/ppc/e500.c
> +++ b/hw/ppc/e500.c
> @@ -500,7 +500,6 @@ static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
>                                            qemu_irq **irqs)
>  {
>      DeviceState *dev;
> -    CPUPPCState *env;
>      CPUState *cs;
>      int r;
>
> @@ -512,9 +511,7 @@ static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
>          return NULL;
>      }
>
> -    for (env = first_cpu; env != NULL; env = env->next_cpu) {
> -        cs = ENV_GET_CPU(env);
> -
> +    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
>          if (kvm_openpic_connect_vcpu(dev, cs)) {
>              fprintf(stderr, "%s: failed to connect vcpu to irqchip\n",
>                      __func__);
> 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 d07dd01..19f2442 100644
> --- a/hw/ppc/prep.c
> +++ b/hw/ppc/prep.c
> @@ -605,8 +605,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));
> @@ -651,7 +652,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];
>
>      portio_list_init(port_list, NULL, prep_portio_list, sysctrl, "prep");
>      portio_list_add(port_list, get_system_io(), 0x0);
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index c040794..e46aad3 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 d7fc186..a08a8ab 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 *, current_cpu);
>  #define current_cpu tls_var(current_cpu)
>
> diff --git a/kvm-all.c b/kvm-all.c
> index 2c14ef3..c130705 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1938,7 +1938,9 @@ int kvm_insert_breakpoint(CPUArchState *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;
> @@ -1979,7 +1981,9 @@ int kvm_remove_breakpoint(CPUArchState *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;
> @@ -1992,13 +1996,11 @@ void kvm_remove_all_breakpoints(CPUState *cpu)
>  {
>      struct kvm_sw_breakpoint *bp, *next;
>      KVMState *s = cpu->kvm_state;
> -    CPUArchState *env;
>
>      QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
>          if (kvm_arch_remove_sw_breakpoint(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;
>                  }
> @@ -2009,7 +2011,9 @@ void kvm_remove_all_breakpoints(CPUState *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 af82db8..564bed6 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 a2125fa..4c96f4f 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 4b557b3..935ef63 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) == NULL ||
> -            !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 e95ad4a..b0099e1 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -1579,7 +1579,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 02f8e5e..e8683d2 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	[flat|nested] 53+ messages in thread

* Re: [Qemu-devel] [PULL 09/43] cpu: Make first_cpu and next_cpu CPUState
  2013-07-11  9:14     ` [Qemu-devel] " TeLeMan
@ 2013-07-11  9:55       ` Andreas Färber
  -1 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-11  9:55 UTC (permalink / raw)
  To: TeLeMan
  Cc: qemu-devel, Peter Maydell, Evgeny Voevodin, Luiz Capitulino,
	Peter Crosthwaite, Edgar E. Iglesias, Igor Mitsyanko,
	Gleb Natapov, Alexander Graf, Maksim Kozlov, Riku Voipio,
	Paul Brook, kvm, Scott Wood, Anthony Liguori, Mark Langsdorf,
	Marcelo Tosatti, qemu-ppc, Dmitry Solodkiy, Paolo Bonzini,
	Aurelien Jarno

Am 11.07.2013 11:14, schrieb TeLeMan:
> On Wed, Jul 10, 2013 at 10:33 PM, Andreas Färber <afaerber@suse.de> wrote:
>> diff --git a/gdbstub.c b/gdbstub.c
>> index f7d9f13..0ee82a9 100644
>> --- a/gdbstub.c
>> +++ b/gdbstub.c
[...]
>> @@ -2394,7 +2401,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:
>> @@ -2402,7 +2409,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;
> next_cpu may be NULL.

True. If this is the only place where you've found that mistake then the
implicit fix is already queued next on qom-cpu:
http://patchwork.ozlabs.org/patch/255756/

Review and/or testing of the remaining gdbstub patches would be appreciated:
http://lists.nongnu.org/archive/html/qemu-devel/2013-07/msg01510.html
Mainly I'm waiting on an ack or feedback for the vaddr typedef to proceed.

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] 53+ messages in thread

* Re: [Qemu-devel] [PULL 09/43] cpu: Make first_cpu and next_cpu CPUState
@ 2013-07-11  9:55       ` Andreas Färber
  0 siblings, 0 replies; 53+ messages in thread
From: Andreas Färber @ 2013-07-11  9:55 UTC (permalink / raw)
  To: TeLeMan
  Cc: Peter Maydell, Anthony Liguori, Marcelo Tosatti, Igor Mitsyanko,
	Gleb Natapov, Evgeny Voevodin, Riku Voipio, qemu-devel,
	Luiz Capitulino, Peter Crosthwaite, Mark Langsdorf,
	Alexander Graf, qemu-ppc, Paul Brook, kvm, Paolo Bonzini,
	Scott Wood, Edgar E. Iglesias, Maksim Kozlov, Aurelien Jarno,
	Dmitry Solodkiy

Am 11.07.2013 11:14, schrieb TeLeMan:
> On Wed, Jul 10, 2013 at 10:33 PM, Andreas Färber <afaerber@suse.de> wrote:
>> diff --git a/gdbstub.c b/gdbstub.c
>> index f7d9f13..0ee82a9 100644
>> --- a/gdbstub.c
>> +++ b/gdbstub.c
[...]
>> @@ -2394,7 +2401,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:
>> @@ -2402,7 +2409,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;
> next_cpu may be NULL.

True. If this is the only place where you've found that mistake then the
implicit fix is already queued next on qom-cpu:
http://patchwork.ozlabs.org/patch/255756/

Review and/or testing of the remaining gdbstub patches would be appreciated:
http://lists.nongnu.org/archive/html/qemu-devel/2013-07/msg01510.html
Mainly I'm waiting on an ack or feedback for the vaddr typedef to proceed.

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] 53+ messages in thread

end of thread, other threads:[~2013-07-11  9:55 UTC | newest]

Thread overview: 53+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-10 14:33 [Qemu-devel] [PULL 00/43] QOM CPUState patch queue 2013-07-10 Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 01/43] target-openrisc: Fix typename in openrisc_cpu_class_by_name() Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 02/43] Revert "gdbstub: Simplify find_cpu()" Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 03/43] linux-user: Move cpu_clone_regs() and cpu_set_tls() into linux-user Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 04/43] cpu: Drop unnecessary dynamic casts in *_env_get_cpu() Andreas Färber
2013-07-10 14:33 ` [PULL 05/43] kvm: Free current_cpu identifier Andreas Färber
2013-07-10 14:33   ` [Qemu-devel] " Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 06/43] cpu: Replace cpu_single_env with CPUState current_cpu Andreas Färber
2013-07-10 14:33 ` [PULL 07/43] kvm: Change kvm_remove_all_breakpoints() argument to CPUState Andreas Färber
2013-07-10 14:33   ` [Qemu-devel] " Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 08/43] linux-user: Clean up do_syscall() Coding Style for TARGET_NR_exit Andreas Färber
2013-07-10 14:33 ` [PULL 09/43] cpu: Make first_cpu and next_cpu CPUState Andreas Färber
2013-07-10 14:33   ` [Qemu-devel] " Andreas Färber
2013-07-11  9:14   ` TeLeMan
2013-07-11  9:14     ` [Qemu-devel] " TeLeMan
2013-07-11  9:55     ` Andreas Färber
2013-07-11  9:55       ` Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 10/43] linux-user: Change thread_env to CPUState Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 11/43] bsd-user: " Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 12/43] intc/arm_gic: Build arm_gic only once Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 13/43] intc/openpic: Build openpic " Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 14/43] timer/arm_mptimer: Build arm_mptimer " Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 15/43] target-ppc: Don't overuse ENV_GET_CPU() Andreas Färber
2013-07-10 14:33 ` [PULL 16/43] target-s390x: " Andreas Färber
2013-07-10 14:33   ` [Qemu-devel] " Andreas Färber
2013-07-10 14:33 ` [PULL 17/43] target-s390x: Change handle_{hypercall,diag}() argument to S390CPU Andreas Färber
2013-07-10 14:33   ` [Qemu-devel] [PULL 17/43] target-s390x: Change handle_{hypercall, diag}() " Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 18/43] target-i386: Don't overuse CPUArchState Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 19/43] target-cris: gen_intermediate_code_internal() should be inlined Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 20/43] target-lm32: " Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 21/43] target-microblaze: " Andreas Färber
2013-07-10 14:33 ` [Qemu-devel] [PULL 22/43] target-moxie: " Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 23/43] target-xtensa: " Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 24/43] target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 25/43] target-arm: Change gen_intermediate_code_internal() argument to ARMCPU Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 26/43] target-cris: Change gen_intermediate_code_internal() argument to CRISCPU Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 27/43] target-i386: Change gen_intermediate_code_internal() argument to X86CPU Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 28/43] target-lm32: Change gen_intermediate_code_internal() argument to LM32CPU Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 29/43] target-m68k: Change gen_intermediate_code_internal() argument to M68kCPU Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 30/43] target-microblaze: Change gen_intermediate_code_internal() argument types Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 31/43] target-mips: Change gen_intermediate_code_internal() argument to MIPSCPU Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 32/43] target-ppc: Change gen_intermediate_code_internal() argument to PowerPCCPU Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 33/43] target-s390x: Change gen_intermediate_code_internal() argument to S390CPU Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 34/43] target-sh4: Change gen_intermediate_code_internal() argument to SuperHCPU Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 35/43] target-sparc: Change gen_intermediate_code_internal() argument to SPARCCPU Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 36/43] target-unicore32: Change gen_intermediate_code_internal() signature Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 37/43] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 38/43] target-i386: Change do_interrupt_all() argument to X86CPU Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 39/43] target-i386: Change do_smm_enter() " Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 40/43] log: Change log_cpu_state[_mask]() argument to CPUState Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 41/43] target-i386: Change LOG_PCALL_STATE() " Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 42/43] target-ppc: Change LOG_MMU_STATE() " Andreas Färber
2013-07-10 14:34 ` [Qemu-devel] [PULL 43/43] cpu: Move reset logging " 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.