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 <[email protected]> --- 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 = 0x00010000, CPU_DUMP_FPU = 0x00020000, CPU_DUMP_CCOP = 0x00040000, + CPU_DUMP_APIC = 0x00080000, }; /** 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=%08x SVR=%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
