From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: "Hesse, Christian" <mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Subject: Re: [PATCH] KVM: fix calculation of initial value of rdx register
Date: Tue, 07 Nov 2006 16:11:42 +0200 [thread overview]
Message-ID: <4550941E.4070409@qumranet.com> (raw)
In-Reply-To: <200611071446.17870.mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1090 bytes --]
Hesse, Christian wrote:
> On Tuesday 07 November 2006 14:25, Avi Kivity wrote:
>
>> Hesse, Christian wrote:
>>
>>> On Tuesday 07 November 2006 13:31, Avi Kivity wrote:
>>>
>>>> Hesse, Christian wrote:
>>>>
>>>>>> Then, please apply the attached patch. You will need serial console
>>>>>> or netconsole, and to
>>>>>>
>>>>>> echo 9 > /proc/sysrq-trigger
>>>>>>
>>>>>> before launching the VM.
>>>>>>
>>>>> There is no patch attached to this mail...
>>>>>
>>>> Sorry, attaching now.
>>>>
>>> There are some undefined values in your code:
>>>
>>> /usr/src/kvm-module/debug.c: In function 'vmcs_dump':
>>> /usr/src/kvm-module/debug.c:924: error: 'HOST_TR_LIMIT' undeclared (first
>>> use in this function)
>>>
>> Sorry, refreshed patch attached.
>>
>
> Looks better, but you did not catch them all.
>
>
Forgot you're using 32-bit. #ifdef'ed out.
Is this machine a laptop? If so, we may be seeing interaction between
system management mode and VT.
--
error compiling committee.c: too many arguments to function
[-- Attachment #2: kvm-debug.patch --]
[-- Type: text/x-patch, Size: 31520 bytes --]
Index: linux-2.6/drivers/kvm/debug.c
===================================================================
--- /dev/null
+++ linux-2.6/drivers/kvm/debug.c
@@ -0,0 +1,1051 @@
+/*
+ * Kernel-based Virtual Machine driver for Linux
+ *
+ * This module enables machines with Intel VT-x extensions to run virtual
+ * machines without emulation or binary translation.
+ *
+ * Debug support
+ *
+ * Copyright (C) 2006 Qumranet, Inc.
+ *
+ * Authors:
+ * Yaniv Kamay <yaniv-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
+ * Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
+ *
+ */
+
+#include <linux/highmem.h>
+
+#include <linux/kvm.h>
+#include "kvm.h"
+#include "debug.h"
+
+#ifdef KVM_DEBUG
+
+static const char *vmx_msr_name[] = {
+ "MSR_EFER", "MSR_STAR", "MSR_CSTAR",
+ "MSR_KERNEL_GS_BASE", "MSR_SYSCALL_MASK", "MSR_LSTAR"
+};
+
+#define NR_VMX_MSR (sizeof(vmx_msr_name) / sizeof(char*))
+
+void show_msrs(struct kvm_vcpu *vcpu)
+{
+ int i;
+
+ for (i = 0; i < NR_VMX_MSR; ++i) {
+ vcpu_printf(vcpu, "%s: %s=0x%llx\n",
+ __FUNCTION__,
+ vmx_msr_name[i],
+ vcpu->guest_msrs[i].data);
+ }
+}
+
+void show_code(struct kvm_vcpu *vcpu)
+{
+ gva_t rip = vmcs_readl(GUEST_RIP);
+ u8 code[50];
+ char buf[30 + 3 * sizeof code];
+ int i;
+
+ if (!is_long_mode())
+ rip += vmcs_readl(GUEST_CS_BASE);
+
+ kvm_read_guest(vcpu, rip, sizeof code, code);
+ for (i = 0; i < sizeof code; ++i)
+ sprintf(buf + i * 3, " %02x", code[i]);
+ vcpu_printf(vcpu, "code: %lx%s\n", rip, buf);
+}
+
+struct gate_struct {
+ u16 offset_low;
+ u16 segment;
+ unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
+ u16 offset_middle;
+ u32 offset_high;
+ u32 zero1;
+} __attribute__((packed));
+
+void show_irq(struct kvm_vcpu *vcpu, int irq)
+{
+ unsigned long idt_base = vmcs_readl(GUEST_IDTR_BASE);
+ unsigned long idt_limit = vmcs_readl(GUEST_IDTR_LIMIT);
+ struct gate_struct gate;
+
+ if (!is_long_mode())
+ vcpu_printf(vcpu, "%s: not in long mode\n", __FUNCTION__);
+
+ if (!is_long_mode() || idt_limit < irq * sizeof(gate)) {
+ vcpu_printf(vcpu, "%s: 0x%x read_guest err\n",
+ __FUNCTION__,
+ irq);
+ return;
+ }
+
+ if (kvm_read_guest(vcpu, idt_base + irq * sizeof(gate), sizeof(gate), &gate) != sizeof(gate)) {
+ vcpu_printf(vcpu, "%s: 0x%x read_guest err\n",
+ __FUNCTION__,
+ irq);
+ return;
+ }
+ vcpu_printf(vcpu, "%s: 0x%x handler 0x%llx\n",
+ __FUNCTION__,
+ irq,
+ ((u64)gate.offset_high << 32) |
+ ((u64)gate.offset_middle << 16) |
+ gate.offset_low);
+}
+
+void show_page(struct kvm_vcpu *vcpu,
+ gva_t addr)
+{
+ u64 *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+
+ if (!buf)
+ return;
+
+ addr &= PAGE_MASK;
+ if (kvm_read_guest(vcpu, addr, PAGE_SIZE, buf)) {
+ int i;
+ for (i = 0; i < PAGE_SIZE / sizeof(u64) ; i++) {
+ u8 *ptr = (u8*)&buf[i];
+ int j;
+ vcpu_printf(vcpu, " 0x%16.16lx:",
+ addr + i * sizeof(u64));
+ for (j = 0; j < sizeof(u64) ; j++)
+ vcpu_printf(vcpu, " 0x%2.2x", ptr[j]);
+ vcpu_printf(vcpu, "\n");
+ }
+ }
+ kfree(buf);
+}
+
+void show_u64(struct kvm_vcpu *vcpu, gva_t addr)
+{
+ u64 buf;
+
+ if (kvm_read_guest(vcpu, addr, sizeof(u64), &buf) == sizeof(u64)) {
+ u8 *ptr = (u8*)&buf;
+ int j;
+ vcpu_printf(vcpu, " 0x%16.16lx:", addr);
+ for (j = 0; j < sizeof(u64) ; j++)
+ vcpu_printf(vcpu, " 0x%2.2x", ptr[j]);
+ vcpu_printf(vcpu, "\n");
+ }
+}
+
+#define IA32_DEBUGCTL_RESERVED_BITS 0xfffffffffffffe3cULL
+
+static int is_canonical(unsigned long addr)
+{
+ return addr == ((long)addr << 16) >> 16;
+}
+
+int vm_entry_test_guest(struct kvm_vcpu *vcpu)
+{
+ unsigned long cr0;
+ unsigned long cr4;
+ unsigned long cr3;
+ unsigned long dr7;
+ u64 ia32_debugctl;
+ unsigned long sysenter_esp;
+ unsigned long sysenter_eip;
+ unsigned long rflags;
+
+ int long_mode;
+ int virtual8086;
+
+ #define RFLAGS_VM (1 << 17)
+ #define RFLAGS_RF (1 << 9)
+
+
+ #define VIR8086_SEG_BASE_TEST(seg)\
+ if (vmcs_readl(GUEST_##seg##_BASE) != \
+ (unsigned long)vmcs_read16(GUEST_##seg##_SELECTOR) << 4) {\
+ vcpu_printf(vcpu, "%s: "#seg" base 0x%lx in "\
+ "virtual8086 is not "#seg" selector 0x%x"\
+ " shifted right 4 bits\n",\
+ __FUNCTION__,\
+ vmcs_readl(GUEST_##seg##_BASE),\
+ vmcs_read16(GUEST_##seg##_SELECTOR));\
+ return 0;\
+ }
+
+ #define VIR8086_SEG_LIMIT_TEST(seg)\
+ if (vmcs_readl(GUEST_##seg##_LIMIT) != 0x0ffff) { \
+ vcpu_printf(vcpu, "%s: "#seg" limit 0x%lx in "\
+ "virtual8086 is not 0xffff\n",\
+ __FUNCTION__,\
+ vmcs_readl(GUEST_##seg##_LIMIT));\
+ return 0;\
+ }
+
+ #define VIR8086_SEG_AR_TEST(seg)\
+ if (vmcs_read32(GUEST_##seg##_AR_BYTES) != 0x0f3) { \
+ vcpu_printf(vcpu, "%s: "#seg" AR 0x%x in "\
+ "virtual8086 is not 0xf3\n",\
+ __FUNCTION__,\
+ vmcs_read32(GUEST_##seg##_AR_BYTES));\
+ return 0;\
+ }
+
+
+ cr0 = vmcs_readl(GUEST_CR0);
+
+ if (!(cr0 & CR0_PG_MASK)) {
+ vcpu_printf(vcpu, "%s: cr0 0x%lx, PG is not set\n",
+ __FUNCTION__, cr0);
+ return 0;
+ }
+
+ if (!(cr0 & CR0_PE_MASK)) {
+ vcpu_printf(vcpu, "%s: cr0 0x%lx, PE is not set\n",
+ __FUNCTION__, cr0);
+ return 0;
+ }
+
+ if (!(cr0 & CR0_NE_MASK)) {
+ vcpu_printf(vcpu, "%s: cr0 0x%lx, NE is not set\n",
+ __FUNCTION__, cr0);
+ return 0;
+ }
+
+ if (!(cr0 & CR0_WP_MASK)) {
+ vcpu_printf(vcpu, "%s: cr0 0x%lx, WP is not set\n",
+ __FUNCTION__, cr0);
+ }
+
+ cr4 = vmcs_readl(GUEST_CR4);
+
+ if (!(cr4 & CR4_VMXE_MASK)) {
+ vcpu_printf(vcpu, "%s: cr4 0x%lx, VMXE is not set\n",
+ __FUNCTION__, cr4);
+ return 0;
+ }
+
+ if (!(cr4 & CR4_PAE_MASK)) {
+ vcpu_printf(vcpu, "%s: cr4 0x%lx, PAE is not set\n",
+ __FUNCTION__, cr4);
+ }
+
+ ia32_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL);
+
+ if (ia32_debugctl & IA32_DEBUGCTL_RESERVED_BITS ) {
+ vcpu_printf(vcpu, "%s: ia32_debugctl 0x%llx, reserve bits\n",
+ __FUNCTION__, ia32_debugctl);
+ return 0;
+ }
+
+ long_mode = is_long_mode();
+
+ if (long_mode) {
+ }
+
+ if ( long_mode && !(cr4 & CR4_PAE_MASK)) {
+ vcpu_printf(vcpu, "%s: long mode and not PAE\n",
+ __FUNCTION__);
+ return 0;
+ }
+
+ cr3 = vmcs_readl(GUEST_CR3);
+
+ if (cr3 & CR3_L_MODE_RESEVED_BITS) {
+ vcpu_printf(vcpu, "%s: cr3 0x%lx, reserved bits\n",
+ __FUNCTION__, cr3);
+ return 0;
+ }
+
+ if ( !long_mode && (cr4 & CR4_PAE_MASK)) {
+ /* check the 4 PDPTEs for reserved bits */
+ unsigned long pdpt_pfn = cr3 >> PAGE_SHIFT;
+ int i;
+ u64 pdpte;
+ unsigned offset = (cr3 & (PAGE_SIZE-1)) >> 5;
+ u64 *pdpt = kmap_atomic(pfn_to_page(pdpt_pfn), KM_USER0);
+
+ for (i = 0; i < 4; ++i) {
+ pdpte = pdpt[offset + i];
+ if ((pdpte & 1) && (pdpte & 0xfffffff0000001e6ull))
+ break;
+ }
+
+ kunmap_atomic(pdpt, KM_USER0);
+
+ if (i != 4) {
+ vcpu_printf(vcpu, "%s: pae cr3[%d] 0x%llx, reserved bits\n",
+ __FUNCTION__, i, pdpte);
+ return 0;
+ }
+ }
+
+ dr7 = vmcs_readl(GUEST_DR7);
+
+ if (dr7 & ~((1ULL << 32) - 1)) {
+ vcpu_printf(vcpu, "%s: dr7 0x%lx, reserved bits\n",
+ __FUNCTION__, dr7);
+ return 0;
+ }
+
+ sysenter_esp = vmcs_readl(GUEST_SYSENTER_ESP);
+
+ if (!is_canonical(sysenter_esp)) {
+ vcpu_printf(vcpu, "%s: sysenter_esp 0x%lx, not canonical\n",
+ __FUNCTION__, sysenter_esp);
+ return 0;
+ }
+
+ sysenter_eip = vmcs_readl(GUEST_SYSENTER_EIP);
+
+ if (!is_canonical(sysenter_eip)) {
+ vcpu_printf(vcpu, "%s: sysenter_eip 0x%lx, not canonical\n",
+ __FUNCTION__, sysenter_eip);
+ return 0;
+ }
+
+ rflags = vmcs_readl(GUEST_RFLAGS);
+ virtual8086 = rflags & RFLAGS_VM;
+
+
+ if (vmcs_read16(GUEST_TR_SELECTOR) & SELECTOR_TI_MASK) {
+ vcpu_printf(vcpu, "%s: tr selctor 0x%x, TI is set\n",
+ __FUNCTION__, vmcs_read16(GUEST_TR_SELECTOR));
+ return 0;
+ }
+
+ if (!(vmcs_read32(GUEST_LDTR_AR_BYTES) & AR_UNUSABLE_MASK) &&
+ vmcs_read16(GUEST_LDTR_SELECTOR) & SELECTOR_TI_MASK) {
+ vcpu_printf(vcpu, "%s: ldtr selctor 0x%x,"
+ " is usable and TI is set\n",
+ __FUNCTION__, vmcs_read16(GUEST_LDTR_SELECTOR));
+ return 0;
+ }
+
+ if (!virtual8086 &&
+ (vmcs_read16(GUEST_SS_SELECTOR) & SELECTOR_RPL_MASK) !=
+ (vmcs_read16(GUEST_CS_SELECTOR) & SELECTOR_RPL_MASK)) {
+ vcpu_printf(vcpu, "%s: ss selctor 0x%x cs selctor 0x%x,"
+ " not same RPL\n",
+ __FUNCTION__,
+ vmcs_read16(GUEST_SS_SELECTOR),
+ vmcs_read16(GUEST_CS_SELECTOR));
+ return 0;
+ }
+
+ if (virtual8086) {
+ VIR8086_SEG_BASE_TEST(CS);
+ VIR8086_SEG_BASE_TEST(SS);
+ VIR8086_SEG_BASE_TEST(DS);
+ VIR8086_SEG_BASE_TEST(ES);
+ VIR8086_SEG_BASE_TEST(FS);
+ VIR8086_SEG_BASE_TEST(GS);
+ }
+
+ if (!is_canonical(vmcs_readl(GUEST_TR_BASE)) ||
+ !is_canonical(vmcs_readl(GUEST_FS_BASE)) ||
+ !is_canonical(vmcs_readl(GUEST_GS_BASE)) ) {
+ vcpu_printf(vcpu, "%s: TR 0x%lx FS 0x%lx or GS 0x%lx base"
+ " is not canonical\n",
+ __FUNCTION__,
+ vmcs_readl(GUEST_TR_BASE),
+ vmcs_readl(GUEST_FS_BASE),
+ vmcs_readl(GUEST_GS_BASE));
+ return 0;
+
+ }
+
+ if (!(vmcs_read32(GUEST_LDTR_AR_BYTES) & AR_UNUSABLE_MASK) &&
+ !is_canonical(vmcs_readl(GUEST_LDTR_BASE))) {
+ vcpu_printf(vcpu, "%s: LDTR base 0x%lx, usable and is not"
+ " canonical\n",
+ __FUNCTION__,
+ vmcs_readl(GUEST_LDTR_BASE));
+ return 0;
+ }
+
+ if ((vmcs_readl(GUEST_CS_BASE) & ~((1ULL << 32) - 1))) {
+ vcpu_printf(vcpu, "%s: CS base 0x%lx, not all bits 63-32"
+ " are zero\n",
+ __FUNCTION__,
+ vmcs_readl(GUEST_CS_BASE));
+ return 0;
+ }
+
+ #define SEG_BASE_TEST(seg)\
+ if ( !(vmcs_read32(GUEST_##seg##_AR_BYTES) & AR_UNUSABLE_MASK) &&\
+ (vmcs_readl(GUEST_##seg##_BASE) & ~((1ULL << 32) - 1))) {\
+ vcpu_printf(vcpu, "%s: "#seg" base 0x%lx, is usable and not"\
+ " all bits 63-32 are zero\n",\
+ __FUNCTION__,\
+ vmcs_readl(GUEST_##seg##_BASE));\
+ return 0;\
+ }
+ SEG_BASE_TEST(SS);
+ SEG_BASE_TEST(DS);
+ SEG_BASE_TEST(ES);
+
+ if (virtual8086) {
+ VIR8086_SEG_LIMIT_TEST(CS);
+ VIR8086_SEG_LIMIT_TEST(SS);
+ VIR8086_SEG_LIMIT_TEST(DS);
+ VIR8086_SEG_LIMIT_TEST(ES);
+ VIR8086_SEG_LIMIT_TEST(FS);
+ VIR8086_SEG_LIMIT_TEST(GS);
+ }
+
+ if (virtual8086) {
+ VIR8086_SEG_AR_TEST(CS);
+ VIR8086_SEG_AR_TEST(SS);
+ VIR8086_SEG_AR_TEST(DS);
+ VIR8086_SEG_AR_TEST(ES);
+ VIR8086_SEG_AR_TEST(FS);
+ VIR8086_SEG_AR_TEST(GS);
+ } else {
+
+ u32 cs_ar = vmcs_read32(GUEST_CS_AR_BYTES);
+ u32 ss_ar = vmcs_read32(GUEST_SS_AR_BYTES);
+ u32 tr_ar = vmcs_read32(GUEST_TR_AR_BYTES);
+ u32 ldtr_ar = vmcs_read32(GUEST_LDTR_AR_BYTES);
+
+ #define SEG_G_TEST(seg) { \
+ u32 lim = vmcs_read32(GUEST_##seg##_LIMIT); \
+ u32 ar = vmcs_read32(GUEST_##seg##_AR_BYTES); \
+ int err = 0; \
+ if (((lim & ~PAGE_MASK) != ~PAGE_MASK) && (ar & AR_G_MASK)) \
+ err = 1; \
+ if ((lim & ~((1u << 20) - 1)) && !(ar & AR_G_MASK)) \
+ err = 1; \
+ if (err) { \
+ vcpu_printf(vcpu, "%s: "#seg" AR 0x%x, G err. lim" \
+ " is 0x%x\n", \
+ __FUNCTION__, \
+ ar, lim); \
+ return 0; \
+ } \
+ }
+
+
+ if (!(cs_ar & AR_TYPE_ACCESSES_MASK)) {
+ vcpu_printf(vcpu, "%s: cs AR 0x%x, accesses is clear\n",
+ __FUNCTION__,
+ cs_ar);
+ return 0;
+ }
+
+ if (!(cs_ar & AR_TYPE_CODE_MASK)) {
+ vcpu_printf(vcpu, "%s: cs AR 0x%x, code is clear\n",
+ __FUNCTION__,
+ cs_ar);
+ return 0;
+ }
+
+ if (!(cs_ar & AR_S_MASK)) {
+ vcpu_printf(vcpu, "%s: cs AR 0x%x, type is sys\n",
+ __FUNCTION__,
+ cs_ar);
+ return 0;
+ }
+
+ if ((cs_ar & AR_TYPE_MASK) >= 8 && (cs_ar & AR_TYPE_MASK) < 12 &&
+ AR_DPL(cs_ar) !=
+ (vmcs_read16(GUEST_CS_SELECTOR) & SELECTOR_RPL_MASK) ) {
+ vcpu_printf(vcpu, "%s: cs AR 0x%x, "
+ "DPL not as RPL\n",
+ __FUNCTION__,
+ cs_ar);
+ return 0;
+ }
+
+ if ((cs_ar & AR_TYPE_MASK) >= 13 && (cs_ar & AR_TYPE_MASK) < 16 &&
+ AR_DPL(cs_ar) >
+ (vmcs_read16(GUEST_CS_SELECTOR) & SELECTOR_RPL_MASK) ) {
+ vcpu_printf(vcpu, "%s: cs AR 0x%x, "
+ "DPL greater than RPL\n",
+ __FUNCTION__,
+ cs_ar);
+ return 0;
+ }
+
+ if (!(cs_ar & AR_P_MASK)) {
+ vcpu_printf(vcpu, "%s: CS AR 0x%x, not "
+ "present\n",
+ __FUNCTION__,
+ cs_ar);
+ return 0;
+ }
+
+ if ((cs_ar & AR_RESERVD_MASK)) {
+ vcpu_printf(vcpu, "%s: CS AR 0x%x, reseved"
+ " bits are set\n",
+ __FUNCTION__,
+ cs_ar);
+ return 0;
+ }
+
+ if (long_mode & (cs_ar & AR_L_MASK) && (cs_ar & AR_DB_MASK)) {
+ vcpu_printf(vcpu, "%s: CS AR 0x%x, DB and L are set"
+ " in long mode\n",
+ __FUNCTION__,
+ cs_ar);
+ return 0;
+
+ }
+
+ SEG_G_TEST(CS);
+
+ if (!(ss_ar & AR_UNUSABLE_MASK)) {
+ if ((ss_ar & AR_TYPE_MASK) != 3 &&
+ (ss_ar & AR_TYPE_MASK) != 7 ) {
+ vcpu_printf(vcpu, "%s: ss AR 0x%x, usable and type"
+ " is not 3 or 7\n",
+ __FUNCTION__,
+ ss_ar);
+ return 0;
+ }
+
+ if (!(ss_ar & AR_S_MASK)) {
+ vcpu_printf(vcpu, "%s: ss AR 0x%x, usable and"
+ " is sys\n",
+ __FUNCTION__,
+ ss_ar);
+ return 0;
+ }
+ if (!(ss_ar & AR_P_MASK)) {
+ vcpu_printf(vcpu, "%s: SS AR 0x%x, usable"
+ " and not present\n",
+ __FUNCTION__,
+ ss_ar);
+ return 0;
+ }
+
+ if ((ss_ar & AR_RESERVD_MASK)) {
+ vcpu_printf(vcpu, "%s: SS AR 0x%x, reseved"
+ " bits are set\n",
+ __FUNCTION__,
+ ss_ar);
+ return 0;
+ }
+
+ SEG_G_TEST(SS);
+
+ }
+
+ if (AR_DPL(ss_ar) !=
+ (vmcs_read16(GUEST_SS_SELECTOR) & SELECTOR_RPL_MASK) ) {
+ vcpu_printf(vcpu, "%s: SS AR 0x%x, "
+ "DPL not as RPL\n",
+ __FUNCTION__,
+ ss_ar);
+ return 0;
+ }
+
+ #define SEG_AR_TEST(seg) {\
+ u32 ar = vmcs_read32(GUEST_##seg##_AR_BYTES);\
+ if (!(ar & AR_UNUSABLE_MASK)) {\
+ if (!(ar & AR_TYPE_ACCESSES_MASK)) {\
+ vcpu_printf(vcpu, "%s: "#seg" AR 0x%x, "\
+ "usable and not accesses\n",\
+ __FUNCTION__,\
+ ar);\
+ return 0;\
+ }\
+ if ((ar & AR_TYPE_CODE_MASK) &&\
+ !(ar & AR_TYPE_READABLE_MASK)) {\
+ vcpu_printf(vcpu, "%s: "#seg" AR 0x%x, "\
+ "code and not readable\n",\
+ __FUNCTION__,\
+ ar);\
+ return 0;\
+ }\
+ if (!(ar & AR_S_MASK)) {\
+ vcpu_printf(vcpu, "%s: "#seg" AR 0x%x, usable and"\
+ " is sys\n",\
+ __FUNCTION__,\
+ ar);\
+ return 0;\
+ }\
+ if ((ar & AR_TYPE_MASK) >= 0 && \
+ (ar & AR_TYPE_MASK) < 12 && \
+ AR_DPL(ar) < (vmcs_read16(GUEST_##seg##_SELECTOR) & \
+ SELECTOR_RPL_MASK) ) {\
+ vcpu_printf(vcpu, "%s: "#seg" AR 0x%x, "\
+ "DPL less than RPL\n",\
+ __FUNCTION__,\
+ ar);\
+ return 0;\
+ }\
+ if (!(ar & AR_P_MASK)) {\
+ vcpu_printf(vcpu, "%s: "#seg" AR 0x%x, usable and"\
+ " not present\n",\
+ __FUNCTION__,\
+ ar);\
+ return 0;\
+ }\
+ if ((ar & AR_RESERVD_MASK)) {\
+ vcpu_printf(vcpu, "%s: "#seg" AR"\
+ " 0x%x, reseved"\
+ " bits are set\n",\
+ __FUNCTION__,\
+ ar);\
+ return 0;\
+ }\
+ SEG_G_TEST(seg)\
+ }\
+ }
+
+#undef DS
+#undef ES
+#undef FS
+#undef GS
+
+ SEG_AR_TEST(DS);
+ SEG_AR_TEST(ES);
+ SEG_AR_TEST(FS);
+ SEG_AR_TEST(GS);
+
+ // TR test
+ if (long_mode) {
+ if ((tr_ar & AR_TYPE_MASK) != AR_TYPE_BUSY_64_TSS) {
+ vcpu_printf(vcpu, "%s: TR AR 0x%x, long"
+ " mode and not 64bit busy"
+ " tss\n",
+ __FUNCTION__,
+ tr_ar);
+ return 0;
+ }
+ } else {
+ if ((tr_ar & AR_TYPE_MASK) != AR_TYPE_BUSY_32_TSS &&
+ (tr_ar & AR_TYPE_MASK) != AR_TYPE_BUSY_16_TSS) {
+ vcpu_printf(vcpu, "%s: TR AR 0x%x, legacy"
+ " mode and not 16/32bit "
+ "busy tss\n",
+ __FUNCTION__,
+ tr_ar);
+ return 0;
+ }
+
+ }
+ if ((tr_ar & AR_S_MASK)) {
+ vcpu_printf(vcpu, "%s: TR AR 0x%x, S is set\n",
+ __FUNCTION__,
+ tr_ar);
+ return 0;
+ }
+ if (!(tr_ar & AR_P_MASK)) {
+ vcpu_printf(vcpu, "%s: TR AR 0x%x, P is not set\n",
+ __FUNCTION__,
+ tr_ar);
+ return 0;
+ }
+
+ if ((tr_ar & (AR_RESERVD_MASK| AR_UNUSABLE_MASK))) {
+ vcpu_printf(vcpu, "%s: TR AR 0x%x, reserved bit are"
+ " set\n",
+ __FUNCTION__,
+ tr_ar);
+ return 0;
+ }
+ SEG_G_TEST(TR);
+
+ // TR test
+ if (!(ldtr_ar & AR_UNUSABLE_MASK)) {
+
+ if ((ldtr_ar & AR_TYPE_MASK) != AR_TYPE_LDT) {
+ vcpu_printf(vcpu, "%s: LDTR AR 0x%x,"
+ " bad type\n",
+ __FUNCTION__,
+ ldtr_ar);
+ return 0;
+ }
+
+ if ((ldtr_ar & AR_S_MASK)) {
+ vcpu_printf(vcpu, "%s: LDTR AR 0x%x,"
+ " S is set\n",
+ __FUNCTION__,
+ ldtr_ar);
+ return 0;
+ }
+
+ if (!(ldtr_ar & AR_P_MASK)) {
+ vcpu_printf(vcpu, "%s: LDTR AR 0x%x,"
+ " P is not set\n",
+ __FUNCTION__,
+ ldtr_ar);
+ return 0;
+ }
+ if ((ldtr_ar & AR_RESERVD_MASK)) {
+ vcpu_printf(vcpu, "%s: LDTR AR 0x%x,"
+ " reserved bit are set\n",
+ __FUNCTION__,
+ ldtr_ar);
+ return 0;
+ }
+ SEG_G_TEST(LDTR);
+ }
+ }
+
+ // GDTR and IDTR
+
+
+ #define IDT_GDT_TEST(reg)\
+ if (!is_canonical(vmcs_readl(GUEST_##reg##_BASE))) {\
+ vcpu_printf(vcpu, "%s: "#reg" BASE 0x%lx, not canonical\n",\
+ __FUNCTION__,\
+ vmcs_readl(GUEST_##reg##_BASE));\
+ return 0;\
+ }\
+ if (vmcs_read32(GUEST_##reg##_LIMIT) >> 16) {\
+ vcpu_printf(vcpu, "%s: "#reg" LIMIT 0x%x, size err\n",\
+ __FUNCTION__,\
+ vmcs_read32(GUEST_##reg##_LIMIT));\
+ return 0;\
+ }\
+
+ IDT_GDT_TEST(GDTR);
+ IDT_GDT_TEST(IDTR);
+
+
+ // RIP
+
+ if ((!long_mode || !(vmcs_read32(GUEST_CS_AR_BYTES) & AR_L_MASK)) &&
+ vmcs_readl(GUEST_RIP) & ~((1ULL << 32) - 1) ){
+ vcpu_printf(vcpu, "%s: RIP 0x%lx, size err\n",
+ __FUNCTION__,
+ vmcs_readl(GUEST_RIP));
+ return 0;
+ }
+
+ if (!is_canonical(vmcs_readl(GUEST_RIP))) {
+ vcpu_printf(vcpu, "%s: RIP 0x%lx, not canonical\n",
+ __FUNCTION__,
+ vmcs_readl(GUEST_RIP));
+ return 0;
+ }
+
+ // RFLAGS
+ #define RFLAGS_RESEVED_CLEAR_BITS\
+ (~((1ULL << 22) - 1) | (1ULL << 15) | (1ULL << 5) | (1ULL << 3))
+ #define RFLAGS_RESEVED_SET_BITS (1 << 1)
+
+ if ((rflags & RFLAGS_RESEVED_CLEAR_BITS) ||
+ !(rflags & RFLAGS_RESEVED_SET_BITS)) {
+ vcpu_printf(vcpu, "%s: RFLAGS 0x%lx, reserved bits 0x%llx 0x%x\n",
+ __FUNCTION__,
+ rflags,
+ RFLAGS_RESEVED_CLEAR_BITS,
+ RFLAGS_RESEVED_SET_BITS);
+ return 0;
+ }
+
+ if (long_mode && virtual8086) {
+ vcpu_printf(vcpu, "%s: RFLAGS 0x%lx, vm and long mode\n",
+ __FUNCTION__,
+ rflags);
+ return 0;
+ }
+
+
+ if (!(rflags & RFLAGS_RF)) {
+ u32 vm_entry_info = vmcs_read32(VM_ENTRY_INTR_INFO_FIELD);
+ if ((vm_entry_info & INTR_INFO_VALID_MASK) &&
+ (vm_entry_info & INTR_INFO_INTR_TYPE_MASK) ==
+ INTR_TYPE_EXT_INTR) {
+ vcpu_printf(vcpu, "%s: RFLAGS 0x%lx, external"
+ " interrupt and RF is clear\n",
+ __FUNCTION__,
+ rflags);
+ return 0;
+ }
+
+ }
+
+ // to be continued from Checks on Guest Non-Register State (22.3.1.5)
+ return 1;
+}
+
+static int check_fixed_bits(struct kvm_vcpu *vcpu, const char *reg,
+ unsigned long cr,
+ u32 msr_fixed_0, u32 msr_fixed_1)
+{
+ u64 fixed_bits_0, fixed_bits_1;
+
+ rdmsrl(msr_fixed_0, fixed_bits_0);
+ rdmsrl(msr_fixed_1, fixed_bits_1);
+ if ((cr & fixed_bits_0) != fixed_bits_0) {
+ vcpu_printf(vcpu, "%s: %s (%lx) has one of %llx unset\n",
+ __FUNCTION__, reg, cr, fixed_bits_0);
+ return 0;
+ }
+ if ((~cr & ~fixed_bits_1) != ~fixed_bits_1) {
+ vcpu_printf(vcpu, "%s: %s (%lx) has one of %llx set\n",
+ __FUNCTION__, reg, cr, ~fixed_bits_1);
+ return 0;
+ }
+ return 1;
+}
+
+static int phys_addr_width(void)
+{
+ unsigned eax, ebx, ecx, edx;
+
+ cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
+ return eax & 0xff;
+}
+
+static int check_canonical(struct kvm_vcpu *vcpu, const char *name,
+ unsigned long reg)
+{
+#ifdef __x86_64__
+ unsigned long x;
+
+ if (sizeof(reg) == 4)
+ return 1;
+ x = (long)reg >> 48;
+ if (!(x == 0 || x == ~0UL)) {
+ vcpu_printf(vcpu, "%s: %s (%lx) not canonical\n",
+ __FUNCTION__, name, reg);
+ return 0;
+ }
+#endif
+ return 1;
+}
+
+static int check_selector(struct kvm_vcpu *vcpu, const char *name,
+ int rpl_ti, int null,
+ u16 sel)
+{
+ if (rpl_ti && (sel & 7)) {
+ vcpu_printf(vcpu, "%s: %s (%x) nonzero rpl or ti\n",
+ __FUNCTION__, name, sel);
+ return 0;
+ }
+ if (null && !sel) {
+ vcpu_printf(vcpu, "%s: %s (%x) zero\n",
+ __FUNCTION__, name, sel);
+ return 0;
+ }
+ return 1;
+}
+
+#define MSR_IA32_VMX_CR0_FIXED0 0x486
+#define MSR_IA32_VMX_CR0_FIXED1 0x487
+
+#define MSR_IA32_VMX_CR4_FIXED0 0x488
+#define MSR_IA32_VMX_CR4_FIXED1 0x489
+
+int vm_entry_test_host(struct kvm_vcpu *vcpu)
+{
+ int r = 0;
+ unsigned long cr0 = vmcs_readl(HOST_CR0);
+ unsigned long cr4 = vmcs_readl(HOST_CR4);
+ unsigned long cr3 = vmcs_readl(HOST_CR3);
+ int host_64;
+
+ host_64 = vmcs_read32(VM_EXIT_CONTROLS) & VM_EXIT_HOST_ADD_SPACE_SIZE;
+
+ /* 22.2.2 */
+ r &= check_fixed_bits(vcpu, "host cr0", cr0, MSR_IA32_VMX_CR0_FIXED0,
+ MSR_IA32_VMX_CR0_FIXED1);
+
+ r &= check_fixed_bits(vcpu, "host cr0", cr4, MSR_IA32_VMX_CR4_FIXED0,
+ MSR_IA32_VMX_CR4_FIXED1);
+ if ((u64)cr3 >> phys_addr_width()) {
+ vcpu_printf(vcpu, "%s: cr3 (%lx) vs phys addr width\n",
+ __FUNCTION__, cr3);
+ r = 0;
+ }
+
+ r &= check_canonical(vcpu, "host ia32_sysenter_eip",
+ vmcs_readl(HOST_IA32_SYSENTER_EIP));
+ r &= check_canonical(vcpu, "host ia32_sysenter_esp",
+ vmcs_readl(HOST_IA32_SYSENTER_ESP));
+
+ /* 22.2.3 */
+ r &= check_selector(vcpu, "host cs", 1, 1,
+ vmcs_read16(HOST_CS_SELECTOR));
+ r &= check_selector(vcpu, "host ss", 1, !host_64,
+ vmcs_read16(HOST_SS_SELECTOR));
+ r &= check_selector(vcpu, "host ds", 1, 0,
+ vmcs_read16(HOST_DS_SELECTOR));
+ r &= check_selector(vcpu, "host es", 1, 0,
+ vmcs_read16(HOST_ES_SELECTOR));
+ r &= check_selector(vcpu, "host fs", 1, 0,
+ vmcs_read16(HOST_FS_SELECTOR));
+ r &= check_selector(vcpu, "host gs", 1, 0,
+ vmcs_read16(HOST_GS_SELECTOR));
+ r &= check_selector(vcpu, "host tr", 1, 1,
+ vmcs_read16(HOST_TR_SELECTOR));
+
+#ifdef __x86_64__
+ r &= check_canonical(vcpu, "host fs base",
+ vmcs_readl(HOST_FS_BASE));
+ r &= check_canonical(vcpu, "host gs base",
+ vmcs_readl(HOST_GS_BASE));
+ r &= check_canonical(vcpu, "host gdtr base",
+ vmcs_readl(HOST_GDTR_BASE));
+ r &= check_canonical(vcpu, "host idtr base",
+ vmcs_readl(HOST_IDTR_BASE));
+#endif
+
+ /* 22.2.4 */
+#ifdef __x86_64__
+ if (!host_64) {
+ vcpu_printf(vcpu, "%s: vm exit controls: !64 bit host\n",
+ __FUNCTION__);
+ r = 0;
+ }
+ if (!(cr4 & CR4_PAE_MASK)) {
+ vcpu_printf(vcpu, "%s: cr4 (%lx): !pae\n",
+ __FUNCTION__, cr4);
+ r = 0;
+ }
+ r &= check_canonical(vcpu, "host rip", vmcs_readl(HOST_RIP));
+#endif
+
+ return r;
+}
+
+int vm_entry_test(struct kvm_vcpu *vcpu)
+{
+ int rg, rh;
+
+ rg = vm_entry_test_guest(vcpu);
+ rh = vm_entry_test_host(vcpu);
+ return rg && rh;
+}
+
+void vmcs_dump(struct kvm_vcpu *vcpu)
+{
+ vcpu_printf(vcpu, "************************ vmcs_dump ************************\n");
+ vcpu_printf(vcpu, "HOST_CR0 0x%lx\n", vmcs_readl(HOST_CR0));
+ vcpu_printf(vcpu, "HOST_CR3 0x%lx\n", vmcs_readl(HOST_CR3));
+ vcpu_printf(vcpu, "HOST_CR4 0x%lx\n", vmcs_readl(HOST_CR4));
+
+ vcpu_printf(vcpu, "HOST_TR_SELECTOR 0x%x\n", vmcs_read16(HOST_TR_SELECTOR));
+ vcpu_printf(vcpu, "HOST_TR_BASE 0x%lx\n", vmcs_readl(HOST_TR_BASE));
+
+ vcpu_printf(vcpu, "HOST_GDTR_BASE 0x%lx\n", vmcs_readl(HOST_GDTR_BASE));
+ vcpu_printf(vcpu, "HOST_LDTR_SELECTOR 0x%x\n", vmcs_read16(HOST_TR_SELECTOR));
+ vcpu_printf(vcpu, "HOST_IDTR_BASE 0x%lx\n", vmcs_readl(HOST_IDTR_BASE));
+
+ vcpu_printf(vcpu, "HOST_CS_SELECTOR 0x%x\n", vmcs_read16(HOST_CS_SELECTOR));
+ vcpu_printf(vcpu, "HOST_DS_SELECTOR 0x%x\n", vmcs_read16(HOST_DS_SELECTOR));
+ vcpu_printf(vcpu, "HOST_ES_SELECTOR 0x%x\n", vmcs_read16(HOST_ES_SELECTOR));
+ vcpu_printf(vcpu, "HOST_FS_SELECTOR 0x%x\n", vmcs_read16(HOST_FS_SELECTOR));
+ vcpu_printf(vcpu, "HOST_GS_SELECTOR 0x%x\n", vmcs_read16(HOST_GS_SELECTOR));
+ vcpu_printf(vcpu, "HOST_SS_SELECTOR 0x%x\n", vmcs_read16(HOST_SS_SELECTOR));
+
+
+ vcpu_printf(vcpu, "VM_ENTRY_CONTROLS 0x%x\n", vmcs_read32(VM_ENTRY_CONTROLS));
+
+ vcpu_printf(vcpu, "GUEST_CR0 0x%lx\n", vmcs_readl(GUEST_CR0));
+ vcpu_printf(vcpu, "GUEST_CR3 0x%lx\n", vmcs_readl(GUEST_CR3));
+ vcpu_printf(vcpu, "GUEST_CR4 0x%lx\n", vmcs_readl(GUEST_CR4));
+
+ vcpu_printf(vcpu, "GUEST_SYSENTER_ESP 0x%lx\n", vmcs_readl(GUEST_SYSENTER_ESP));
+ vcpu_printf(vcpu, "GUEST_SYSENTER_EIP 0x%lx\n", vmcs_readl(GUEST_SYSENTER_EIP));
+
+
+ vcpu_printf(vcpu, "GUEST_IA32_DEBUGCTL 0x%llx\n", vmcs_read64(GUEST_IA32_DEBUGCTL));
+ vcpu_printf(vcpu, "GUEST_DR7 0x%lx\n", vmcs_readl(GUEST_DR7));
+
+ vcpu_printf(vcpu, "GUEST_RFLAGS 0x%lx\n", vmcs_readl(GUEST_RFLAGS));
+ vcpu_printf(vcpu, "GUEST_RIP 0x%lx\n", vmcs_readl(GUEST_RIP));
+
+ vcpu_printf(vcpu, "GUEST_CS_SELECTOR 0x%x\n", vmcs_read16(GUEST_CS_SELECTOR));
+ vcpu_printf(vcpu, "GUEST_DS_SELECTOR 0x%x\n", vmcs_read16(GUEST_DS_SELECTOR));
+ vcpu_printf(vcpu, "GUEST_ES_SELECTOR 0x%x\n", vmcs_read16(GUEST_ES_SELECTOR));
+ vcpu_printf(vcpu, "GUEST_FS_SELECTOR 0x%x\n", vmcs_read16(GUEST_FS_SELECTOR));
+ vcpu_printf(vcpu, "GUEST_GS_SELECTOR 0x%x\n", vmcs_read16(GUEST_GS_SELECTOR));
+ vcpu_printf(vcpu, "GUEST_SS_SELECTOR 0x%x\n", vmcs_read16(GUEST_SS_SELECTOR));
+
+ vcpu_printf(vcpu, "GUEST_TR_SELECTOR 0x%x\n", vmcs_read16(GUEST_TR_SELECTOR));
+ vcpu_printf(vcpu, "GUEST_LDTR_SELECTOR 0x%x\n", vmcs_read16(GUEST_LDTR_SELECTOR));
+
+ vcpu_printf(vcpu, "GUEST_CS_AR_BYTES 0x%x\n", vmcs_read32(GUEST_CS_AR_BYTES));
+ vcpu_printf(vcpu, "GUEST_DS_AR_BYTES 0x%x\n", vmcs_read32(GUEST_DS_AR_BYTES));
+ vcpu_printf(vcpu, "GUEST_ES_AR_BYTES 0x%x\n", vmcs_read32(GUEST_ES_AR_BYTES));
+ vcpu_printf(vcpu, "GUEST_FS_AR_BYTES 0x%x\n", vmcs_read32(GUEST_FS_AR_BYTES));
+ vcpu_printf(vcpu, "GUEST_GS_AR_BYTES 0x%x\n", vmcs_read32(GUEST_GS_AR_BYTES));
+ vcpu_printf(vcpu, "GUEST_SS_AR_BYTES 0x%x\n", vmcs_read32(GUEST_SS_AR_BYTES));
+
+ vcpu_printf(vcpu, "GUEST_LDTR_AR_BYTES 0x%x\n", vmcs_read32(GUEST_LDTR_AR_BYTES));
+ vcpu_printf(vcpu, "GUEST_TR_AR_BYTES 0x%x\n", vmcs_read32(GUEST_TR_AR_BYTES));
+
+ vcpu_printf(vcpu, "GUEST_CS_BASE 0x%lx\n", vmcs_readl(GUEST_CS_BASE));
+ vcpu_printf(vcpu, "GUEST_DS_BASE 0x%lx\n", vmcs_readl(GUEST_DS_BASE));
+ vcpu_printf(vcpu, "GUEST_ES_BASE 0x%lx\n", vmcs_readl(GUEST_ES_BASE));
+ vcpu_printf(vcpu, "GUEST_FS_BASE 0x%lx\n", vmcs_readl(GUEST_FS_BASE));
+ vcpu_printf(vcpu, "GUEST_GS_BASE 0x%lx\n", vmcs_readl(GUEST_GS_BASE));
+ vcpu_printf(vcpu, "GUEST_SS_BASE 0x%lx\n", vmcs_readl(GUEST_SS_BASE));
+
+
+ vcpu_printf(vcpu, "GUEST_LDTR_BASE 0x%lx\n", vmcs_readl(GUEST_LDTR_BASE));
+ vcpu_printf(vcpu, "GUEST_TR_BASE 0x%lx\n", vmcs_readl(GUEST_TR_BASE));
+
+ vcpu_printf(vcpu, "GUEST_CS_LIMIT 0x%x\n", vmcs_read32(GUEST_CS_LIMIT));
+ vcpu_printf(vcpu, "GUEST_DS_LIMIT 0x%x\n", vmcs_read32(GUEST_DS_LIMIT));
+ vcpu_printf(vcpu, "GUEST_ES_LIMIT 0x%x\n", vmcs_read32(GUEST_ES_LIMIT));
+ vcpu_printf(vcpu, "GUEST_FS_LIMIT 0x%x\n", vmcs_read32(GUEST_FS_LIMIT));
+ vcpu_printf(vcpu, "GUEST_GS_LIMIT 0x%x\n", vmcs_read32(GUEST_GS_LIMIT));
+ vcpu_printf(vcpu, "GUEST_SS_LIMIT 0x%x\n", vmcs_read32(GUEST_SS_LIMIT));
+
+ vcpu_printf(vcpu, "GUEST_LDTR_LIMIT 0x%x\n", vmcs_read32(GUEST_LDTR_LIMIT));
+ vcpu_printf(vcpu, "GUEST_TR_LIMIT 0x%x\n", vmcs_read32(GUEST_TR_LIMIT));
+
+ vcpu_printf(vcpu, "GUEST_GDTR_BASE 0x%lx\n", vmcs_readl(GUEST_GDTR_BASE));
+ vcpu_printf(vcpu, "GUEST_IDTR_BASE 0x%lx\n", vmcs_readl(GUEST_IDTR_BASE));
+
+ vcpu_printf(vcpu, "GUEST_GDTR_LIMIT 0x%x\n", vmcs_read32(GUEST_GDTR_LIMIT));
+ vcpu_printf(vcpu, "GUEST_IDTR_LIMIT 0x%x\n", vmcs_read32(GUEST_IDTR_LIMIT));
+ vcpu_printf(vcpu, "***********************************************************\n");
+}
+
+void regs_dump(struct kvm_vcpu *vcpu)
+{
+ #define REG_DUMP(reg) \
+ vcpu_printf(vcpu, #reg" = 0x%lx\n", vcpu->regs[VCPU_REGS_##reg])
+ #define VMCS_REG_DUMP(reg) \
+ vcpu_printf(vcpu, #reg" = 0x%lx\n", vmcs_readl(GUEST_##reg))
+
+ vcpu_printf(vcpu, "************************ regs_dump ************************\n");
+ REG_DUMP(RAX);
+ REG_DUMP(RBX);
+ REG_DUMP(RCX);
+ REG_DUMP(RDX);
+ REG_DUMP(RSP);
+ REG_DUMP(RBP);
+ REG_DUMP(RSI);
+ REG_DUMP(RDI);
+#ifdef __x86_64__
+ REG_DUMP(R8);
+ REG_DUMP(R9);
+ REG_DUMP(R10);
+ REG_DUMP(R11);
+ REG_DUMP(R12);
+ REG_DUMP(R13);
+ REG_DUMP(R14);
+ REG_DUMP(R15);
+#endif
+
+ VMCS_REG_DUMP(RSP);
+ VMCS_REG_DUMP(RIP);
+ VMCS_REG_DUMP(RFLAGS);
+
+ vcpu_printf(vcpu, "***********************************************************\n");
+}
+
+void sregs_dump(struct kvm_vcpu *vcpu)
+{
+ vcpu_printf(vcpu, "************************ sregs_dump ************************\n");
+ vcpu_printf(vcpu, "cr0 = 0x%lx\n", guest_cr0());
+ vcpu_printf(vcpu, "cr2 = 0x%lx\n", vcpu->cr2);
+ vcpu_printf(vcpu, "cr3 = 0x%lx\n", vcpu->cr3);
+ vcpu_printf(vcpu, "cr4 = 0x%lx\n", guest_cr4());
+ vcpu_printf(vcpu, "cr8 = 0x%lx\n", vcpu->cr8);
+ vcpu_printf(vcpu, "shadow_efer = 0x%llx\n", vcpu->shadow_efer);
+ vmcs_dump(vcpu);
+ vcpu_printf(vcpu, "***********************************************************\n");
+}
+
+#endif
+
Index: linux-2.6/drivers/kvm/debug.h
===================================================================
--- /dev/null
+++ linux-2.6/drivers/kvm/debug.h
@@ -0,0 +1,21 @@
+#ifndef __KVM_DEBUG_H
+#define __KVM_DEBUG_H
+
+#ifdef KVM_DEBUG
+
+void show_msrs(struct kvm_vcpu *vcpu);
+
+
+void show_irq(struct kvm_vcpu *vcpu, int irq);
+void show_page(struct kvm_vcpu *vcpu, gva_t addr);
+void show_u64(struct kvm_vcpu *vcpu, gva_t addr);
+void show_code(struct kvm_vcpu *vcpu);
+int vm_entry_test(struct kvm_vcpu *vcpu);
+
+void vmcs_dump(struct kvm_vcpu *vcpu);
+void regs_dump(struct kvm_vcpu *vcpu);
+void sregs_dump(struct kvm_vcpu *vcpu);
+
+#endif
+
+#endif
Index: linux-2.6/drivers/kvm/kvm.h
===================================================================
--- linux-2.6.orig/drivers/kvm/kvm.h
+++ linux-2.6/drivers/kvm/kvm.h
@@ -9,6 +9,8 @@
#include "vmx.h"
+#define KVM_DEBUG 1
+
#define CR0_PE_MASK (1ULL << 0)
#define CR0_TS_MASK (1ULL << 3)
#define CR0_NE_MASK (1ULL << 5)
Index: linux-2.6/drivers/kvm/kvm_main.c
===================================================================
--- linux-2.6.orig/drivers/kvm/kvm_main.c
+++ linux-2.6/drivers/kvm/kvm_main.c
@@ -33,6 +33,7 @@
#include "vmx.h"
#include "x86_emulate.h"
+#include "debug.h"
MODULE_AUTHOR("Qumranet");
MODULE_LICENSE("GPL");
@@ -1107,6 +1108,9 @@ static int kvm_vcpu_setup(struct kvm_vcp
int nr_good_msrs;
+ printk("*** vcpu_setup begin\n");
+ vmcs_dump(vcpu);
+
if (!init_rmode_tss(vcpu->kvm)) {
ret = 0;
goto out;
@@ -1303,6 +1307,9 @@ static int kvm_vcpu_setup(struct kvm_vcp
ret = kvm_mmu_init(vcpu);
+ printk("*** vcpu_setup end\n");
+ vmcs_dump(vcpu);
+
return ret;
out_free_guest_msrs:
@@ -2618,6 +2625,9 @@ again:
fx_save(vcpu->host_fx_image);
fx_restore(vcpu->guest_fx_image);
+ printk("*** pre launch\n");
+ vmcs_dump(vcpu);
+
save_msrs(vcpu->host_msrs, vcpu->nmsrs);
load_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
@@ -2740,6 +2750,9 @@ again:
[cr2]"i"(offsetof(struct kvm_vcpu, cr2))
: "cc", "memory" );
+ printk("*** post launch\n");
+ vmcs_dump(vcpu);
+
++kvm_stat.exits;
save_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
[-- Attachment #3: Type: text/plain, Size: 373 bytes --]
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
[-- Attachment #4: Type: text/plain, Size: 186 bytes --]
_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel
next prev parent reply other threads:[~2006-11-07 14:11 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-11-06 13:15 [PATCH] KVM: fix calculation of initial value of rdx register Avi Kivity
2006-11-06 13:15 ` Avi Kivity
2006-11-06 18:47 ` Hesse, Christian
[not found] ` <200611061947.47165.mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
2006-11-07 8:14 ` Avi Kivity
[not found] ` <4550407F.6030007-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2006-11-07 11:55 ` Hesse, Christian
[not found] ` <200611071255.59831.mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
2006-11-07 12:31 ` Avi Kivity
[not found] ` <45507C84.70504-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2006-11-07 13:04 ` Hesse, Christian
[not found] ` <200611071404.38825.mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
2006-11-07 13:25 ` Avi Kivity
[not found] ` <4550893A.1000304-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2006-11-07 13:46 ` Hesse, Christian
[not found] ` <200611071446.17870.mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
2006-11-07 14:11 ` Avi Kivity [this message]
[not found] ` <4550941E.4070409-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2006-11-08 8:04 ` Hesse, Christian
[not found] ` <200611080904.27777.mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
2006-11-08 8:11 ` Avi Kivity
[not found] ` <4551914D.70303-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2006-11-08 8:24 ` Hesse, Christian
[not found] ` <200611080924.59607.mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
2006-11-08 8:28 ` Avi Kivity
[not found] ` <45519512.3050606-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2006-11-09 12:10 ` Hesse, Christian
[not found] ` <200611091310.25066.mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
2006-11-09 13:01 ` Avi Kivity
[not found] ` <455326C3.90601-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2006-11-09 13:29 ` Hesse, Christian
[not found] ` <200611091429.57097.mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
2006-11-09 14:03 ` Hesse, Christian
[not found] ` <200611091503.25231.mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
2006-11-09 14:27 ` Avi Kivity
2006-11-10 8:09 ` Hesse, Christian
[not found] ` <200611100909.32168.mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
2006-11-10 15:51 ` Avi Kivity
[not found] ` <45549FF0.8070207-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2006-11-14 10:41 ` Avi Kivity
[not found] ` <45599D57.2090001-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2006-11-14 10:55 ` Avi Kivity
2006-11-16 13:03 ` Hesse, Christian
[not found] ` <200611161403.13461.mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
2006-11-18 10:16 ` Hesse, Christian
[not found] ` <200611181116.07278.mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org>
2006-11-19 8:22 ` Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4550941E.4070409@qumranet.com \
--to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
--cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=mail-8oMOrB1mGocUSW6y5lq3GQ@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.