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
---
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