Skip to content

Commit

Permalink
cpu: Turn cpu_dump_{state,statistics}() into CPUState hooks
Browse files Browse the repository at this point in the history
Make cpustats monitor command available unconditionally.

Prepares for changing kvm_handle_internal_error() and kvm_cpu_exec()
arguments to CPUState.

Signed-off-by: Andreas Färber <[email protected]>
  • Loading branch information
afaerber committed Jun 28, 2013
1 parent 13618e0 commit 878096e
Show file tree
Hide file tree
Showing 63 changed files with 242 additions and 86 deletions.
3 changes: 2 additions & 1 deletion bsd-user/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ static void flush_windows(CPUSPARCState *env)

void cpu_loop(CPUSPARCState *env)
{
CPUState *cs = CPU(sparc_env_get_cpu(env));
int trapnr, ret, syscall_nr;
//target_siginfo_t info;

Expand Down Expand Up @@ -659,7 +660,7 @@ void cpu_loop(CPUSPARCState *env)
badtrap:
#endif
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
exit (1);
}
process_pending_signals (env);
Expand Down
2 changes: 1 addition & 1 deletion cpus.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ void hw_error(const char *fmt, ...)
for (env = first_cpu; env != NULL; env = env->next_cpu) {
cpu = ENV_GET_CPU(env);
fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
cpu_dump_state(env, stderr, fprintf, CPU_DUMP_FPU);
cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU);
}
va_end(ap);
abort();
Expand Down
3 changes: 2 additions & 1 deletion exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ void cpu_single_step(CPUArchState *env, int enabled)

void cpu_abort(CPUArchState *env, const char *fmt, ...)
{
CPUState *cpu = ENV_GET_CPU(env);
va_list ap;
va_list ap2;

Expand All @@ -608,7 +609,7 @@ void cpu_abort(CPUArchState *env, const char *fmt, ...)
fprintf(stderr, "qemu: fatal: ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
cpu_dump_state(env, stderr, fprintf, CPU_DUMP_FPU | CPU_DUMP_CCOP);
cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU | CPU_DUMP_CCOP);
if (qemu_log_enabled()) {
qemu_log("qemu: fatal: ");
qemu_log_vprintf(fmt, ap2);
Expand Down
10 changes: 0 additions & 10 deletions include/exec/cpu-all.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,16 +355,6 @@ int page_check_range(target_ulong start, target_ulong len, int flags);

CPUArchState *cpu_copy(CPUArchState *env);

#define CPU_DUMP_CODE 0x00010000
#define CPU_DUMP_FPU 0x00020000 /* dump FPU register state, not just integer */
/* dump info about TCG QEMU's condition code optimization state */
#define CPU_DUMP_CCOP 0x00040000

void cpu_dump_state(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
int flags);
void cpu_dump_statistics(CPUArchState *env, FILE *f, fprintf_function cpu_fprintf,
int flags);

void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
GCC_FMT_ATTR(2, 3);
extern CPUArchState *first_cpu;
Expand Down
2 changes: 1 addition & 1 deletion include/qemu/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void GCC_FMT_ATTR(2, 3) qemu_log_mask(int mask, const char *fmt, ...);
static inline void log_cpu_state(CPUArchState *env1, int flags)
{
if (qemu_log_enabled()) {
cpu_dump_state(env1, qemu_logfile, fprintf, flags);
cpu_dump_state(ENV_GET_CPU(env1), qemu_logfile, fprintf, flags);
}
}

Expand Down
42 changes: 42 additions & 0 deletions include/qom/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ typedef struct CPUState CPUState;
* instantiatable CPU type.
* @reset: Callback to reset the #CPUState to its initial state.
* @do_interrupt: Callback for interrupt handling.
* @dump_state: Callback for dumping state.
* @dump_statistics: Callback for dumping statistics.
* @get_arch_id: Callback for getting architecture-dependent CPU ID.
* @get_paging_enabled: Callback for inquiring whether paging is enabled.
* @get_memory_mapping: Callback for obtaining the memory mappings.
Expand All @@ -64,6 +66,10 @@ typedef struct CPUClass {

void (*reset)(CPUState *cpu);
void (*do_interrupt)(CPUState *cpu);
void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags);
void (*dump_statistics)(CPUState *cpu, FILE *f,
fprintf_function cpu_fprintf, int flags);
int64_t (*get_arch_id)(CPUState *cpu);
bool (*get_paging_enabled)(const CPUState *cpu);
void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
Expand Down Expand Up @@ -200,6 +206,42 @@ int cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu,
int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
void *opaque);

/**
* CPUDumpFlags:
* @CPU_DUMP_CODE:
* @CPU_DUMP_FPU: dump FPU register state, not just integer
* @CPU_DUMP_CCOP: dump info about TCG QEMU's condition code optimization state
*/
enum CPUDumpFlags {
CPU_DUMP_CODE = 0x00010000,
CPU_DUMP_FPU = 0x00020000,
CPU_DUMP_CCOP = 0x00040000,
};

/**
* cpu_dump_state:
* @cpu: The CPU whose state is to be dumped.
* @f: File to dump to.
* @cpu_fprintf: Function to dump with.
* @flags: Flags what to dump.
*
* Dumps CPU state.
*/
void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags);

/**
* cpu_dump_statistics:
* @cpu: The CPU whose state is to be dumped.
* @f: File to dump to.
* @cpu_fprintf: Function to dump with.
* @flags: Flags what to dump.
*
* Dumps CPU statistics.
*/
void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
int flags);

/**
* cpu_reset:
* @cpu: The CPU whose state is to be reset.
Expand Down
4 changes: 2 additions & 2 deletions kvm-all.c
Original file line number Diff line number Diff line change
Expand Up @@ -1544,7 +1544,7 @@ static int kvm_handle_internal_error(CPUArchState *env, struct kvm_run *run)
if (run->internal.suberror == KVM_INTERNAL_ERROR_EMULATION) {
fprintf(stderr, "emulation failure\n");
if (!kvm_arch_stop_on_emulation_error(cpu)) {
cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE);
return EXCP_INTERRUPT;
}
}
Expand Down Expand Up @@ -1700,7 +1700,7 @@ int kvm_cpu_exec(CPUArchState *env)
} while (ret == 0);

if (ret < 0) {
cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE);
vm_stop(RUN_STATE_INTERNAL_ERROR);
}

Expand Down
38 changes: 23 additions & 15 deletions linux-user/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ void cpu_loop(CPUARMState *env)
error:
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
abort();
}
process_pending_signals(env);
Expand Down Expand Up @@ -985,7 +985,7 @@ void cpu_loop(CPUUniCore32State *env)

error:
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
abort();
}
#endif
Expand Down Expand Up @@ -1115,6 +1115,7 @@ static void flush_windows(CPUSPARCState *env)

void cpu_loop (CPUSPARCState *env)
{
CPUState *cs = CPU(sparc_env_get_cpu(env));
int trapnr;
abi_long ret;
target_siginfo_t info;
Expand Down Expand Up @@ -1246,7 +1247,7 @@ void cpu_loop (CPUSPARCState *env)
break;
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
exit (1);
}
process_pending_signals (env);
Expand Down Expand Up @@ -1304,7 +1305,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val)
#define EXCP_DUMP(env, fmt, ...) \
do { \
fprintf(stderr, fmt , ## __VA_ARGS__); \
cpu_dump_state(env, stderr, fprintf, 0); \
cpu_dump_state(ENV_GET_CPU(env), stderr, fprintf, 0); \
qemu_log(fmt, ## __VA_ARGS__); \
if (qemu_log_enabled()) { \
log_cpu_state(env, 0); \
Expand Down Expand Up @@ -2391,7 +2392,7 @@ void cpu_loop(CPUMIPSState *env)
error:
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
abort();
}
process_pending_signals(env);
Expand All @@ -2403,6 +2404,7 @@ void cpu_loop(CPUMIPSState *env)

void cpu_loop(CPUOpenRISCState *env)
{
CPUState *cs = CPU(openrisc_env_get_cpu(env));
int trapnr, gdbsig;

for (;;) {
Expand All @@ -2420,7 +2422,7 @@ void cpu_loop(CPUOpenRISCState *env)
break;
case EXCP_DPF:
case EXCP_IPF:
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
gdbsig = TARGET_SIGSEGV;
break;
case EXCP_TICK:
Expand Down Expand Up @@ -2469,7 +2471,7 @@ void cpu_loop(CPUOpenRISCState *env)
default:
qemu_log("\nqemu: unhandled CPU exception %#x - aborting\n",
trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
gdbsig = TARGET_SIGILL;
break;
}
Expand All @@ -2489,6 +2491,7 @@ void cpu_loop(CPUOpenRISCState *env)
#ifdef TARGET_SH4
void cpu_loop(CPUSH4State *env)
{
CPUState *cs = CPU(sh_env_get_cpu(env));
int trapnr, ret;
target_siginfo_t info;

Expand Down Expand Up @@ -2537,7 +2540,7 @@ void cpu_loop(CPUSH4State *env)

default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
exit (1);
}
process_pending_signals (env);
Expand All @@ -2548,6 +2551,7 @@ void cpu_loop(CPUSH4State *env)
#ifdef TARGET_CRIS
void cpu_loop(CPUCRISState *env)
{
CPUState *cs = CPU(cris_env_get_cpu(env));
int trapnr, ret;
target_siginfo_t info;

Expand Down Expand Up @@ -2595,7 +2599,7 @@ void cpu_loop(CPUCRISState *env)
break;
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
exit (1);
}
process_pending_signals (env);
Expand All @@ -2606,6 +2610,7 @@ void cpu_loop(CPUCRISState *env)
#ifdef TARGET_MICROBLAZE
void cpu_loop(CPUMBState *env)
{
CPUState *cs = CPU(mb_env_get_cpu(env));
int trapnr, ret;
target_siginfo_t info;

Expand Down Expand Up @@ -2673,7 +2678,7 @@ void cpu_loop(CPUMBState *env)
default:
printf ("Unhandled hw-exception: 0x%x\n",
env->sregs[SR_ESR] & ESR_EC_MASK);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
exit (1);
break;
}
Expand All @@ -2694,7 +2699,7 @@ void cpu_loop(CPUMBState *env)
break;
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
exit (1);
}
process_pending_signals (env);
Expand All @@ -2706,6 +2711,7 @@ void cpu_loop(CPUMBState *env)

void cpu_loop(CPUM68KState *env)
{
CPUState *cs = CPU(m68k_env_get_cpu(env));
int trapnr;
unsigned int n;
target_siginfo_t info;
Expand Down Expand Up @@ -2787,7 +2793,7 @@ void cpu_loop(CPUM68KState *env)
default:
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
abort();
}
process_pending_signals(env);
Expand Down Expand Up @@ -2843,6 +2849,7 @@ static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)

void cpu_loop(CPUAlphaState *env)
{
CPUState *cs = CPU(alpha_env_get_cpu(env));
int trapnr;
target_siginfo_t info;
abi_long sysret;
Expand Down Expand Up @@ -3017,7 +3024,7 @@ void cpu_loop(CPUAlphaState *env)
break;
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
exit (1);
}
process_pending_signals (env);
Expand All @@ -3028,6 +3035,7 @@ void cpu_loop(CPUAlphaState *env)
#ifdef TARGET_S390X
void cpu_loop(CPUS390XState *env)
{
CPUState *cs = CPU(s390_env_get_cpu(env));
int trapnr, n, sig;
target_siginfo_t info;
target_ulong addr;
Expand Down Expand Up @@ -3118,7 +3126,7 @@ void cpu_loop(CPUS390XState *env)

default:
fprintf(stderr, "Unhandled program exception: %#x\n", n);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
exit(1);
}
break;
Expand All @@ -3135,7 +3143,7 @@ void cpu_loop(CPUS390XState *env)

default:
fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
cpu_dump_state(cs, stderr, fprintf, 0);
exit(1);
}
process_pending_signals (env);
Expand Down
13 changes: 6 additions & 7 deletions monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -921,9 +921,11 @@ int monitor_get_cpu_index(void)

static void do_info_registers(Monitor *mon, const QDict *qdict)
{
CPUState *cpu;
CPUArchState *env;
env = mon_get_cpu();
cpu_dump_state(env, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
cpu = ENV_GET_CPU(env);
cpu_dump_state(cpu, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
}

static void do_info_jit(Monitor *mon, const QDict *qdict)
Expand All @@ -948,16 +950,15 @@ static void do_info_history(Monitor *mon, const QDict *qdict)
}
}

#if defined(TARGET_PPC)
/* XXX: not implemented in other targets */
static void do_info_cpu_stats(Monitor *mon, const QDict *qdict)
{
CPUState *cpu;
CPUArchState *env;

env = mon_get_cpu();
cpu_dump_statistics(env, (FILE *)mon, &monitor_fprintf, 0);
cpu = ENV_GET_CPU(env);
cpu_dump_statistics(cpu, (FILE *)mon, &monitor_fprintf, 0);
}
#endif

static void do_trace_print_events(Monitor *mon, const QDict *qdict)
{
Expand Down Expand Up @@ -2678,15 +2679,13 @@ static mon_cmd_t info_cmds[] = {
.help = "show the current VM UUID",
.mhandler.cmd = hmp_info_uuid,
},
#if defined(TARGET_PPC)
{
.name = "cpustats",
.args_type = "",
.params = "",
.help = "show CPU statistics",
.mhandler.cmd = do_info_cpu_stats,
},
#endif
#if defined(CONFIG_SLIRP)
{
.name = "usernet",
Expand Down
Loading

0 comments on commit 878096e

Please sign in to comment.