When KVM exit reason is KVM_EXIT_SHUTDOWN, there will cause
guest to reset, but we can't get any information to fix.
we knew KVM handle triple fault will set exit_reason to
KVM_EXIT_SHUTDOWN, so we also should dump the APIC information
to help to fix.
Signed-off-by: Chen Fan chen.fan.f...@cn.fujitsu.com
---
include/qom/cpu.h| 2 ++
kvm-all.c| 1 +
target-i386/helper.c | 53
3 files changed, 56 insertions(+)
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 1aafbf5..2d4d9d9 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -362,11 +362,13 @@ int cpu_write_elf32_qemunote(WriteCoreDumpFunction f,
CPUState *cpu,
* @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
+ * @CPU_DUMP_APIC: dump APIC info about interrupt executed state
*/
enum CPUDumpFlags {
CPU_DUMP_CODE = 0x0001,
CPU_DUMP_FPU = 0x0002,
CPU_DUMP_CCOP = 0x0004,
+CPU_DUMP_APIC = 0x0008,
};
/**
diff --git a/kvm-all.c b/kvm-all.c
index 3ae30ee..74f27e6 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1753,6 +1753,7 @@ int kvm_cpu_exec(CPUState *cpu)
case KVM_EXIT_SHUTDOWN:
DPRINTF(shutdown\n);
qemu_system_reset_request();
+cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE|CPU_DUMP_APIC);
ret = EXCP_INTERRUPT;
break;
case KVM_EXIT_UNKNOWN:
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 11ca864..1a2d26e 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -25,6 +25,8 @@
#include monitor/monitor.h
#endif
+#include hw/i386/apic_internal.h
+
//#define DEBUG_MMU
static void cpu_x86_version(CPUX86State *env, int *family, int *model)
@@ -186,6 +188,7 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f,
fprintf_function cpu_fprintf,
int flags)
{
X86CPU *cpu = X86_CPU(cs);
+APICCommonState *apic = APIC_COMMON(cpu-apic_state);
CPUX86State *env = cpu-env;
int eflags, i, nb;
char cc_op_name[32];
@@ -356,6 +359,56 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f,
fprintf_function cpu_fprintf,
cpu_fprintf(f, );
}
}
+if (flags CPU_DUMP_APIC apic) {
+cpu_fprintf(f, APICBASE=%08x APICID=%08x VERSION=%08x APR=%08x\n
+TPR=%08xSVR=%08x LDR=%08x DFR=%08x\n,
+apic-apicbase,
+apic-id,
+apic-version,
+apic-arb_id,
+apic-tpr,
+apic-spurious_vec,
+apic-log_dest,
+apic-dest_mode);
+ for (i = 0; i 8; i++) {
+ cpu_fprintf(f, ISR[%3d:%3d]=%08x,
+ (32 * i), (32 * i + 31), apic-isr[i]);
+ if (i == 3 || i == 7) {
+ cpu_fprintf(f, \n);
+ } else {
+ cpu_fprintf(f, );
+ }
+ }
+ for (i = 0; i 8; i++) {
+ cpu_fprintf(f, TMR[%3d:%3d]=%08x,
+ (32 * i), (32 * i + 31), apic-tmr[i]);
+ if (i == 3 || i == 7) {
+ cpu_fprintf(f, \n);
+ } else {
+ cpu_fprintf(f, );
+ }
+ }
+ for (i = 0; i 8; i++) {
+ cpu_fprintf(f, IRR[%3d:%3d]=%08x,
+ (32 * i), (32 * i + 31), apic-irr[i]);
+ if (i == 3 || i == 7) {
+ cpu_fprintf(f, \n);
+ } else {
+ cpu_fprintf(f, );
+ }
+ }
+ for (i = 0; i APIC_LVT_NB; i++) {
+ cpu_fprintf(f, LVT[%d]=%08x, i, apic-lvt[i]);
+ if (i == (APIC_LVT_NB - 1) / 2 || i == (APIC_LVT_NB -1)) {
+ cpu_fprintf(f, \n);
+ } else {
+ cpu_fprintf(f, );
+ }
+ }
+ cpu_fprintf(f, ESR=%08x , apic-esr);
+ cpu_fprintf(f, ICR[31:0]=%08x ICR[63:32]=%08x\n, apic-icr[0],
apic-icr[1]);
+}
+
if (flags CPU_DUMP_CODE) {
target_ulong base = env-segs[R_CS].base + env-eip;
target_ulong offs = MIN(env-eip, DUMP_CODE_BYTES_BACKWARD);
--
1.9.3