Patchwork [29/35] cpus: Pass CPUState to [qemu_]cpu_has_work()

login
register
mail settings
Submitter Andreas Färber
Date Oct. 31, 2012, 1 a.m.
Message ID <1351645206-3041-30-git-send-email-afaerber@suse.de>
Download mbox | patch
Permalink /patch/195716/
State New
Headers show

Comments

Andreas Färber - Oct. 31, 2012, 1 a.m.
For target-mips also change the return type to bool.

Make include paths for cpu-qom.h consistent for alpha and unicore32.

Signed-off-by: Andreas Färber <afaerber@suse.de>
[AF: Updated new target-openrisc function accordingly]
---
 cpu-all.h               |    2 --
 cpu-exec.c              |    8 +++-----
 cpus.c                  |    2 +-
 hw/spapr_hcall.c        |    2 +-
 hw/xtensa_pic.c         |    2 +-
 include/qemu/cpu.h      |   10 ++++++++++
 target-alpha/cpu.c      |    2 +-
 target-alpha/cpu.h      |    4 +++-
 target-arm/cpu.h        |    4 +++-
 target-cris/cpu.h       |    4 +++-
 target-i386/cpu.h       |    4 +++-
 target-lm32/cpu.h       |    4 +++-
 target-m68k/cpu.h       |    4 +++-
 target-microblaze/cpu.h |    4 +++-
 target-mips/cpu.h       |   11 ++++++-----
 target-openrisc/cpu.h   |    4 +++-
 target-ppc/cpu.h        |    4 +++-
 target-s390x/cpu.h      |    4 +++-
 target-sh4/cpu.h        |    4 +++-
 target-sparc/cpu.h      |    4 +++-
 target-unicore32/cpu.c  |    2 +-
 target-unicore32/cpu.h  |    4 +++-
 target-xtensa/cpu.h     |    4 +++-
 23 Dateien geändert, 66 Zeilen hinzugefügt(+), 31 Zeilen entfernt(-)
Aurelien Jarno - Oct. 31, 2012, 9:05 p.m.
On Wed, Oct 31, 2012 at 02:00:00AM +0100, Andreas Färber wrote:
> For target-mips also change the return type to bool.
> 
> Make include paths for cpu-qom.h consistent for alpha and unicore32.
> 
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> [AF: Updated new target-openrisc function accordingly]
> ---
>  cpu-all.h               |    2 --
>  cpu-exec.c              |    8 +++-----
>  cpus.c                  |    2 +-
>  hw/spapr_hcall.c        |    2 +-
>  hw/xtensa_pic.c         |    2 +-
>  include/qemu/cpu.h      |   10 ++++++++++
>  target-alpha/cpu.c      |    2 +-
>  target-alpha/cpu.h      |    4 +++-
>  target-arm/cpu.h        |    4 +++-
>  target-cris/cpu.h       |    4 +++-
>  target-i386/cpu.h       |    4 +++-
>  target-lm32/cpu.h       |    4 +++-
>  target-m68k/cpu.h       |    4 +++-
>  target-microblaze/cpu.h |    4 +++-
>  target-mips/cpu.h       |   11 ++++++-----
>  target-openrisc/cpu.h   |    4 +++-
>  target-ppc/cpu.h        |    4 +++-
>  target-s390x/cpu.h      |    4 +++-
>  target-sh4/cpu.h        |    4 +++-
>  target-sparc/cpu.h      |    4 +++-
>  target-unicore32/cpu.c  |    2 +-
>  target-unicore32/cpu.h  |    4 +++-
>  target-xtensa/cpu.h     |    4 +++-
>  23 Dateien geändert, 66 Zeilen hinzugefügt(+), 31 Zeilen entfernt(-)
> 
> diff --git a/cpu-all.h b/cpu-all.h
> index d19ec12..0356684 100644
> --- a/cpu-all.h
> +++ b/cpu-all.h
> @@ -438,8 +438,6 @@ void cpu_reset_interrupt(CPUArchState *env, int mask);
>  
>  void cpu_exit(CPUArchState *s);
>  
> -bool qemu_cpu_has_work(CPUArchState *env);
> -
>  /* Breakpoint/watchpoint flags */
>  #define BP_MEM_READ           0x01
>  #define BP_MEM_WRITE          0x02
> diff --git a/cpu-exec.c b/cpu-exec.c
> index 252da86..904ee73 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -27,9 +27,9 @@ int tb_invalidated_flag;
>  
>  //#define CONFIG_DEBUG_EXEC
>  
> -bool qemu_cpu_has_work(CPUArchState *env)
> +bool qemu_cpu_has_work(CPUState *cpu)
>  {
> -    return cpu_has_work(env);
> +    return cpu_has_work(cpu);
>  }
>  
>  void cpu_loop_exit(CPUArchState *env)
> @@ -181,16 +181,14 @@ volatile sig_atomic_t exit_request;
>  
>  int cpu_exec(CPUArchState *env)
>  {
> -#ifdef TARGET_PPC
>      CPUState *cpu = ENV_GET_CPU(env);
> -#endif
>      int ret, interrupt_request;
>      TranslationBlock *tb;
>      uint8_t *tc_ptr;
>      tcg_target_ulong next_tb;
>  
>      if (env->halted) {
> -        if (!cpu_has_work(env)) {
> +        if (!cpu_has_work(cpu)) {
>              return EXCP_HALTED;
>          }
>  
> diff --git a/cpus.c b/cpus.c
> index 6baf2bc..76f32fc 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -72,7 +72,7 @@ static bool cpu_thread_is_idle(CPUArchState *env)
>      if (cpu->stopped || !runstate_is_running()) {
>          return true;
>      }
> -    if (!env->halted || qemu_cpu_has_work(env) ||
> +    if (!env->halted || qemu_cpu_has_work(cpu) ||
>          kvm_async_interrupts_enabled()) {
>          return false;
>      }
> diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
> index c6d55da..63cadb8 100644
> --- a/hw/spapr_hcall.c
> +++ b/hw/spapr_hcall.c
> @@ -516,7 +516,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>  
>      env->msr |= (1ULL << MSR_EE);
>      hreg_compute_hflags(env);
> -    if (!cpu_has_work(env)) {
> +    if (!cpu_has_work(CPU(cpu))) {
>          env->halted = 1;
>          env->exception_index = EXCP_HLT;
>          env->exit_request = 1;
> diff --git a/hw/xtensa_pic.c b/hw/xtensa_pic.c
> index 8b9c051..1ec70cd 100644
> --- a/hw/xtensa_pic.c
> +++ b/hw/xtensa_pic.c
> @@ -131,7 +131,7 @@ static void xtensa_ccompare_cb(void *opaque)
>      if (env->halted) {
>          env->halt_clock = qemu_get_clock_ns(vm_clock);
>          xtensa_advance_ccount(env, env->wake_ccount - env->sregs[CCOUNT]);
> -        if (!cpu_has_work(env)) {
> +        if (!cpu_has_work(CPU(cpu))) {
>              env->sregs[CCOUNT] = env->wake_ccount + 1;
>              xtensa_rearm_ccompare_timer(env);
>          }
> diff --git a/include/qemu/cpu.h b/include/qemu/cpu.h
> index eea6175..f04da6e 100644
> --- a/include/qemu/cpu.h
> +++ b/include/qemu/cpu.h
> @@ -87,6 +87,16 @@ struct CPUState {
>  void cpu_reset(CPUState *cpu);
>  
>  /**
> + * qemu_cpu_has_work:
> + * @cpu: The vCPU to check.
> + *
> + * Checks whether the CPU has work to do.
> + *
> + * Returns: %true if the CPU has work, %false otherwise.
> + */
> +bool qemu_cpu_has_work(CPUState *cpu);
> +
> +/**
>   * qemu_cpu_is_self:
>   * @cpu: The vCPU to check against.
>   *
> diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
> index 62d2a66..11a19eb 100644
> --- a/target-alpha/cpu.c
> +++ b/target-alpha/cpu.c
> @@ -19,7 +19,7 @@
>   * <http://www.gnu.org/licenses/lgpl-2.1.html>
>   */
>  
> -#include "cpu-qom.h"
> +#include "cpu.h"
>  #include "qemu-common.h"
>  
>  
> diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
> index 8f131b7..34221fb 100644
> --- a/target-alpha/cpu.h
> +++ b/target-alpha/cpu.h
> @@ -510,8 +510,10 @@ static inline void cpu_set_tls(CPUAlphaState *env, target_ulong newtls)
>  }
>  #endif
>  
> -static inline bool cpu_has_work(CPUAlphaState *env)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> +    CPUAlphaState *env = &ALPHA_CPU(cpu)->env;
> +
>      /* Here we are checking to see if the CPU should wake up from HALT.
>         We will have gotten into this state only for WTINT from PALmode.  */
>      /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index ff4de10..e4ff918 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -718,8 +718,10 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
>      }
>  }
>  
> -static inline bool cpu_has_work(CPUARMState *env)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> +    CPUARMState *env = &ARM_CPU(cpu)->env;
> +
>      return env->interrupt_request &
>          (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
>  }
> diff --git a/target-cris/cpu.h b/target-cris/cpu.h
> index 4f4df6d..2c27506 100644
> --- a/target-cris/cpu.h
> +++ b/target-cris/cpu.h
> @@ -285,8 +285,10 @@ static inline void cpu_get_tb_cpu_state(CPUCRISState *env, target_ulong *pc,
>  #define cpu_list cris_cpu_list
>  void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf);
>  
> -static inline bool cpu_has_work(CPUCRISState *env)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> +    CPUCRISState *env = &CRIS_CPU(cpu)->env;
> +
>      return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
>  }
>  
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index d840914..2d7b4c3 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -1100,8 +1100,10 @@ static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp)
>  #include "hw/apic.h"
>  #endif
>  
> -static inline bool cpu_has_work(CPUX86State *env)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> +    CPUX86State *env = &X86_CPU(cpu)->env;
> +
>      return ((env->interrupt_request & (CPU_INTERRUPT_HARD |
>                                         CPU_INTERRUPT_POLL)) &&
>              (env->eflags & IF_MASK)) ||
> diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
> index da80469..7243b4f 100644
> --- a/target-lm32/cpu.h
> +++ b/target-lm32/cpu.h
> @@ -253,8 +253,10 @@ static inline void cpu_get_tb_cpu_state(CPULM32State *env, target_ulong *pc,
>      *flags = 0;
>  }
>  
> -static inline bool cpu_has_work(CPULM32State *env)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> +    CPULM32State *env = &LM32_CPU(cpu)->env;
> +
>      return env->interrupt_request & CPU_INTERRUPT_HARD;
>  }
>  
> diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
> index 5e6ee50..780e2c9 100644
> --- a/target-m68k/cpu.h
> +++ b/target-m68k/cpu.h
> @@ -257,8 +257,10 @@ static inline void cpu_get_tb_cpu_state(CPUM68KState *env, target_ulong *pc,
>              | ((env->macsr >> 4) & 0xf);        /* Bits 0-3 */
>  }
>  
> -static inline bool cpu_has_work(CPUM68KState *env)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> +    CPUM68KState *env = &M68K_CPU(cpu)->env;
> +
>      return env->interrupt_request & CPU_INTERRUPT_HARD;
>  }
>  
> diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
> index 37bbdf1..585bbd6 100644
> --- a/target-microblaze/cpu.h
> +++ b/target-microblaze/cpu.h
> @@ -374,8 +374,10 @@ void cpu_unassigned_access(CPUMBState *env1, hwaddr addr,
>                             int is_write, int is_exec, int is_asi, int size);
>  #endif
>  
> -static inline bool cpu_has_work(CPUMBState *env)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> +    CPUMBState *env = &MICROBLAZE_CPU(cpu)->env;
> +
>      return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
>  }
>  
> diff --git a/target-mips/cpu.h b/target-mips/cpu.h
> index c4ca285..38943de 100644
> --- a/target-mips/cpu.h
> +++ b/target-mips/cpu.h
> @@ -706,16 +706,17 @@ static inline int mips_vpe_active(CPUMIPSState *env)
>      return active;
>  }
>  
> -static inline int cpu_has_work(CPUMIPSState *env)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> -    int has_work = 0;
> +    CPUMIPSState *env = &MIPS_CPU(cpu)->env;
> +    bool has_work = false;
>  
>      /* It is implementation dependent if non-enabled interrupts
>         wake-up the CPU, however most of the implementations only
>         check for interrupts that can be taken. */
>      if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
>          cpu_mips_hw_interrupts_pending(env)) {
> -        has_work = 1;
> +        has_work = true;
>      }
>  
>      /* MIPS-MT has the ability to halt the CPU.  */
> @@ -723,11 +724,11 @@ static inline int cpu_has_work(CPUMIPSState *env)
>          /* The QEMU model will issue an _WAKE request whenever the CPUs
>             should be woken up.  */
>          if (env->interrupt_request & CPU_INTERRUPT_WAKE) {
> -            has_work = 1;
> +            has_work = true;
>          }
>  
>          if (!mips_vpe_active(env)) {
> -            has_work = 0;
> +            has_work = false;
>          }
>      }
>      return has_work;
> diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
> index a701d36..d42ffb0 100644
> --- a/target-openrisc/cpu.h
> +++ b/target-openrisc/cpu.h
> @@ -437,8 +437,10 @@ static inline int cpu_mmu_index(CPUOpenRISCState *env)
>  }
>  
>  #define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
> -static inline bool cpu_has_work(CPUOpenRISCState *env)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> +    CPUOpenRISCState *env = &OPENRISC_CPU(cpu)->env;
> +
>      return env->interrupt_request & (CPU_INTERRUPT_HARD |
>                                       CPU_INTERRUPT_TIMER);
>  }
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index 5574042..ed491d2 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -2222,8 +2222,10 @@ static inline bool msr_is_64bit(CPUPPCState *env, target_ulong msr)
>  
>  extern void (*cpu_ppc_hypercall)(PowerPCCPU *);
>  
> -static inline bool cpu_has_work(CPUPPCState *env)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> +    CPUPPCState *env = &POWERPC_CPU(cpu)->env;
> +
>      return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD);
>  }
>  
> diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
> index 5be6e83..0f9a1f7 100644
> --- a/target-s390x/cpu.h
> +++ b/target-s390x/cpu.h
> @@ -977,8 +977,10 @@ static inline void cpu_inject_ext(CPUS390XState *env, uint32_t code, uint32_t pa
>      cpu_interrupt(env, CPU_INTERRUPT_HARD);
>  }
>  
> -static inline bool cpu_has_work(CPUS390XState *env)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> +    CPUS390XState *env = &S390_CPU(cpu)->env;
> +
>      return (env->interrupt_request & CPU_INTERRUPT_HARD) &&
>          (env->psw.mask & PSW_MASK_EXT);
>  }
> diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
> index 782159e..9a0e72b 100644
> --- a/target-sh4/cpu.h
> +++ b/target-sh4/cpu.h
> @@ -371,8 +371,10 @@ static inline void cpu_get_tb_cpu_state(CPUSH4State *env, target_ulong *pc,
>              | (env->movcal_backup ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 4 */
>  }
>  
> -static inline bool cpu_has_work(CPUSH4State *env)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> +    CPUSH4State *env = &SUPERH_CPU(cpu)->env;
> +
>      return env->interrupt_request & CPU_INTERRUPT_HARD;
>  }
>  
> diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
> index a55fe08..6aa82b3 100644
> --- a/target-sparc/cpu.h
> +++ b/target-sparc/cpu.h
> @@ -764,8 +764,10 @@ static inline bool tb_am_enabled(int tb_flags)
>  #endif
>  }
>  
> -static inline bool cpu_has_work(CPUSPARCState *env1)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> +    CPUSPARCState *env1 = &SPARC_CPU(cpu)->env;
> +
>      return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
>             cpu_interrupts_enabled(env1);
>  }
> diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
> index 3425bbe..884c101 100644
> --- a/target-unicore32/cpu.c
> +++ b/target-unicore32/cpu.c
> @@ -12,7 +12,7 @@
>   * or (at your option) any later version.
>   */
>  
> -#include "cpu-qom.h"
> +#include "cpu.h"
>  #include "qemu-common.h"
>  
>  static inline void set_feature(CPUUniCore32State *env, int feature)
> diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
> index 06508a1..676c5d9 100644
> --- a/target-unicore32/cpu.h
> +++ b/target-unicore32/cpu.h
> @@ -181,8 +181,10 @@ void uc32_translate_init(void);
>  void do_interrupt(CPUUniCore32State *);
>  void switch_mode(CPUUniCore32State *, int);
>  
> -static inline bool cpu_has_work(CPUUniCore32State *env)
> +static inline bool cpu_has_work(CPUState *cpu)
>  {
> +    CPUUniCore32State *env = &UNICORE32_CPU(cpu)->env;
> +
>      return env->interrupt_request &
>          (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
>  }
> diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
> index 7348277..74e9888 100644
> --- a/target-xtensa/cpu.h
> +++ b/target-xtensa/cpu.h
> @@ -501,8 +501,10 @@ static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
>  #include "cpu-all.h"
>  #include "exec-all.h"
>  
> -static inline int cpu_has_work(CPUXtensaState *env)
> +static inline int cpu_has_work(CPUState *cpu)
>  {
> +    CPUXtensaState *env = &XTENSA_CPU(cpu)->env;
> +
>      return env->pending_irq_level;
>  }
>  

I find strange to see a pull request for something that hasn't been sent
on the list before. That said MIPS part is

Acked-by: Aurelien Jarno <aurelien@aurel32.net>
Andreas Färber - Oct. 31, 2012, 9:37 p.m.
Am 31.10.2012 22:05, schrieb Aurelien Jarno:
> On Wed, Oct 31, 2012 at 02:00:00AM +0100, Andreas Färber wrote:
>> For target-mips also change the return type to bool.
>>
>> Make include paths for cpu-qom.h consistent for alpha and unicore32.
>>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>> [AF: Updated new target-openrisc function accordingly]
[...]
> I find strange to see a pull request for something that hasn't been sent
> on the list before. That said MIPS part is
> 
> Acked-by: Aurelien Jarno <aurelien@aurel32.net>

The patch has been on the list before [1], I just spared me a v2 for the
rebase (therefore the marking above) due to the upcoming Soft Freeze.
The responsiveness to these CPUState patches has generally been low in
the past, especially when cross-target, and most of them are rather trivial.

Andreas

[1] http://patchwork.ozlabs.org/patch/160822/
Aurelien Jarno - Oct. 31, 2012, 9:47 p.m.
On Wed, Oct 31, 2012 at 10:37:41PM +0100, Andreas Färber wrote:
> Am 31.10.2012 22:05, schrieb Aurelien Jarno:
> > On Wed, Oct 31, 2012 at 02:00:00AM +0100, Andreas Färber wrote:
> >> For target-mips also change the return type to bool.
> >>
> >> Make include paths for cpu-qom.h consistent for alpha and unicore32.
> >>
> >> Signed-off-by: Andreas Färber <afaerber@suse.de>
> >> [AF: Updated new target-openrisc function accordingly]
> [...]
> > I find strange to see a pull request for something that hasn't been sent
> > on the list before. That said MIPS part is
> > 
> > Acked-by: Aurelien Jarno <aurelien@aurel32.net>
> 
> The patch has been on the list before [1], I just spared me a v2 for the
> rebase (therefore the marking above) due to the upcoming Soft Freeze.
> The responsiveness to these CPUState patches has generally been low in
> the past, especially when cross-target, and most of them are rather trivial.
> 

Ok, then I missed it. Sorry about that.

Patch

diff --git a/cpu-all.h b/cpu-all.h
index d19ec12..0356684 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -438,8 +438,6 @@  void cpu_reset_interrupt(CPUArchState *env, int mask);
 
 void cpu_exit(CPUArchState *s);
 
-bool qemu_cpu_has_work(CPUArchState *env);
-
 /* Breakpoint/watchpoint flags */
 #define BP_MEM_READ           0x01
 #define BP_MEM_WRITE          0x02
diff --git a/cpu-exec.c b/cpu-exec.c
index 252da86..904ee73 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -27,9 +27,9 @@  int tb_invalidated_flag;
 
 //#define CONFIG_DEBUG_EXEC
 
-bool qemu_cpu_has_work(CPUArchState *env)
+bool qemu_cpu_has_work(CPUState *cpu)
 {
-    return cpu_has_work(env);
+    return cpu_has_work(cpu);
 }
 
 void cpu_loop_exit(CPUArchState *env)
@@ -181,16 +181,14 @@  volatile sig_atomic_t exit_request;
 
 int cpu_exec(CPUArchState *env)
 {
-#ifdef TARGET_PPC
     CPUState *cpu = ENV_GET_CPU(env);
-#endif
     int ret, interrupt_request;
     TranslationBlock *tb;
     uint8_t *tc_ptr;
     tcg_target_ulong next_tb;
 
     if (env->halted) {
-        if (!cpu_has_work(env)) {
+        if (!cpu_has_work(cpu)) {
             return EXCP_HALTED;
         }
 
diff --git a/cpus.c b/cpus.c
index 6baf2bc..76f32fc 100644
--- a/cpus.c
+++ b/cpus.c
@@ -72,7 +72,7 @@  static bool cpu_thread_is_idle(CPUArchState *env)
     if (cpu->stopped || !runstate_is_running()) {
         return true;
     }
-    if (!env->halted || qemu_cpu_has_work(env) ||
+    if (!env->halted || qemu_cpu_has_work(cpu) ||
         kvm_async_interrupts_enabled()) {
         return false;
     }
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index c6d55da..63cadb8 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -516,7 +516,7 @@  static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 
     env->msr |= (1ULL << MSR_EE);
     hreg_compute_hflags(env);
-    if (!cpu_has_work(env)) {
+    if (!cpu_has_work(CPU(cpu))) {
         env->halted = 1;
         env->exception_index = EXCP_HLT;
         env->exit_request = 1;
diff --git a/hw/xtensa_pic.c b/hw/xtensa_pic.c
index 8b9c051..1ec70cd 100644
--- a/hw/xtensa_pic.c
+++ b/hw/xtensa_pic.c
@@ -131,7 +131,7 @@  static void xtensa_ccompare_cb(void *opaque)
     if (env->halted) {
         env->halt_clock = qemu_get_clock_ns(vm_clock);
         xtensa_advance_ccount(env, env->wake_ccount - env->sregs[CCOUNT]);
-        if (!cpu_has_work(env)) {
+        if (!cpu_has_work(CPU(cpu))) {
             env->sregs[CCOUNT] = env->wake_ccount + 1;
             xtensa_rearm_ccompare_timer(env);
         }
diff --git a/include/qemu/cpu.h b/include/qemu/cpu.h
index eea6175..f04da6e 100644
--- a/include/qemu/cpu.h
+++ b/include/qemu/cpu.h
@@ -87,6 +87,16 @@  struct CPUState {
 void cpu_reset(CPUState *cpu);
 
 /**
+ * qemu_cpu_has_work:
+ * @cpu: The vCPU to check.
+ *
+ * Checks whether the CPU has work to do.
+ *
+ * Returns: %true if the CPU has work, %false otherwise.
+ */
+bool qemu_cpu_has_work(CPUState *cpu);
+
+/**
  * qemu_cpu_is_self:
  * @cpu: The vCPU to check against.
  *
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index 62d2a66..11a19eb 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -19,7 +19,7 @@ 
  * <http://www.gnu.org/licenses/lgpl-2.1.html>
  */
 
-#include "cpu-qom.h"
+#include "cpu.h"
 #include "qemu-common.h"
 
 
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 8f131b7..34221fb 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -510,8 +510,10 @@  static inline void cpu_set_tls(CPUAlphaState *env, target_ulong newtls)
 }
 #endif
 
-static inline bool cpu_has_work(CPUAlphaState *env)
+static inline bool cpu_has_work(CPUState *cpu)
 {
+    CPUAlphaState *env = &ALPHA_CPU(cpu)->env;
+
     /* Here we are checking to see if the CPU should wake up from HALT.
        We will have gotten into this state only for WTINT from PALmode.  */
     /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index ff4de10..e4ff918 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -718,8 +718,10 @@  static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
     }
 }
 
-static inline bool cpu_has_work(CPUARMState *env)
+static inline bool cpu_has_work(CPUState *cpu)
 {
+    CPUARMState *env = &ARM_CPU(cpu)->env;
+
     return env->interrupt_request &
         (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
 }
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index 4f4df6d..2c27506 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -285,8 +285,10 @@  static inline void cpu_get_tb_cpu_state(CPUCRISState *env, target_ulong *pc,
 #define cpu_list cris_cpu_list
 void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 
-static inline bool cpu_has_work(CPUCRISState *env)
+static inline bool cpu_has_work(CPUState *cpu)
 {
+    CPUCRISState *env = &CRIS_CPU(cpu)->env;
+
     return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 }
 
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index d840914..2d7b4c3 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1100,8 +1100,10 @@  static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp)
 #include "hw/apic.h"
 #endif
 
-static inline bool cpu_has_work(CPUX86State *env)
+static inline bool cpu_has_work(CPUState *cpu)
 {
+    CPUX86State *env = &X86_CPU(cpu)->env;
+
     return ((env->interrupt_request & (CPU_INTERRUPT_HARD |
                                        CPU_INTERRUPT_POLL)) &&
             (env->eflags & IF_MASK)) ||
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index da80469..7243b4f 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -253,8 +253,10 @@  static inline void cpu_get_tb_cpu_state(CPULM32State *env, target_ulong *pc,
     *flags = 0;
 }
 
-static inline bool cpu_has_work(CPULM32State *env)
+static inline bool cpu_has_work(CPUState *cpu)
 {
+    CPULM32State *env = &LM32_CPU(cpu)->env;
+
     return env->interrupt_request & CPU_INTERRUPT_HARD;
 }
 
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 5e6ee50..780e2c9 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -257,8 +257,10 @@  static inline void cpu_get_tb_cpu_state(CPUM68KState *env, target_ulong *pc,
             | ((env->macsr >> 4) & 0xf);        /* Bits 0-3 */
 }
 
-static inline bool cpu_has_work(CPUM68KState *env)
+static inline bool cpu_has_work(CPUState *cpu)
 {
+    CPUM68KState *env = &M68K_CPU(cpu)->env;
+
     return env->interrupt_request & CPU_INTERRUPT_HARD;
 }
 
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 37bbdf1..585bbd6 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -374,8 +374,10 @@  void cpu_unassigned_access(CPUMBState *env1, hwaddr addr,
                            int is_write, int is_exec, int is_asi, int size);
 #endif
 
-static inline bool cpu_has_work(CPUMBState *env)
+static inline bool cpu_has_work(CPUState *cpu)
 {
+    CPUMBState *env = &MICROBLAZE_CPU(cpu)->env;
+
     return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 }
 
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index c4ca285..38943de 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -706,16 +706,17 @@  static inline int mips_vpe_active(CPUMIPSState *env)
     return active;
 }
 
-static inline int cpu_has_work(CPUMIPSState *env)
+static inline bool cpu_has_work(CPUState *cpu)
 {
-    int has_work = 0;
+    CPUMIPSState *env = &MIPS_CPU(cpu)->env;
+    bool has_work = false;
 
     /* It is implementation dependent if non-enabled interrupts
        wake-up the CPU, however most of the implementations only
        check for interrupts that can be taken. */
     if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
         cpu_mips_hw_interrupts_pending(env)) {
-        has_work = 1;
+        has_work = true;
     }
 
     /* MIPS-MT has the ability to halt the CPU.  */
@@ -723,11 +724,11 @@  static inline int cpu_has_work(CPUMIPSState *env)
         /* The QEMU model will issue an _WAKE request whenever the CPUs
            should be woken up.  */
         if (env->interrupt_request & CPU_INTERRUPT_WAKE) {
-            has_work = 1;
+            has_work = true;
         }
 
         if (!mips_vpe_active(env)) {
-            has_work = 0;
+            has_work = false;
         }
     }
     return has_work;
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index a701d36..d42ffb0 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -437,8 +437,10 @@  static inline int cpu_mmu_index(CPUOpenRISCState *env)
 }
 
 #define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
-static inline bool cpu_has_work(CPUOpenRISCState *env)
+static inline bool cpu_has_work(CPUState *cpu)
 {
+    CPUOpenRISCState *env = &OPENRISC_CPU(cpu)->env;
+
     return env->interrupt_request & (CPU_INTERRUPT_HARD |
                                      CPU_INTERRUPT_TIMER);
 }
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 5574042..ed491d2 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -2222,8 +2222,10 @@  static inline bool msr_is_64bit(CPUPPCState *env, target_ulong msr)
 
 extern void (*cpu_ppc_hypercall)(PowerPCCPU *);
 
-static inline bool cpu_has_work(CPUPPCState *env)
+static inline bool cpu_has_work(CPUState *cpu)
 {
+    CPUPPCState *env = &POWERPC_CPU(cpu)->env;
+
     return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD);
 }
 
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 5be6e83..0f9a1f7 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -977,8 +977,10 @@  static inline void cpu_inject_ext(CPUS390XState *env, uint32_t code, uint32_t pa
     cpu_interrupt(env, CPU_INTERRUPT_HARD);
 }
 
-static inline bool cpu_has_work(CPUS390XState *env)
+static inline bool cpu_has_work(CPUState *cpu)
 {
+    CPUS390XState *env = &S390_CPU(cpu)->env;
+
     return (env->interrupt_request & CPU_INTERRUPT_HARD) &&
         (env->psw.mask & PSW_MASK_EXT);
 }
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 782159e..9a0e72b 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -371,8 +371,10 @@  static inline void cpu_get_tb_cpu_state(CPUSH4State *env, target_ulong *pc,
             | (env->movcal_backup ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 4 */
 }
 
-static inline bool cpu_has_work(CPUSH4State *env)
+static inline bool cpu_has_work(CPUState *cpu)
 {
+    CPUSH4State *env = &SUPERH_CPU(cpu)->env;
+
     return env->interrupt_request & CPU_INTERRUPT_HARD;
 }
 
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index a55fe08..6aa82b3 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -764,8 +764,10 @@  static inline bool tb_am_enabled(int tb_flags)
 #endif
 }
 
-static inline bool cpu_has_work(CPUSPARCState *env1)
+static inline bool cpu_has_work(CPUState *cpu)
 {
+    CPUSPARCState *env1 = &SPARC_CPU(cpu)->env;
+
     return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
            cpu_interrupts_enabled(env1);
 }
diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
index 3425bbe..884c101 100644
--- a/target-unicore32/cpu.c
+++ b/target-unicore32/cpu.c
@@ -12,7 +12,7 @@ 
  * or (at your option) any later version.
  */
 
-#include "cpu-qom.h"
+#include "cpu.h"
 #include "qemu-common.h"
 
 static inline void set_feature(CPUUniCore32State *env, int feature)
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index 06508a1..676c5d9 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -181,8 +181,10 @@  void uc32_translate_init(void);
 void do_interrupt(CPUUniCore32State *);
 void switch_mode(CPUUniCore32State *, int);
 
-static inline bool cpu_has_work(CPUUniCore32State *env)
+static inline bool cpu_has_work(CPUState *cpu)
 {
+    CPUUniCore32State *env = &UNICORE32_CPU(cpu)->env;
+
     return env->interrupt_request &
         (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
 }
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 7348277..74e9888 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -501,8 +501,10 @@  static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
 #include "cpu-all.h"
 #include "exec-all.h"
 
-static inline int cpu_has_work(CPUXtensaState *env)
+static inline int cpu_has_work(CPUState *cpu)
 {
+    CPUXtensaState *env = &XTENSA_CPU(cpu)->env;
+
     return env->pending_irq_level;
 }