[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 16/35] kvm: Improve reporting of fatal errors
From: |
Marcelo Tosatti |
Subject: |
[Qemu-devel] [PATCH 16/35] kvm: Improve reporting of fatal errors |
Date: |
Thu, 6 Jan 2011 15:56:22 -0200 |
From: Jan Kiszka <address@hidden>
Report KVM_EXIT_UNKNOWN, KVM_EXIT_FAIL_ENTRY, and KVM_EXIT_EXCEPTION
with more details to stderr. The latter two are so far x86-only, so move
them into the arch-specific handler. Integrate the Intel real mode
warning on KVM_EXIT_FAIL_ENTRY that qemu-kvm carries, but actually
restrict it to Intel CPUs. Moreover, always dump the CPU state in case
we fail.
Signed-off-by: Jan Kiszka <address@hidden>
Signed-off-by: Marcelo Tosatti <address@hidden>
---
kvm-all.c | 22 ++++++++--------------
target-i386/cpu.h | 2 ++
target-i386/cpuid.c | 5 ++---
target-i386/kvm.c | 33 +++++++++++++++++++++++++++++++++
4 files changed, 45 insertions(+), 17 deletions(-)
diff --git a/kvm-all.c b/kvm-all.c
index a46a3b6..ad1d0a8 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -776,22 +776,22 @@ static int kvm_handle_io(uint16_t port, void *data, int
direction, int size,
#ifdef KVM_CAP_INTERNAL_ERROR_DATA
static int kvm_handle_internal_error(CPUState *env, struct kvm_run *run)
{
-
+ fprintf(stderr, "KVM internal error.");
if (kvm_check_extension(kvm_state, KVM_CAP_INTERNAL_ERROR_DATA)) {
int i;
- fprintf(stderr, "KVM internal error. Suberror: %d\n",
- run->internal.suberror);
-
+ fprintf(stderr, " Suberror: %d\n", run->internal.suberror);
for (i = 0; i < run->internal.ndata; ++i) {
fprintf(stderr, "extra data[%d]: %"PRIx64"\n",
i, (uint64_t)run->internal.data[i]);
}
+ } else {
+ fprintf(stderr, "\n");
}
- cpu_dump_state(env, stderr, fprintf, 0);
if (run->internal.suberror == KVM_INTERNAL_ERROR_EMULATION) {
fprintf(stderr, "emulation failure\n");
if (!kvm_arch_stop_on_emulation_error(env)) {
+ cpu_dump_state(env, stderr, fprintf, 0);
return 0;
}
}
@@ -925,15 +925,8 @@ void kvm_cpu_exec(CPUState *env)
ret = 1;
break;
case KVM_EXIT_UNKNOWN:
- DPRINTF("kvm_exit_unknown\n");
- ret = -1;
- break;
- case KVM_EXIT_FAIL_ENTRY:
- DPRINTF("kvm_exit_fail_entry\n");
- ret = -1;
- break;
- case KVM_EXIT_EXCEPTION:
- DPRINTF("kvm_exit_exception\n");
+ fprintf(stderr, "KVM: unknown exit, hardware reason %" PRIx64 "\n",
+ (uint64_t)run->hw.hardware_exit_reason);
ret = -1;
break;
#ifdef KVM_CAP_INTERNAL_ERROR_DATA
@@ -960,6 +953,7 @@ void kvm_cpu_exec(CPUState *env)
} while (ret > 0);
if (ret < 0) {
+ cpu_dump_state(env, stderr, fprintf, 0);
vm_stop(0);
env->exit_request = 1;
}
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index dddcd74..a457423 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -874,6 +874,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
uint32_t count,
uint32_t *ecx, uint32_t *edx);
int cpu_x86_register (CPUX86State *env, const char *cpu_model);
void cpu_clear_apic_feature(CPUX86State *env);
+void host_cpuid(uint32_t function, uint32_t count,
+ uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
/* helper.c */
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 165045e..5382a28 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -103,9 +103,8 @@ typedef struct model_features_t {
int check_cpuid = 0;
int enforce_cpuid = 0;
-static void host_cpuid(uint32_t function, uint32_t count,
- uint32_t *eax, uint32_t *ebx,
- uint32_t *ecx, uint32_t *edx)
+void host_cpuid(uint32_t function, uint32_t count,
+ uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
{
#if defined(CONFIG_KVM)
uint32_t vec[4];
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 2431a1f..d4f253e 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1525,8 +1525,19 @@ static int kvm_handle_halt(CPUState *env)
return 1;
}
+static bool host_supports_vmx(void)
+{
+ uint32_t ecx, unused;
+
+ host_cpuid(1, 0, &unused, &unused, &ecx, &unused);
+ return ecx & CPUID_EXT_VMX;
+}
+
+#define VMX_INVALID_GUEST_STATE 0x80000021
+
int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
{
+ uint64_t code;
int ret = 0;
switch (run->exit_reason) {
@@ -1534,6 +1545,28 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run
*run)
DPRINTF("handle_hlt\n");
ret = kvm_handle_halt(env);
break;
+ case KVM_EXIT_FAIL_ENTRY:
+ code = run->fail_entry.hardware_entry_failure_reason;
+ fprintf(stderr, "KVM: entry failed, hardware error 0x%" PRIx64 "\n",
+ code);
+ if (host_supports_vmx() && code == VMX_INVALID_GUEST_STATE) {
+ fprintf(stderr,
+ "\nIf you're runnning a guest on an Intel machine without "
+ "unrestricted mode\n"
+ "support, the failure can be most likely due to the guest "
+ "entering an invalid\n"
+ "state for Intel VT. For example, the guest maybe running "
+ "in big real mode\n"
+ "which is not supported on less recent Intel processors."
+ "\n\n");
+ }
+ ret = -1;
+ break;
+ case KVM_EXIT_EXCEPTION:
+ fprintf(stderr, "KVM: exception %d exit (error code 0x%x)\n",
+ run->ex.exception, run->ex.error_code);
+ ret = -1;
+ break;
default:
fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
ret = -1;
--
1.7.2.3
- [Qemu-devel] [PATCH 13/35] kvm: Fix coding style violations, (continued)
- [Qemu-devel] [PATCH 13/35] kvm: Fix coding style violations, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 35/35] kvm: x86: Only read/write MSR_KVM_ASYNC_PF_EN if supported, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 24/35] Synchronize VCPU states before reset, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 10/35] kvm: x86: Remove obsolete SS.RPL/DPL aligment, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 14/35] kvm: Drop return value of kvm_cpu_exec, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 03/35] Clean up cpu_inject_x86_mce(), Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 17/35] x86: Optionally dump code bytes on cpu_dump_state, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 33/35] kvm: Do not use qemu_fair_mutex, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 15/35] kvm: Stop on all fatal exit reasons, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 16/35] kvm: Improve reporting of fatal errors,
Marcelo Tosatti <=
- [Qemu-devel] [PATCH 05/35] Add function for checking mca broadcast of CPU, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 07/35] kvm: kvm_mce_inj_* subroutines for templated error injections, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 04/35] Add "broadcast" option for mce command, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 18/35] kvm: x86: Align kvm_arch_put_registers code with comment, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 06/35] kvm: introduce kvm_mce_in_progress, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 21/35] kvm: x86: Fix xcr0 reset mismerge, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 31/35] kvm: x86: Rework identity map and TSS setup for larger BIOS sizes, Marcelo Tosatti, 2011/01/06
- [Qemu-devel] [PATCH 28/35] kvm: x86: Introduce kvmclock device to save/restore its state, Marcelo Tosatti, 2011/01/06