More pruning of files we don't need.
authorRon Minnich <rminnich@gmail.com>
Mon, 16 Mar 2015 17:43:48 +0000 (10:43 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 17 Mar 2015 14:33:39 +0000 (10:33 -0400)
(git-fu'd by brho)

14 files changed:
kern/arch/x86/virtext.h [deleted file]
kern/arch/x86/vm.h [deleted file]
kern/arch/x86/vmdebug.h [deleted file]
kern/arch/x86/vmm/func.h [deleted file]
kern/arch/x86/vmm/intel/vmcs.h [deleted file]
kern/arch/x86/vmm/intel/vmx_cpufunc.h [deleted file]
kern/arch/x86/vmm/x86.h [deleted file]
kern/arch/x86/vmx.c [deleted file]
kern/arch/x86/vmx.h [deleted file]
kern/arch/x86/vmx_mmu.c [deleted file]
kern/drivers/dev/Kbuild
kern/drivers/dev/nix.c
kern/drivers/dev/vm.c [deleted file]
kern/include/smp.h

diff --git a/kern/arch/x86/virtext.h b/kern/arch/x86/virtext.h
deleted file mode 100644 (file)
index 75fb11b..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/* CPU virtualization extensions handling
- *
- * This should carry the code for handling CPU virtualization extensions
- * that needs to live in the kernel core.
- *
- * Author: Eduardo Habkost <ehabkost@redhat.com>
- *
- * Copyright (C) 2008, Red Hat Inc.
- *
- * Contains code from KVM, Copyright (C) 2006 Qumranet, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- */
-#ifndef VIRTEX_H
-#define VIRTEX_H
-
-/*
- * VMX functions:
- */
-
-static inline int cpu_has_vmx(void)
-{
-       unsigned long ecx = cpuid_ecx(1);
-       return ecx & (1<<5); /* CPUID.1:ECX.VMX[bit 5] -> VT */
-}
-
-
-/** Disable VMX on the current CPU
- *
- * vmxoff causes a undefined-opcode exception if vmxon was not run
- * on the CPU previously. Only call this function if you know VMX
- * is enabled.
- */
-static inline void cpu_vmxoff(void)
-{
-       asm volatile (ASM_VMX_VMXOFF : : : "cc");
-       lcr4(rcr4() & ~X86_CR4_VMXE);
-}
-
-static inline int cpu_vmx_enabled(void)
-{
-       return rcr4() & X86_CR4_VMXE;
-}
-
-/** Disable VMX if it is enabled on the current CPU
- *
- * You shouldn't call this if cpu_has_vmx() returns 0.
- */
-static inline void __cpu_emergency_vmxoff(void)
-{
-       if (cpu_vmx_enabled())
-               cpu_vmxoff();
-}
-
-/** Disable VMX if it is supported and enabled on the current CPU
- */
-static inline void cpu_emergency_vmxoff(void)
-{
-       if (cpu_has_vmx())
-               __cpu_emergency_vmxoff();
-}
-
-#if 0
-
-
-/*
- * SVM functions:
- */
-
-/** Check if the CPU has SVM support
- *
- * You can use the 'msg' arg to get a message describing the problem,
- * if the function returns zero. Simply pass NULL if you are not interested
- * on the messages; gcc should take care of not generating code for
- * the messages on this case.
- */
-static inline int cpu_has_svm(const char **msg)
-{
-       uint32_t eax, ebx, ecx, edx;
-
-       if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) {
-               if (msg)
-                       *msg = "not amd";
-               return 0;
-       }
-
-       cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
-       if (eax < SVM_CPUID_FUNC) {
-               if (msg)
-                       *msg = "can't execute cpuid_8000000a";
-               return 0;
-       }
-
-       cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
-       if (!(ecx & (1 << SVM_CPUID_FEATURE_SHIFT))) {
-               if (msg)
-                       *msg = "svm not available";
-               return 0;
-       }
-       return 1;
-}
-
-
-/** Disable SVM on the current CPU
- *
- * You should call this only if cpu_has_svm() returned true.
- */
-static inline void cpu_svm_disable(void)
-{
-       uint64_t efer;
-
-       wrmsrl(MSR_VM_HSAVE_PA, 0);
-       rdmsrl(MSR_EFER, efer);
-       wrmsrl(MSR_EFER, efer & ~EFER_SVME);
-}
-
-/** Makes sure SVM is disabled, if it is supported on the CPU
- */
-static inline void cpu_emergency_svm_disable(void)
-{
-       if (cpu_has_svm(NULL))
-               cpu_svm_disable();
-}
-#endif
-#endif /* _ASM_X86_VIRTEX_H */
diff --git a/kern/arch/x86/vm.h b/kern/arch/x86/vm.h
deleted file mode 100644 (file)
index ee7fc8c..0000000
+++ /dev/null
@@ -1,571 +0,0 @@
-#ifndef __LITEVM_H
-#define __LITEVM_H
-#include <page_alloc.h>
-#include <pmap.h>
-#include "vmx.h"
-
-#include <list.h>
-
-#define CR0_PE_MASK (1ULL << 0)
-#define CR0_TS_MASK (1ULL << 3)
-#define CR0_NE_MASK (1ULL << 5)
-#define CR0_WP_MASK (1ULL << 16)
-#define CR0_NW_MASK (1ULL << 29)
-#define CR0_CD_MASK (1ULL << 30)
-#define CR0_PG_MASK (1ULL << 31)
-
-#define CR3_WPT_MASK (1ULL << 3)
-#define CR3_PCD_MASK (1ULL << 4)
-
-#define CR3_RESEVED_BITS 0x07ULL
-#define CR3_L_MODE_RESEVED_BITS (~((1ULL << 40) - 1) | 0x0fe7ULL)
-#define CR3_FLAGS_MASK ((1ULL << 5) - 1)
-
-#define CR4_VME_MASK (1ULL << 0)
-#define CR4_PSE_MASK (1ULL << 4)
-#define CR4_PAE_MASK (1ULL << 5)
-#define CR4_PGE_MASK (1ULL << 7)
-#define CR4_VMXE_MASK (1ULL << 13)
-
-#define LITEVM_GUEST_CR0_MASK \
-       (CR0_PG_MASK | CR0_PE_MASK | CR0_WP_MASK | CR0_NE_MASK)
-#define LITEVM_VM_CR0_ALWAYS_ON LITEVM_GUEST_CR0_MASK
-
-#define LITEVM_GUEST_CR4_MASK \
-       (CR4_PSE_MASK | CR4_PAE_MASK | CR4_PGE_MASK | CR4_VMXE_MASK | CR4_VME_MASK)
-#define LITEVM_PMODE_VM_CR4_ALWAYS_ON (CR4_VMXE_MASK | CR4_PAE_MASK)
-#define LITEVM_RMODE_VM_CR4_ALWAYS_ON (CR4_VMXE_MASK | CR4_PAE_MASK | CR4_VME_MASK)
-
-#define INVALID_PAGE (~(hpa_t)0)
-#define UNMAPPED_GVA (~(gpa_t)0)
-
-#define LITEVM_MAX_VCPUS 1
-#define LITEVM_MEMORY_SLOTS 4
-#define LITEVM_NUM_MMU_PAGES 256
-
-#define FX_IMAGE_SIZE 512
-#define FX_IMAGE_ALIGN 16
-#define FX_BUF_SIZE (2 * FX_IMAGE_SIZE + FX_IMAGE_ALIGN)
-
-#define DE_VECTOR 0
-#define DF_VECTOR 8
-#define TS_VECTOR 10
-#define NP_VECTOR 11
-#define SS_VECTOR 12
-#define GP_VECTOR 13
-#define PF_VECTOR 14
-
-#define SELECTOR_TI_MASK (1 << 2)
-#define SELECTOR_RPL_MASK 0x03
-
-#define IOPL_SHIFT 12
-
-/*
- * Address types:
- *
- *  gva - guest virtual address
- *  gpa - guest physical address
- *  gfn - guest frame number
- *  hva - host virtual address
- *  hpa - host physical address
- *  hfn - host frame number
- */
-
-typedef unsigned long gva_t;
-typedef uint64_t gpa_t;
-typedef unsigned long gfn_t;
-
-typedef unsigned long hva_t;
-typedef uint64_t hpa_t;
-typedef unsigned long hfn_t;
-
-struct litevm_mmu_page {
-       struct list_head link;
-       hpa_t page_hpa;
-       unsigned long slot_bitmap;      /* One bit set per slot which has memory
-                                                                * in this shadow page.
-                                                                */
-       int global;                                     /* Set if all ptes in this page are global */
-       uint64_t *parent_pte;
-};
-
-struct vmcs {
-       uint32_t revision_id;
-       uint32_t abort;
-       char data[0];
-};
-
-struct litevm_vcpu;
-
-/*
- * x86 supports 3 paging modes (4-level 64-bit, 3-level 64-bit, and 2-level
- * 32-bit).  The litevm_mmu structure abstracts the details of the current mmu
- * mode.
- */
-struct litevm_mmu {
-       void (*new_cr3) (struct litevm_vcpu * vcpu);
-       int (*page_fault) (struct litevm_vcpu * vcpu, gva_t gva, uint32_t err);
-       void (*inval_page) (struct litevm_vcpu * vcpu, gva_t gva);
-       void (*free) (struct litevm_vcpu * vcpu);
-        gpa_t(*gva_to_gpa) (struct litevm_vcpu * vcpu, gva_t gva);
-       hpa_t root_hpa;
-       int root_level;
-       int shadow_root_level;
-};
-
-struct litevm_guest_debug {
-       int enabled;
-       unsigned long bp[4];
-       int singlestep;
-};
-
-enum {
-       VCPU_REGS_RAX = 0,
-       VCPU_REGS_RCX = 1,
-       VCPU_REGS_RDX = 2,
-       VCPU_REGS_RBX = 3,
-       VCPU_REGS_RSP = 4,
-       VCPU_REGS_RBP = 5,
-       VCPU_REGS_RSI = 6,
-       VCPU_REGS_RDI = 7,
-#ifdef __x86_64__
-       VCPU_REGS_R8 = 8,
-       VCPU_REGS_R9 = 9,
-       VCPU_REGS_R10 = 10,
-       VCPU_REGS_R11 = 11,
-       VCPU_REGS_R12 = 12,
-       VCPU_REGS_R13 = 13,
-       VCPU_REGS_R14 = 14,
-       VCPU_REGS_R15 = 15,
-#endif
-       NR_VCPU_REGS
-};
-
-struct litevm_vcpu {
-       struct litevm *litevm;
-       struct vmcs *vmcs;
-       qlock_t mutex;
-       int cpu;
-       int launched;
-       unsigned long irq_summary;      /* bit vector: 1 per word in irq_pending */
-#define NR_IRQ_WORDS (256 / BITS_PER_LONG)
-       unsigned long irq_pending[NR_IRQ_WORDS];
-       unsigned long regs[NR_VCPU_REGS];       /* for rsp: vcpu_load_rsp_rip() */
-       unsigned long rip;                      /* needs vcpu_load_rsp_rip() */
-
-       unsigned long cr2;
-       unsigned long cr3;
-       unsigned long cr8;
-       uint64_t shadow_efer;
-       uint64_t apic_base;
-       int nmsrs;
-       struct vmx_msr_entry *guest_msrs;
-       struct vmx_msr_entry *host_msrs;
-       struct list_head free_pages;
-       struct litevm_mmu_page page_header_buf[LITEVM_NUM_MMU_PAGES];
-       struct litevm_mmu mmu;
-
-       struct litevm_guest_debug guest_debug;
-
-       char fx_buf[FX_BUF_SIZE];
-       char *host_fx_image;
-       char *guest_fx_image;
-
-       int mmio_needed;
-       int mmio_read_completed;
-       int mmio_is_write;
-       int mmio_size;
-       unsigned char mmio_data[8];
-       gpa_t mmio_phys_addr;
-
-       struct {
-               int active;
-               uint8_t save_iopl;
-               struct {
-                       unsigned long base;
-                       uint32_t limit;
-                       uint32_t ar;
-               } tr;
-       } rmode;
-};
-
-struct litevm_memory_slot {
-       gfn_t base_gfn;
-       unsigned long npages;
-       unsigned long flags;
-       struct page **phys_mem;
-//#warning "bitmap is u8. "
-       /*unsigned long */ uint8_t *dirty_bitmap;
-};
-
-struct litevm {
-       spinlock_t lock;                        /* protects everything except vcpus */
-       int nmemslots;
-       struct litevm_memory_slot memslots[LITEVM_MEMORY_SLOTS];
-       struct list_head active_mmu_pages;
-       struct litevm_vcpu vcpus[LITEVM_MAX_VCPUS];
-       int memory_config_version;
-       int busy;
-};
-
-struct litevm_stat {
-       uint32_t pf_fixed;
-       uint32_t pf_guest;
-       uint32_t tlb_flush;
-       uint32_t invlpg;
-
-       uint32_t exits;
-       uint32_t io_exits;
-       uint32_t mmio_exits;
-       uint32_t signal_exits;
-       uint32_t irq_exits;
-};
-
-extern struct litevm_stat litevm_stat;
-
-#define litevm_printf(litevm, fmt ...) printd(fmt)
-#define vcpu_printf(vcpu, fmt...) litevm_printf(vcpu->litevm, fmt)
-
-void litevm_mmu_destroy(struct litevm_vcpu *vcpu);
-int litevm_mmu_init(struct litevm_vcpu *vcpu);
-
-int litevm_mmu_reset_context(struct litevm_vcpu *vcpu);
-void litevm_mmu_slot_remove_write_access(struct litevm *litevm, int slot);
-
-hpa_t gpa_to_hpa(struct litevm_vcpu *vcpu, gpa_t gpa);
-#define HPA_MSB ((sizeof(hpa_t) * 8) - 1)
-#define HPA_ERR_MASK ((hpa_t)1 << HPA_MSB)
-static inline int is_error_hpa(hpa_t hpa)
-{
-       return hpa >> HPA_MSB;
-}
-
-hpa_t gva_to_hpa(struct litevm_vcpu * vcpu, gva_t gva);
-
-extern hpa_t bad_page_address;
-
-static inline struct page *gfn_to_page(struct litevm_memory_slot *slot,
-                                                                          gfn_t gfn)
-{
-       return slot->phys_mem[gfn - slot->base_gfn];
-}
-
-struct litevm_memory_slot *gfn_to_memslot(struct litevm *litevm, gfn_t gfn);
-void mark_page_dirty(struct litevm *litevm, gfn_t gfn);
-
-void realmode_lgdt(struct litevm_vcpu *vcpu, uint16_t size,
-                                  unsigned long address);
-void realmode_lidt(struct litevm_vcpu *vcpu, uint16_t size,
-                                  unsigned long address);
-void realmode_lmsw(struct litevm_vcpu *vcpu, unsigned long msw,
-                                  unsigned long *rflags);
-
-unsigned long realmode_get_cr(struct litevm_vcpu *vcpu, int cr);
-void realmode_set_cr(struct litevm_vcpu *vcpu, int cr, unsigned long value,
-                                        unsigned long *rflags);
-
-int litevm_read_guest(struct litevm_vcpu *vcpu,
-                                         gva_t addr, unsigned long size, void *dest);
-
-int litevm_write_guest(struct litevm_vcpu *vcpu,
-                                          gva_t addr, unsigned long size, void *data);
-
-void vmcs_writel(unsigned long field, unsigned long value);
-unsigned long vmcs_readl(unsigned long field);
-
-static inline uint16_t vmcs_read16(unsigned long field)
-{
-       return vmcs_readl(field);
-}
-
-static inline uint32_t vmcs_read32(unsigned long field)
-{
-       return vmcs_readl(field);
-}
-
-static inline uint64_t vmcs_read64(unsigned long field)
-{
-#ifdef __x86_64__
-       return vmcs_readl(field);
-#else
-       return vmcs_readl(field) | ((uint64_t) vmcs_readl(field + 1) << 32);
-#endif
-}
-
-static inline void vmcs_write32(unsigned long field, uint32_t value)
-{
-       vmcs_writel(field, value);
-}
-
-static inline int is_long_mode(void)
-{
-       return vmcs_read32(VM_ENTRY_CONTROLS) & VM_ENTRY_CONTROLS_IA32E_MASK;
-}
-
-static inline unsigned long guest_cr4(void)
-{
-       return (vmcs_readl(CR4_READ_SHADOW) & LITEVM_GUEST_CR4_MASK) |
-               (vmcs_readl(GUEST_CR4) & ~LITEVM_GUEST_CR4_MASK);
-}
-
-static inline int is_pae(void)
-{
-       return guest_cr4() & CR4_PAE_MASK;
-}
-
-static inline int is_pse(void)
-{
-       return guest_cr4() & CR4_PSE_MASK;
-}
-
-static inline unsigned long guest_cr0(void)
-{
-       return (vmcs_readl(CR0_READ_SHADOW) & LITEVM_GUEST_CR0_MASK) |
-               (vmcs_readl(GUEST_CR0) & ~LITEVM_GUEST_CR0_MASK);
-}
-
-static inline unsigned guest_cpl(void)
-{
-       return vmcs_read16(GUEST_CS_SELECTOR) & SELECTOR_RPL_MASK;
-}
-
-static inline int is_paging(void)
-{
-       return guest_cr0() & CR0_PG_MASK;
-}
-
-static inline int is_page_fault(uint32_t intr_info)
-{
-       return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK |
-                                                INTR_INFO_VALID_MASK)) ==
-               (INTR_TYPE_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK);
-}
-
-static inline int is_external_interrupt(uint32_t intr_info)
-{
-       return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK))
-               == (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK);
-}
-
-static inline void flush_guest_tlb(struct litevm_vcpu *vcpu)
-{
-       vmcs_writel(GUEST_CR3, vmcs_readl(GUEST_CR3));
-}
-
-static inline int memslot_id(struct litevm *litevm,
-                                                        struct litevm_memory_slot *slot)
-{
-       return slot - litevm->memslots;
-}
-
-static inline struct litevm_mmu_page *page_header(hpa_t shadow_page)
-{
-       struct page *page = ppn2page(shadow_page >> PAGE_SHIFT);
-
-       return (struct litevm_mmu_page *)page->pg_private;
-}
-
-#ifdef __x86_64__
-
-/*
- * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64.  Therefore
- * we need to allocate shadow page tables in the first 4GB of memory, which
- * happens to fit the DMA32 zone.
- */
-#define GFP_LITEVM_MMU (GFP_KERNEL | __GFP_DMA32)
-
-#else
-
-#define GFP_LITEVM_MMU GFP_KERNEL
-
-#endif
-
-/* just to get things to build ... include this stuff for now.
- * at some point, this interface gets nuke to and made more plan 
- * 9 like.
- */
-
-/* for LITEVM_CREATE_MEMORY_REGION */
-struct litevm_memory_region {
-       uint32_t slot;
-       uint32_t flags;
-       uint64_t guest_phys_addr;
-       uint64_t memory_size;           /* bytes */
-       void *init_data;
-};
-
-/* for litevm_memory_region::flags */
-#define LITEVM_MEM_LOG_DIRTY_PAGES  1UL
-
-#define LITEVM_EXIT_TYPE_FAIL_ENTRY 1
-#define LITEVM_EXIT_TYPE_VM_EXIT    2
-
-enum litevm_exit_reason {
-       LITEVM_EXIT_UNKNOWN,
-       LITEVM_EXIT_EXCEPTION,
-       LITEVM_EXIT_IO,
-       LITEVM_EXIT_CPUID,
-       LITEVM_EXIT_DEBUG,
-       LITEVM_EXIT_HLT,
-       LITEVM_EXIT_MMIO,
-};
-
-/* for LITEVM_RUN */
-struct litevm_run {
-       /* in */
-       uint32_t vcpu;
-       uint32_t emulated;                      /* skip current instruction */
-       uint32_t mmio_completed;        /* mmio request completed */
-
-       /* out */
-       uint32_t exit_type;
-       uint32_t exit_reason;
-       uint32_t instruction_length;
-       union {
-               /* LITEVM_EXIT_UNKNOWN */
-               struct {
-                       uint32_t hardware_exit_reason;
-               } hw;
-               /* LITEVM_EXIT_EXCEPTION */
-               struct {
-                       uint32_t exception;
-                       uint32_t error_code;
-               } ex;
-               /* LITEVM_EXIT_IO */
-               struct {
-#define LITEVM_EXIT_IO_IN  0
-#define LITEVM_EXIT_IO_OUT 1
-                       uint8_t direction;
-                       uint8_t size;           /* bytes */
-                       uint8_t string;
-                       uint8_t string_down;
-                       uint8_t rep;
-                       uint8_t pad;
-                       uint16_t port;
-                       uint64_t count;
-                       union {
-                               uint64_t address;
-                               uint32_t value;
-                       };
-               } io;
-               struct {
-               } debug;
-               /* LITEVM_EXIT_MMIO */
-               struct {
-                       uint64_t phys_addr;
-                       uint8_t data[8];
-                       uint32_t len;
-                       uint8_t is_write;
-               } mmio;
-       };
-};
-
-/* for LITEVM_GET_REGS and LITEVM_SET_REGS */
-struct litevm_regs {
-       /* in */
-       uint32_t vcpu;
-       uint32_t padding;
-
-       /* out (LITEVM_GET_REGS) / in (LITEVM_SET_REGS) */
-       uint64_t rax, rbx, rcx, rdx;
-       uint64_t rsi, rdi, rsp, rbp;
-       uint64_t r8, r9, r10, r11;
-       uint64_t r12, r13, r14, r15;
-       uint64_t rip, rflags;
-};
-
-struct litevm_segment {
-       uint64_t base;
-       uint32_t limit;
-       uint16_t selector;
-       uint8_t type;
-       uint8_t present, dpl, db, s, l, g, avl;
-       uint8_t unusable;
-       uint8_t padding;
-};
-
-struct litevm_dtable {
-       uint64_t base;
-       uint16_t limit;
-       uint16_t padding[3];
-};
-
-/* for LITEVM_GET_SREGS and LITEVM_SET_SREGS */
-struct litevm_sregs {
-       /* in */
-       uint32_t vcpu;
-       uint32_t padding;
-
-       /* out (LITEVM_GET_SREGS) / in (LITEVM_SET_SREGS) */
-       struct litevm_segment cs, ds, es, fs, gs, ss;
-       struct litevm_segment tr, ldt;
-       struct litevm_dtable gdt, idt;
-       uint64_t cr0, cr2, cr3, cr4, cr8;
-       uint64_t efer;
-       uint64_t apic_base;
-
-       /* out (LITEVM_GET_SREGS) */
-       uint32_t pending_int;
-       uint32_t padding2;
-};
-
-/* for LITEVM_TRANSLATE */
-struct litevm_translation {
-       /* in */
-       uint64_t linear_address;
-       uint32_t vcpu;
-       uint32_t padding;
-
-       /* out */
-       uint64_t physical_address;
-       uint8_t valid;
-       uint8_t writeable;
-       uint8_t usermode;
-};
-
-/* for LITEVM_INTERRUPT */
-struct litevm_interrupt {
-       /* in */
-       uint32_t vcpu;
-       uint32_t irq;
-};
-
-struct litevm_breakpoint {
-       uint32_t enabled;
-       uint32_t padding;
-       uint64_t address;
-};
-
-/* for LITEVM_DEBUG_GUEST */
-struct litevm_debug_guest {
-       /* int */
-       uint32_t vcpu;
-       uint32_t enabled;
-       struct litevm_breakpoint breakpoints[4];
-       uint32_t singlestep;
-};
-
-/* for LITEVM_GET_DIRTY_LOG */
-struct litevm_dirty_log {
-       uint32_t slot;
-       uint32_t padding;
-       union {
-               void *dirty_bitmap;             /* one bit per page */
-               uint64_t paddingw;
-       };
-};
-
-enum {
-       LITEVM_RUN = 1,
-       LITEVM_GET_REGS,
-       LITEVM_SET_REGS,
-       LITEVM_GET_SREGS,
-       LITEVM_SET_SREGS,
-       LITEVM_TRANSLATE,
-       LITEVM_INTERRUPT,
-       LITEVM_DEBUG_GUEST,
-       LITEVM_SET_MEMORY_REGION,
-       LITEVM_CREATE_VCPU,
-       LITEVM_GET_DIRTY_LOG,
-};
-#endif
diff --git a/kern/arch/x86/vmdebug.h b/kern/arch/x86/vmdebug.h
deleted file mode 100644 (file)
index 49e5ae4..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/******************************************************************************
- * x86_emulate.h
- *
- * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
- *
- * Copyright (c) 2005 Keir Fraser
- *
- * From: xen-unstable 10676:af9809f51f81a3c43f276f00c81a52ef558afda4
- */
-
-#ifndef __X86_EMULATE_H__
-#define __X86_EMULATE_H__
-
-struct x86_emulate_ctxt;
-
-/*
- * x86_emulate_ops:
- *
- * These operations represent the instruction emulator's interface to memory.
- * There are two categories of operation: those that act on ordinary memory
- * regions (*_std), and those that act on memory regions known to require
- * special treatment or emulation (*_emulated).
- *
- * The emulator assumes that an instruction accesses only one 'emulated memory'
- * location, that this location is the given linear faulting address (cr2), and
- * that this is one of the instruction's data operands. Instruction fetches and
- * stack operations are assumed never to access emulated memory. The emulator
- * automatically deduces which operand of a string-move operation is accessing
- * emulated memory, and assumes that the other operand accesses normal memory.
- *
- * NOTES:
- *  1. The emulator isn't very smart about emulated vs. standard memory.
- *     'Emulated memory' access addresses should be checked for sanity.
- *     'Normal memory' accesses may fault, and the caller must arrange to
- *     detect and handle reentrancy into the emulator via recursive faults.
- *     Accesses may be unaligned and may cross page boundaries.
- *  2. If the access fails (cannot emulate, or a standard access faults) then
- *     it is up to the memop to propagate the fault to the guest VM via
- *     some out-of-band mechanism, unknown to the emulator. The memop signals
- *     failure by returning X86EMUL_PROPAGATE_FAULT to the emulator, which will
- *     then immediately bail.
- *  3. Valid access sizes are 1, 2, 4 and 8 bytes. On x86/32 systems only
- *     cmpxchg8b_emulated need support 8-byte accesses.
- *  4. The emulator cannot handle 64-bit mode emulation on an x86/32 system.
- */
-/* Access completed successfully: continue emulation as normal. */
-#define X86EMUL_CONTINUE        0
-/* Access is unhandleable: bail from emulation and return error to caller. */
-#define X86EMUL_UNHANDLEABLE    1
-/* Terminate emulation but return success to the caller. */
-#define X86EMUL_PROPAGATE_FAULT 2      /* propagate a generated fault to guest */
-#define X86EMUL_RETRY_INSTR     2      /* retry the instruction for some reason */
-#define X86EMUL_CMPXCHG_FAILED  2      /* cmpxchg did not see expected value */
-struct x86_emulate_ops {
-       /*
-        * read_std: Read bytes of standard (non-emulated/special) memory.
-        *           Used for instruction fetch, stack operations, and others.
-        *  @addr:  [IN ] Linear address from which to read.
-        *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'.
-        *  @bytes: [IN ] Number of bytes to read from memory.
-        */
-       int (*read_std) (unsigned long addr,
-                                        unsigned long *val,
-                                        unsigned int bytes, struct x86_emulate_ctxt * ctxt);
-
-       /*
-        * write_std: Write bytes of standard (non-emulated/special) memory.
-        *            Used for stack operations, and others.
-        *  @addr:  [IN ] Linear address to which to write.
-        *  @val:   [IN ] Value to write to memory (low-order bytes used as
-        *                required).
-        *  @bytes: [IN ] Number of bytes to write to memory.
-        */
-       int (*write_std) (unsigned long addr,
-                                         unsigned long val,
-                                         unsigned int bytes, struct x86_emulate_ctxt * ctxt);
-
-       /*
-        * read_emulated: Read bytes from emulated/special memory area.
-        *  @addr:  [IN ] Linear address from which to read.
-        *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'.
-        *  @bytes: [IN ] Number of bytes to read from memory.
-        */
-       int (*read_emulated) (unsigned long addr,
-                                                 unsigned long *val,
-                                                 unsigned int bytes, struct x86_emulate_ctxt * ctxt);
-
-       /*
-        * write_emulated: Read bytes from emulated/special memory area.
-        *  @addr:  [IN ] Linear address to which to write.
-        *  @val:   [IN ] Value to write to memory (low-order bytes used as
-        *                required).
-        *  @bytes: [IN ] Number of bytes to write to memory.
-        */
-       int (*write_emulated) (unsigned long addr,
-                                                  unsigned long val,
-                                                  unsigned int bytes, struct x86_emulate_ctxt * ctxt);
-
-       /*
-        * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an
-        *                   emulated/special memory area.
-        *  @addr:  [IN ] Linear address to access.
-        *  @old:   [IN ] Value expected to be current at @addr.
-        *  @new:   [IN ] Value to write to @addr.
-        *  @bytes: [IN ] Number of bytes to access using CMPXCHG.
-        */
-       int (*cmpxchg_emulated) (unsigned long addr,
-                                                        unsigned long old,
-                                                        unsigned long new,
-                                                        unsigned int bytes,
-                                                        struct x86_emulate_ctxt * ctxt);
-
-       /*
-        * cmpxchg8b_emulated: Emulate an atomic (LOCKed) CMPXCHG8B operation on an
-        *                     emulated/special memory area.
-        *  @addr:  [IN ] Linear address to access.
-        *  @old:   [IN ] Value expected to be current at @addr.
-        *  @new:   [IN ] Value to write to @addr.
-        * NOTES:
-        *  1. This function is only ever called when emulating a real CMPXCHG8B.
-        *  2. This function is *never* called on x86/64 systems.
-        *  2. Not defining this function (i.e., specifying NULL) is equivalent
-        *     to defining a function that always returns X86EMUL_UNHANDLEABLE.
-        */
-       int (*cmpxchg8b_emulated) (unsigned long addr,
-                                                          unsigned long old_lo,
-                                                          unsigned long old_hi,
-                                                          unsigned long new_lo,
-                                                          unsigned long new_hi,
-                                                          struct x86_emulate_ctxt * ctxt);
-};
-
-struct cpu_user_regs;
-
-struct x86_emulate_ctxt {
-       /* Register state before/after emulation. */
-       struct litevm_vcpu *vcpu;
-
-       /* Linear faulting address (if emulating a page-faulting instruction). */
-       unsigned long eflags;
-       unsigned long cr2;
-
-       /* Emulated execution mode, represented by an X86EMUL_MODE value. */
-       int mode;
-
-       unsigned long cs_base;
-       unsigned long ds_base;
-       unsigned long es_base;
-       unsigned long ss_base;
-       unsigned long gs_base;
-       unsigned long fs_base;
-};
-
-/* Execution mode, passed to the emulator. */
-#define X86EMUL_MODE_REAL     0        /* Real mode.             */
-#define X86EMUL_MODE_PROT16   2        /* 16-bit protected mode. */
-#define X86EMUL_MODE_PROT32   4        /* 32-bit protected mode. */
-#define X86EMUL_MODE_PROT64   8        /* 64-bit (long) mode.    */
-
-/* Host execution mode. */
-#if defined(__i386__)
-#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32
-#elif defined(__x86_64__)
-#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64
-#endif
-
-/*
- * x86_emulate_memop: Emulate an instruction that faulted attempting to
- *                    read/write a 'special' memory area.
- * Returns -1 on failure, 0 on success.
- */
-int x86_emulate_memop(struct x86_emulate_ctxt *ctxt,
-                                         struct x86_emulate_ops *ops);
-
-/*
- * Given the 'reg' portion of a ModRM byte, and a register block, return a
- * pointer into the block that addresses the relevant register.
- * @highbyte_regs specifies whether to decode AH,CH,DH,BH.
- */
-void *decode_register(u8 modrm_reg, unsigned long *regs, int highbyte_regs);
-
-#endif /* __X86_EMULATE_H__ */
diff --git a/kern/arch/x86/vmm/func.h b/kern/arch/x86/vmm/func.h
deleted file mode 100644 (file)
index be3194e..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*-
- * Copyright (c) 2011 NetApp, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _VMM_FUNC_H_
-#define        _VMM_FUNC_H_
-
-/* APIs to inject faults into the guest */
-void vm_inject_fault(void *vm, int vcpuid, int vector, int errcode_valid,
-    int errcode);
-
-static __inline void
-vm_inject_ud(void *vm, int vcpuid)
-{
-       vm_inject_fault(vm, vcpuid, T_ILLOP, 0, 0);
-}
-
-static __inline void
-vm_inject_gp(void *vm, int vcpuid)
-{
-       vm_inject_fault(vm, vcpuid, T_GPFLT, 1, 0);
-}
-
-static __inline void
-vm_inject_ac(void *vm, int vcpuid, int errcode)
-{
-       vm_inject_fault(vm, vcpuid, T_ALIGN, 1, errcode);
-}
-
-static __inline void
-vm_inject_ss(void *vm, int vcpuid, int errcode)
-{
-       vm_inject_fault(vm, vcpuid, T_STACK, 1, errcode);
-}
-
-void vm_inject_pf(void *vm, int vcpuid, int error_code, uint64_t cr2);
-
-int vm_restart_instruction(void *vm, int vcpuid);
-
-/* Intel functions */
-void vminit(struct proc *p);
-
-#endif /* _VMM_FUNC_H_ */
diff --git a/kern/arch/x86/vmm/intel/vmcs.h b/kern/arch/x86/vmm/intel/vmcs.h
deleted file mode 100644 (file)
index 19f42e0..0000000
+++ /dev/null
@@ -1,402 +0,0 @@
-/*-
- * Copyright (c) 2011 NetApp, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _VMCS_H_
-#define        _VMCS_H_
-
-#ifdef ROS_KERNEL
-struct vmcs {
-       uint32_t identifier;
-       uint32_t abort_code;
-       char _impl_specific[PAGE_SIZE - sizeof(uint32_t) * 2];
-};
-
-/* MSR save region is composed of an array of 'struct msr_entry' */
-struct msr_entry {
-       uint32_t index;
-       uint32_t reserved;
-       uint64_t val;
-
-};
-
-int vmcs_set_msr_save(struct vmcs *vmcs, unsigned long g_area,
-                     unsigned int g_count);
-int vmcs_init(struct vmcs *vmcs);
-int vmcs_getreg(struct vmcs *vmcs, int running, int ident, uint64_t * rv);
-int vmcs_setreg(struct vmcs *vmcs, int running, int ident, uint64_t val);
-int vmcs_getdesc(struct vmcs *vmcs, int running, int ident,
-                                syssegdesc_t*desc);
-int vmcs_setdesc(struct vmcs *vmcs, int running, int ident,
-                                syssegdesc_t*desc);
-
-static __inline uint64_t vmcs_read(uint32_t encoding)
-{
-       int error;
-       uint64_t val;
-       static_assert(sizeof(struct vmcs) == PAGE_SIZE);
-
-       error = vmread(encoding, &val);
-       // well, huh, what do we do?
-       if (error) {
-               printk("vmcs_read(%u) error %d", encoding, error);
-               assert(0);
-       }
-       return (val);
-}
-
-static __inline void vmcs_write(uint32_t encoding, uint64_t val)
-{
-       int error;
-
-       error = vmwrite(encoding, val);
-       if (error) {
-               printk("vmcs_write(%u) error %d", encoding, error);
-               assert(0);
-       }
-}
-
-#define        vmexit_instruction_length()     vmcs_read(VMCS_EXIT_INSTRUCTION_LENGTH)
-#define        vmcs_guest_rip()                vmcs_read(VMCS_GUEST_RIP)
-#define        vmcs_instruction_error()        vmcs_read(VMCS_INSTRUCTION_ERROR)
-#define        vmcs_exit_reason()              (vmcs_read(VMCS_EXIT_REASON) & 0xffff)
-#define        vmcs_exit_qualification()       vmcs_read(VMCS_EXIT_QUALIFICATION)
-#define        vmcs_guest_cr3()                vmcs_read(VMCS_GUEST_CR3)
-#define        vmcs_gpa()                      vmcs_read(VMCS_GUEST_PHYSICAL_ADDRESS)
-#define        vmcs_gla()                      vmcs_read(VMCS_GUEST_LINEAR_ADDRESS)
-#define        vmcs_idt_vectoring_info()       vmcs_read(VMCS_IDT_VECTORING_INFO)
-#define        vmcs_idt_vectoring_err()        vmcs_read(VMCS_IDT_VECTORING_ERROR)
-
-#endif /* ROS_KERNEL */
-
-#define        VMCS_INITIAL                    0xffffffffffffffff
-
-#define        VMCS_IDENT(encoding)            ((encoding) | 0x80000000)
-/*
- * VMCS field encodings from Appendix H, Intel Architecture Manual Vol3B.
- */
-#define        VMCS_INVALID_ENCODING           0xffffffff
-
-/* 16-bit control fields */
-#define        VMCS_VPID                       0x00000000
-#define        VMCS_PIR_VECTOR                 0x00000002
-
-/* 16-bit guest-state fields */
-#define        VMCS_GUEST_ES_SELECTOR          0x00000800
-#define        VMCS_GUEST_CS_SELECTOR          0x00000802
-#define        VMCS_GUEST_SS_SELECTOR          0x00000804
-#define        VMCS_GUEST_DS_SELECTOR          0x00000806
-#define        VMCS_GUEST_FS_SELECTOR          0x00000808
-#define        VMCS_GUEST_GS_SELECTOR          0x0000080A
-#define        VMCS_GUEST_LDTR_SELECTOR        0x0000080C
-#define        VMCS_GUEST_TR_SELECTOR          0x0000080E
-#define        VMCS_GUEST_INTR_STATUS          0x00000810
-
-/* 16-bit host-state fields */
-#define        VMCS_HOST_ES_SELECTOR           0x00000C00
-#define        VMCS_HOST_CS_SELECTOR           0x00000C02
-#define        VMCS_HOST_SS_SELECTOR           0x00000C04
-#define        VMCS_HOST_DS_SELECTOR           0x00000C06
-#define        VMCS_HOST_FS_SELECTOR           0x00000C08
-#define        VMCS_HOST_GS_SELECTOR           0x00000C0A
-#define        VMCS_HOST_TR_SELECTOR           0x00000C0C
-
-/* 64-bit control fields */
-#define        VMCS_IO_BITMAP_A                0x00002000
-#define        VMCS_IO_BITMAP_B                0x00002002
-#define        VMCS_MSR_BITMAP                 0x00002004
-#define        VMCS_EXIT_MSR_STORE             0x00002006
-#define        VMCS_EXIT_MSR_LOAD              0x00002008
-#define        VMCS_ENTRY_MSR_LOAD             0x0000200A
-#define        VMCS_EXECUTIVE_VMCS             0x0000200C
-#define        VMCS_TSC_OFFSET                 0x00002010
-#define        VMCS_VIRTUAL_APIC               0x00002012
-#define        VMCS_APIC_ACCESS                0x00002014
-#define        VMCS_PIR_DESC                   0x00002016
-#define        VMCS_EPTP                       0x0000201A
-#define        VMCS_EOI_EXIT0                  0x0000201C
-#define        VMCS_EOI_EXIT1                  0x0000201E
-#define        VMCS_EOI_EXIT2                  0x00002020
-#define        VMCS_EOI_EXIT3                  0x00002022
-#define        VMCS_EOI_EXIT(vector)           (VMCS_EOI_EXIT0 + ((vector) / 64) * 2)
-
-/* 64-bit read-only fields */
-#define        VMCS_GUEST_PHYSICAL_ADDRESS     0x00002400
-
-/* 64-bit guest-state fields */
-#define        VMCS_LINK_POINTER               0x00002800
-#define        VMCS_GUEST_IA32_DEBUGCTL        0x00002802
-#define        VMCS_GUEST_IA32_PAT             0x00002804
-#define        VMCS_GUEST_IA32_EFER            0x00002806
-#define        VMCS_GUEST_IA32_PERF_GLOBAL_CTRL 0x00002808
-#define        VMCS_GUEST_PDPTE0               0x0000280A
-#define        VMCS_GUEST_PDPTE1               0x0000280C
-#define        VMCS_GUEST_PDPTE2               0x0000280E
-#define        VMCS_GUEST_PDPTE3               0x00002810
-
-/* 64-bit host-state fields */
-#define        VMCS_HOST_IA32_PAT              0x00002C00
-#define        VMCS_HOST_IA32_EFER             0x00002C02
-#define        VMCS_HOST_IA32_PERF_GLOBAL_CTRL 0x00002C04
-
-/* 32-bit control fields */
-#define        VMCS_PIN_BASED_CTLS             0x00004000
-#define        VMCS_PRI_PROC_BASED_CTLS        0x00004002
-#define        VMCS_EXCEPTION_BITMAP           0x00004004
-#define        VMCS_PF_ERROR_MASK              0x00004006
-#define        VMCS_PF_ERROR_MATCH             0x00004008
-#define        VMCS_CR3_TARGET_COUNT           0x0000400A
-#define        VMCS_EXIT_CTLS                  0x0000400C
-#define        VMCS_EXIT_MSR_STORE_COUNT       0x0000400E
-#define        VMCS_EXIT_MSR_LOAD_COUNT        0x00004010
-#define        VMCS_ENTRY_CTLS                 0x00004012
-#define        VMCS_ENTRY_MSR_LOAD_COUNT       0x00004014
-#define        VMCS_ENTRY_INTR_INFO            0x00004016
-#define        VMCS_ENTRY_EXCEPTION_ERROR      0x00004018
-#define        VMCS_ENTRY_INST_LENGTH          0x0000401A
-#define        VMCS_TPR_THRESHOLD              0x0000401C
-#define        VMCS_SEC_PROC_BASED_CTLS        0x0000401E
-#define        VMCS_PLE_GAP                    0x00004020
-#define        VMCS_PLE_WINDOW                 0x00004022
-
-/* 32-bit read-only data fields */
-#define        VMCS_INSTRUCTION_ERROR          0x00004400
-#define        VMCS_EXIT_REASON                0x00004402
-#define        VMCS_EXIT_INTR_INFO             0x00004404
-#define        VMCS_EXIT_INTR_ERRCODE          0x00004406
-#define        VMCS_IDT_VECTORING_INFO         0x00004408
-#define        VMCS_IDT_VECTORING_ERROR        0x0000440A
-#define        VMCS_EXIT_INSTRUCTION_LENGTH    0x0000440C
-#define        VMCS_EXIT_INSTRUCTION_INFO      0x0000440E
-
-/* 32-bit guest-state fields */
-#define        VMCS_GUEST_ES_LIMIT             0x00004800
-#define        VMCS_GUEST_CS_LIMIT             0x00004802
-#define        VMCS_GUEST_SS_LIMIT             0x00004804
-#define        VMCS_GUEST_DS_LIMIT             0x00004806
-#define        VMCS_GUEST_FS_LIMIT             0x00004808
-#define        VMCS_GUEST_GS_LIMIT             0x0000480A
-#define        VMCS_GUEST_LDTR_LIMIT           0x0000480C
-#define        VMCS_GUEST_TR_LIMIT             0x0000480E
-#define        VMCS_GUEST_GDTR_LIMIT           0x00004810
-#define        VMCS_GUEST_IDTR_LIMIT           0x00004812
-#define        VMCS_GUEST_ES_ACCESS_RIGHTS     0x00004814
-#define        VMCS_GUEST_CS_ACCESS_RIGHTS     0x00004816
-#define        VMCS_GUEST_SS_ACCESS_RIGHTS     0x00004818
-#define        VMCS_GUEST_DS_ACCESS_RIGHTS     0x0000481A
-#define        VMCS_GUEST_FS_ACCESS_RIGHTS     0x0000481C
-#define        VMCS_GUEST_GS_ACCESS_RIGHTS     0x0000481E
-#define        VMCS_GUEST_LDTR_ACCESS_RIGHTS   0x00004820
-#define        VMCS_GUEST_TR_ACCESS_RIGHTS     0x00004822
-#define        VMCS_GUEST_INTERRUPTIBILITY     0x00004824
-#define        VMCS_GUEST_ACTIVITY             0x00004826
-#define VMCS_GUEST_SMBASE              0x00004828
-#define        VMCS_GUEST_IA32_SYSENTER_CS     0x0000482A
-#define        VMCS_PREEMPTION_TIMER_VALUE     0x0000482E
-
-/* 32-bit host state fields */
-#define        VMCS_HOST_IA32_SYSENTER_CS      0x00004C00
-
-/* Natural Width control fields */
-#define        VMCS_CR0_MASK                   0x00006000
-#define        VMCS_CR4_MASK                   0x00006002
-#define        VMCS_CR0_SHADOW                 0x00006004
-#define        VMCS_CR4_SHADOW                 0x00006006
-#define        VMCS_CR3_TARGET0                0x00006008
-#define        VMCS_CR3_TARGET1                0x0000600A
-#define        VMCS_CR3_TARGET2                0x0000600C
-#define        VMCS_CR3_TARGET3                0x0000600E
-
-/* Natural Width read-only fields */
-#define        VMCS_EXIT_QUALIFICATION         0x00006400
-#define        VMCS_IO_RCX                     0x00006402
-#define        VMCS_IO_RSI                     0x00006404
-#define        VMCS_IO_RDI                     0x00006406
-#define        VMCS_IO_RIP                     0x00006408
-#define        VMCS_GUEST_LINEAR_ADDRESS       0x0000640A
-
-/* Natural Width guest-state fields */
-#define        VMCS_GUEST_CR0                  0x00006800
-#define        VMCS_GUEST_CR3                  0x00006802
-#define        VMCS_GUEST_CR4                  0x00006804
-#define        VMCS_GUEST_ES_BASE              0x00006806
-#define        VMCS_GUEST_CS_BASE              0x00006808
-#define        VMCS_GUEST_SS_BASE              0x0000680A
-#define        VMCS_GUEST_DS_BASE              0x0000680C
-#define        VMCS_GUEST_FS_BASE              0x0000680E
-#define        VMCS_GUEST_GS_BASE              0x00006810
-#define        VMCS_GUEST_LDTR_BASE            0x00006812
-#define        VMCS_GUEST_TR_BASE              0x00006814
-#define        VMCS_GUEST_GDTR_BASE            0x00006816
-#define        VMCS_GUEST_IDTR_BASE            0x00006818
-#define        VMCS_GUEST_DR7                  0x0000681A
-#define        VMCS_GUEST_RSP                  0x0000681C
-#define        VMCS_GUEST_RIP                  0x0000681E
-#define        VMCS_GUEST_RFLAGS               0x00006820
-#define        VMCS_GUEST_PENDING_DBG_EXCEPTIONS 0x00006822
-#define        VMCS_GUEST_IA32_SYSENTER_ESP    0x00006824
-#define        VMCS_GUEST_IA32_SYSENTER_EIP    0x00006826
-
-/* Natural Width host-state fields */
-#define        VMCS_HOST_CR0                   0x00006C00
-#define        VMCS_HOST_CR3                   0x00006C02
-#define        VMCS_HOST_CR4                   0x00006C04
-#define        VMCS_HOST_FS_BASE               0x00006C06
-#define        VMCS_HOST_GS_BASE               0x00006C08
-#define        VMCS_HOST_TR_BASE               0x00006C0A
-#define        VMCS_HOST_GDTR_BASE             0x00006C0C
-#define        VMCS_HOST_IDTR_BASE             0x00006C0E
-#define        VMCS_HOST_IA32_SYSENTER_ESP     0x00006C10
-#define        VMCS_HOST_IA32_SYSENTER_EIP     0x00006C12
-#define        VMCS_HOST_RSP                   0x00006C14
-#define        VMCS_HOST_RIP                   0x00006c16
-
-/*
- * VM instruction error numbers
- */
-#define        VMRESUME_WITH_NON_LAUNCHED_VMCS 5
-
-/*
- * VMCS exit reasons
- */
-#define EXIT_REASON_EXCEPTION          0
-#define EXIT_REASON_EXT_INTR           1
-#define EXIT_REASON_TRIPLE_FAULT       2
-#define EXIT_REASON_INIT               3
-#define EXIT_REASON_SIPI               4
-#define EXIT_REASON_IO_SMI             5
-#define EXIT_REASON_SMI                        6
-#define EXIT_REASON_INTR_WINDOW                7
-#define EXIT_REASON_NMI_WINDOW         8
-#define EXIT_REASON_TASK_SWITCH                9
-#define EXIT_REASON_CPUID              10
-#define EXIT_REASON_GETSEC             11
-#define EXIT_REASON_HLT                        12
-#define EXIT_REASON_INVD               13
-#define EXIT_REASON_INVLPG             14
-#define EXIT_REASON_RDPMC              15
-#define EXIT_REASON_RDTSC              16
-#define EXIT_REASON_RSM                        17
-#define EXIT_REASON_VMCALL             18
-#define EXIT_REASON_VMCLEAR            19
-#define EXIT_REASON_VMLAUNCH           20
-#define EXIT_REASON_VMPTRLD            21
-#define EXIT_REASON_VMPTRST            22
-#define EXIT_REASON_VMREAD             23
-#define EXIT_REASON_VMRESUME           24
-#define EXIT_REASON_VMWRITE            25
-#define EXIT_REASON_VMXOFF             26
-#define EXIT_REASON_VMXON              27
-#define EXIT_REASON_CR_ACCESS          28
-#define EXIT_REASON_DR_ACCESS          29
-#define EXIT_REASON_INOUT              30
-#define EXIT_REASON_RDMSR              31
-#define EXIT_REASON_WRMSR              32
-#define EXIT_REASON_INVAL_VMCS         33
-#define EXIT_REASON_INVAL_MSR          34
-#define EXIT_REASON_MWAIT              36
-#define EXIT_REASON_MTF                        37
-#define EXIT_REASON_MONITOR            39
-#define EXIT_REASON_PAUSE              40
-#define EXIT_REASON_MCE_DURING_ENTRY   41
-#define EXIT_REASON_TPR                        43
-#define EXIT_REASON_APIC_ACCESS                44
-#define        EXIT_REASON_VIRTUALIZED_EOI     45
-#define EXIT_REASON_GDTR_IDTR          46
-#define EXIT_REASON_LDTR_TR            47
-#define EXIT_REASON_EPT_FAULT          48
-#define EXIT_REASON_EPT_MISCONFIG      49
-#define EXIT_REASON_INVEPT             50
-#define EXIT_REASON_RDTSCP             51
-#define EXIT_REASON_VMX_PREEMPT                52
-#define EXIT_REASON_INVVPID            53
-#define EXIT_REASON_WBINVD             54
-#define EXIT_REASON_XSETBV             55
-#define        EXIT_REASON_APIC_WRITE          56
-
-/*
- * NMI unblocking due to IRET.
- *
- * Applies to VM-exits due to hardware exception or EPT fault.
- */
-#define        EXIT_QUAL_NMIUDTI       (1 << 12)
-/*
- * VMCS interrupt information fields
- */
-#define        VMCS_INTR_VALID         (1U << 31)
-#define        VMCS_INTR_T_MASK        0x700   /* Interruption-info type */
-#define        VMCS_INTR_T_HWINTR      (0 << 8)
-#define        VMCS_INTR_T_NMI         (2 << 8)
-#define        VMCS_INTR_T_HWEXCEPTION (3 << 8)
-#define        VMCS_INTR_T_SWINTR      (4 << 8)
-#define        VMCS_INTR_T_PRIV_SWEXCEPTION (5 << 8)
-#define        VMCS_INTR_T_SWEXCEPTION (6 << 8)
-#define        VMCS_INTR_DEL_ERRCODE   (1 << 11)
-
-/*
- * VMCS IDT-Vectoring information fields
- */
-#define        VMCS_IDT_VEC_VALID              (1U << 31)
-#define        VMCS_IDT_VEC_ERRCODE_VALID      (1 << 11)
-
-/*
- * VMCS Guest interruptibility field
- */
-#define        VMCS_INTERRUPTIBILITY_STI_BLOCKING      (1 << 0)
-#define        VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING    (1 << 1)
-#define        VMCS_INTERRUPTIBILITY_SMI_BLOCKING      (1 << 2)
-#define        VMCS_INTERRUPTIBILITY_NMI_BLOCKING      (1 << 3)
-
-/*
- * Exit qualification for EXIT_REASON_INVAL_VMCS
- */
-#define        EXIT_QUAL_NMI_WHILE_STI_BLOCKING        3
-
-/*
- * Exit qualification for EPT violation
- */
-#define        EPT_VIOLATION_DATA_READ         (1UL << 0)
-#define        EPT_VIOLATION_DATA_WRITE        (1UL << 1)
-#define        EPT_VIOLATION_INST_FETCH        (1UL << 2)
-#define        EPT_VIOLATION_GPA_READABLE      (1UL << 3)
-#define        EPT_VIOLATION_GPA_WRITEABLE     (1UL << 4)
-#define        EPT_VIOLATION_GPA_EXECUTABLE    (1UL << 5)
-#define        EPT_VIOLATION_GLA_VALID         (1UL << 7)
-#define        EPT_VIOLATION_XLAT_VALID        (1UL << 8)
-
-/*
- * Exit qualification for APIC-access VM exit
- */
-#define        APIC_ACCESS_OFFSET(qual)        ((qual) & 0xFFF)
-#define        APIC_ACCESS_TYPE(qual)          (((qual) >> 12) & 0xF)
-
-/*
- * Exit qualification for APIC-write VM exit
- */
-#define        APIC_WRITE_OFFSET(qual)         ((qual) & 0xFFF)
-
-#endif
diff --git a/kern/arch/x86/vmm/intel/vmx_cpufunc.h b/kern/arch/x86/vmm/intel/vmx_cpufunc.h
deleted file mode 100644 (file)
index eafb7b3..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/*-
- * Copyright (c) 2011 NetApp, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef        _VMX_CPUFUNC_H_
-#define        _VMX_CPUFUNC_H_
-
-struct vmcs;
-
-/*
- * Section 5.2 "Conventions" from Intel Architecture Manual 2B.
- *
- *                     error
- * VMsucceed             0
- * VMFailInvalid         1
- * VMFailValid           2     see also VMCS VM-Instruction Error Field
- */
-#define        VM_SUCCESS              0
-#define        VM_FAIL_INVALID         1
-#define        VM_FAIL_VALID           2
-#define        VMX_SET_ERROR_CODE \
-       "       jnc 1f;"                                                \
-       "       mov $1, %[error];"      /* CF: error = 1 */             \
-       "       jmp 3f;"                                                \
-       "1:     jnz 2f;"                                                \
-       "       mov $2, %[error];"      /* ZF: error = 2 */             \
-       "       jmp 3f;"                                                \
-       "2:     mov $0, %[error];"                                      \
-       "3:"
-
-/* returns 0 on success and non-zero on failure */
-static __inline int vmxon(char *region)
-{
-       int error;
-       uint64_t addr;
-
-       addr = PADDR(region);
-       __asm __volatile("vmxon %[addr];" VMX_SET_ERROR_CODE:[error] "=r"(error)
-                                        :[addr] "m"(*(uint64_t *) & addr)
-                                        :"memory");
-
-       return (error);
-}
-
-/* returns 0 on success and non-zero on failure */
-static __inline int vmclear(struct vmcs *vmcs)
-{
-       int error;
-       uint64_t addr;
-
-       addr = PADDR(vmcs);
-       __asm __volatile("vmclear %[addr];" VMX_SET_ERROR_CODE:[error] "=r"(error)
-                                        :[addr] "m"(*(uint64_t *) & addr)
-                                        :"memory");
-       return (error);
-}
-
-static __inline void vmxoff(void)
-{
-
-       __asm __volatile("vmxoff");
-}
-
-static __inline void vmptrst(uint64_t * addr)
-{
-
-       __asm __volatile("vmptrst %[addr]"::[addr] "m"(*addr):"memory");
-}
-
-static __inline int vmptrld(struct vmcs *vmcs)
-{
-       int error;
-       uint64_t addr;
-
-       addr = PADDR(vmcs);
-       __asm __volatile("vmptrld %[addr];" VMX_SET_ERROR_CODE:[error] "=r"(error)
-                                        :[addr] "m"(*(uint64_t *) & addr)
-                                        :"memory");
-       return (error);
-}
-
-static __inline int vmwrite(uint64_t reg, uint64_t val)
-{
-       int error;
-
-       __asm __volatile("vmwrite %[val], %[reg];"
-                                        VMX_SET_ERROR_CODE:[error] "=r"(error)
-                                        :[val] "r"(val),[reg] "r"(reg)
-                                        :"memory");
-
-       return (error);
-}
-
-static __inline int vmread(uint64_t r, uint64_t * addr)
-{
-       int error;
-
-       __asm __volatile("vmread %[r], %[addr];"
-                                        VMX_SET_ERROR_CODE:[error] "=r"(error)
-                                        :[r] "r"(r),[addr] "m"(*addr)
-                                        :"memory");
-
-       return (error);
-}
-
-static void __inline VMCLEAR(int8_t *irq, struct vmcs *vmcs)
-{
-       int err;
-
-       err = vmclear(vmcs);
-       if (err != 0)
-               panic("%s: vmclear(%p) error %d", __func__, vmcs, err);
-
-       enable_irqsave(irq);
-}
-
-static void __inline VMPTRLD(int8_t *irq, struct vmcs *vmcs)
-{
-       int err;
-
-       disable_irqsave(irq);
-
-       err = vmptrld(vmcs);
-       if (err != 0)
-               panic("%s: vmptrld(%p) error %d", __func__, vmcs, err);
-}
-
-#define        INVVPID_TYPE_ADDRESS            0UL
-#define        INVVPID_TYPE_SINGLE_CONTEXT     1UL
-#define        INVVPID_TYPE_ALL_CONTEXTS       2UL
-
-struct invvpid_desc {
-       uint16_t vpid;
-       uint16_t _res1;
-       uint32_t _res2;
-       uint64_t linear_addr;
-};
-
-static void __inline invvpid(uint64_t type, struct invvpid_desc desc)
-{
-       int error;
-       static_assert(sizeof(struct invvpid_desc) == 16);
-
-       __asm __volatile("invvpid %[desc], %[type];"
-                                        VMX_SET_ERROR_CODE:[error] "=r"(error)
-                                        :[desc] "m"(desc),[type] "r"(type)
-                                        :"memory");
-
-       if (error)
-               panic("invvpid error %d", error);
-}
-
-#define        INVEPT_TYPE_SINGLE_CONTEXT      1UL
-#define        INVEPT_TYPE_ALL_CONTEXTS        2UL
-struct invept_desc {
-       uint64_t eptp;
-       uint64_t _res;
-};
-static void __inline invept(uint64_t type, struct invept_desc desc)
-{
-       int error;
-       static_assert(sizeof(struct invept_desc) == 16);
-
-       __asm __volatile("invept %[desc], %[type];"
-                                        VMX_SET_ERROR_CODE:[error] "=r"(error)
-                                        :[desc] "m"(desc),[type] "r"(type)
-                                        :"memory");
-
-       if (error)
-               panic("invept error %d", error);
-}
-#endif
diff --git a/kern/arch/x86/vmm/x86.h b/kern/arch/x86/vmm/x86.h
deleted file mode 100644 (file)
index 6a8bf56..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*-
- * Copyright (c) 2011 NetApp, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _X86_H_
-#define        _X86_H_
-
-#define CPUID_0000_0000 (0x0)
-#define CPUID_0000_0001        (0x1)
-#define CPUID_0000_0002 (0x2)
-#define CPUID_0000_0003 (0x3)
-#define CPUID_0000_0004 (0x4)
-#define CPUID_0000_0006 (0x6)
-#define CPUID_0000_0007 (0x7)
-#define        CPUID_0000_000A (0xA)
-#define        CPUID_0000_000B (0xB)
-#define        CPUID_0000_000D (0xD)
-#define CPUID_8000_0000        (0x80000000)
-#define CPUID_8000_0001        (0x80000001)
-#define CPUID_8000_0002        (0x80000002)
-#define CPUID_8000_0003        (0x80000003)
-#define CPUID_8000_0004        (0x80000004)
-#define CPUID_8000_0006        (0x80000006)
-#define CPUID_8000_0007        (0x80000007)
-#define CPUID_8000_0008        (0x80000008)
-
-/*
- * CPUID instruction Fn0000_0001:
- */
-#define CPUID_0000_0001_APICID_MASK                    (0xff<<24)
-#define CPUID_0000_0001_APICID_SHIFT                   24
-
-/*
- * CPUID instruction Fn0000_0001 ECX
- */
-#define CPUID_0000_0001_FEAT0_VMX      (1<<5)
-
-int x86_emulate_cpuid(struct vm *vm, int vcpu_id, uint32_t * eax,
-                                         uint32_t * ebx, uint32_t * ecx, uint32_t * edx);
-
-#endif
diff --git a/kern/arch/x86/vmx.c b/kern/arch/x86/vmx.c
deleted file mode 100644 (file)
index 93a1527..0000000
+++ /dev/null
@@ -1,3838 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2006 Qumranet, Inc.
- *
- * Authors:
- *   Avi Kivity   <avi@qumranet.com>
- *   Yaniv Kamay  <yaniv@qumranet.com>
- *
- */
-
-#define DEBUG
-#define LITEVM_DEBUG
-
-#include <kmalloc.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <error.h>
-#include <pmap.h>
-#include <sys/queue.h>
-#include <smp.h>
-#include <kref.h>
-#include <atomic.h>
-#include <alarm.h>
-#include <event.h>
-#include <umem.h>
-#include <devalarm.h>
-#include <arch/types.h>
-#include <arch/vm.h>
-#include <arch/emulate.h>
-#include <arch/vmdebug.h>
-#include <arch/msr-index.h>
-
-void monitor(void *);
-
-#define currentcpu (&per_cpu_info[core_id()])
-#define QLOCK_init(x) {printd("qlock_init %p\n", x); qlock_init(x); printd("%p lock_inited\n", x);}
-#define QLOCK(x) {printd("qlock %p\n", x); qlock(x); printd("%p locked\n", x);}
-#define QUNLOCK(x) {printd("qunlock %p\n", x); qunlock(x); printd("%p unlocked\n", x);}
-#define SPLI_irqsave(x){printd("spin_lock_init %p:", x); spinlock_init(x); printd("inited\n");}
-#define SPLL(x){printd("spin_lock %p\n", x); spin_lock_irqsave(x); printd("%p locked\n", x);}
-#define SPLU(x){printd("spin_unlock %p\n", x); spin_unlock(x); printd("%p unlocked\n", x);}
-struct litevm_stat litevm_stat;
-
-static struct litevm_stats_debugfs_item {
-       const char *name;
-       uint32_t *data;
-} debugfs_entries[] = {
-       {
-       "pf_fixed", &litevm_stat.pf_fixed}, {
-       "pf_guest", &litevm_stat.pf_guest}, {
-       "tlb_flush", &litevm_stat.tlb_flush}, {
-       "invlpg", &litevm_stat.invlpg}, {
-       "exits", &litevm_stat.exits}, {
-       "io_exits", &litevm_stat.io_exits}, {
-       "mmio_exits", &litevm_stat.mmio_exits}, {
-       "signal_exits", &litevm_stat.signal_exits}, {
-       "irq_exits", &litevm_stat.irq_exits}, {
-       0, 0}
-};
-
-static struct dentry *debugfs_dir;
-
-static const uint32_t vmx_msr_index[] = {
-#ifdef __x86_64__
-       MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR, MSR_KERNEL_GS_BASE,
-#endif
-       MSR_EFER,       // wtf? MSR_K6_STAR,
-};
-
-static const char* vmx_msr_name[] = {
-#ifdef __x86_64__
-       "MSR_SYSCALL_MASK", "MSR_LSTAR", "MSR_CSTAR", "MSR_KERNEL_GS_BASE",
-#endif
-       "MSR_EFER",     // wtf? MSR_K6_STAR,
-};
-
-#define NR_VMX_MSR (sizeof(vmx_msr_index) / sizeof(*vmx_msr_index))
-
-#ifdef __x86_64__
-/*
- * avoid save/load MSR_SYSCALL_MASK and MSR_LSTAR by std vt
- * mechanism (cpu bug AA24)
- */
-#define NR_BAD_MSRS 2
-#else
-#define NR_BAD_MSRS 0
-#endif
-
-#define TSS_IOPB_BASE_OFFSET 0x66
-#define TSS_BASE_SIZE 0x68
-#define TSS_IOPB_SIZE (65536 / 8)
-#define TSS_REDIRECTION_SIZE (256 / 8)
-#define RMODE_TSS_SIZE (TSS_BASE_SIZE + TSS_REDIRECTION_SIZE + TSS_IOPB_SIZE + 1)
-
-#define MSR_IA32_VMX_BASIC_MSR                 0x480
-#define MSR_IA32_VMX_PINBASED_CTLS_MSR         0x481
-#define MSR_IA32_VMX_PROCBASED_CTLS_MSR                0x482
-#define MSR_IA32_VMX_EXIT_CTLS_MSR             0x483
-#define MSR_IA32_VMX_ENTRY_CTLS_MSR            0x484
-
-#define CR0_RESEVED_BITS 0xffffffff1ffaffc0ULL
-#define LMSW_GUEST_MASK 0x0eULL
-#define CR4_RESEVED_BITS (~((1ULL << 11) - 1))
-//#define CR4_VMXE 0x2000
-#define CR8_RESEVED_BITS (~0x0fULL)
-#define EFER_RESERVED_BITS 0xfffffffffffff2fe
-
-#ifdef __x86_64__
-#define HOST_IS_64 1
-#else
-#define HOST_IS_64 0
-#endif
-
-int vm_set_memory_region(struct litevm *litevm,
-                                                struct litevm_memory_region *mem);
-
-/* bit ops not yet widely used in akaros and we're not sure where to put them. */
-/**
- * __ffs - find first set bit in word
- * @word: The word to search
- *
- * Undefined if no bit exists, so code should check against 0 first.
- */
-static inline unsigned long __ffs(unsigned long word)
-{
-       print_func_entry();
-asm("rep; bsf %1,%0":"=r"(word)
-:              "rm"(word));
-       print_func_exit();
-       return word;
-}
-
-static struct vmx_msr_entry *find_msr_entry(struct litevm_vcpu *vcpu,
-                                                                                       uint32_t msr)
-{
-       print_func_entry();
-       int i;
-
-       for (i = 0; i < vcpu->nmsrs; ++i)
-               if (vcpu->guest_msrs[i].index == msr) {
-                       print_func_exit();
-                       return &vcpu->guest_msrs[i];
-               }
-       print_func_exit();
-       return 0;
-}
-
-struct descriptor_table {
-       uint16_t limit;
-       unsigned long base;
-} __attribute__ ((packed));
-
-static void get_gdt(struct descriptor_table *table)
-{
-       print_func_entry();
-asm("sgdt %0":"=m"(*table));
-       print_func_exit();
-}
-
-static void get_idt(struct descriptor_table *table)
-{
-       print_func_entry();
-asm("sidt %0":"=m"(*table));
-       print_func_exit();
-}
-
-static uint16_t read_fs(void)
-{
-       //print_func_entry();
-       uint16_t seg;
-       asm("mov %%fs, %0":"=g"(seg));
-       //print_func_exit();
-       return seg;
-}
-
-static uint16_t read_gs(void)
-{
-       //print_func_entry();
-       uint16_t seg;
-       asm("mov %%gs, %0":"=g"(seg));
-       //print_func_exit();
-       return seg;
-}
-
-static uint16_t read_ldt(void)
-{
-       //print_func_entry();
-       uint16_t ldt;
-       asm("sldt %0":"=g"(ldt));
-       //print_func_exit();
-       return ldt;
-}
-
-static void load_fs(uint16_t sel)
-{
-       //print_func_entry();
-       asm("mov %0, %%fs": :"g"(sel));
-       //print_func_exit();
-}
-
-static void load_gs(uint16_t sel)
-{
-       //print_func_entry();
-       asm("mov %0, %%gs": :"g"(sel));
-       //print_func_exit();
-}
-
-#ifndef load_ldt
-static void load_ldt(uint16_t sel)
-{
-       //print_func_entry();
-       asm("lldt %0": :"g"(sel));
-       //print_func_exit();
-}
-#endif
-
-static void fx_save(void *image)
-{
-       //print_func_entry();
-       asm("fxsave (%0)"::"r"(image));
-       //print_func_exit();
-}
-
-static void fx_restore(void *image)
-{
-       //print_func_entry();
-       asm("fxrstor (%0)"::"r"(image));
-       //print_func_exit();
-}
-
-static void fpu_init(void)
-{
-       print_func_entry();
-       asm("finit");
-       print_func_exit();
-}
-
-struct segment_descriptor {
-       uint16_t limit_low;
-       uint16_t base_low;
-       uint8_t base_mid;
-       uint8_t type:4;
-       uint8_t system:1;
-       uint8_t dpl:2;
-       uint8_t present:1;
-       uint8_t limit_high:4;
-       uint8_t avl:1;
-       uint8_t long_mode:1;
-       uint8_t default_op:1;
-       uint8_t granularity:1;
-       uint8_t base_high;
-} __attribute__ ((packed));
-
-#ifdef __x86_64__
-// LDT or TSS descriptor in the GDT. 16 bytes.
-struct segment_descriptor_64 {
-       struct segment_descriptor s;
-       uint32_t base_higher;
-       uint32_t pad_zero;
-};
-
-#endif
-
-static unsigned long segment_base(uint16_t selector)
-{
-       print_func_entry();
-       struct descriptor_table gdt;
-       struct segment_descriptor *d;
-       unsigned long table_base;
-       typedef unsigned long ul;
-       unsigned long v;
-
-asm("sgdt %0":"=m"(gdt));
-       table_base = gdt.base;
-
-       if (selector & 4) {     /* from ldt */
-               uint16_t ldt_selector;
-
-asm("sldt %0":"=g"(ldt_selector));
-               table_base = segment_base(ldt_selector);
-       }
-       d = (struct segment_descriptor *)(table_base + (selector & ~7));
-       v = d->base_low | ((ul) d->base_mid << 16) | ((ul) d->base_high << 24);
-#ifdef __x86_64__
-       if (d->system == 0 && (d->type == 2 || d->type == 9 || d->type == 11))
-               v |= ((ul) ((struct segment_descriptor_64 *)d)->base_higher) << 32;
-#endif
-       print_func_exit();
-       return v;
-}
-
-static unsigned long read_tr_base(void)
-{
-       print_func_entry();
-       uint16_t tr;
-asm("str %0":"=g"(tr));
-       print_func_exit();
-       return segment_base(tr);
-}
-
-static void reload_tss(void)
-{
-       print_func_entry();
-#ifndef __x86_64__
-
-       /*
-        * VT restores TR but not its size.  Useless.
-        */
-       struct descriptor_table gdt;
-       struct segment_descriptor *descs;
-
-       get_gdt(&gdt);
-       descs = (void *)gdt.base;
-       descs[GD_TSS].type = 9; /* available TSS */
-       load_TR_desc();
-#endif
-       print_func_exit();
-}
-
-static struct vmcs_descriptor {
-       int size;
-       int order;
-       uint32_t revision_id;
-} vmcs_descriptor;
-
-static inline struct page *_gfn_to_page(struct litevm *litevm, gfn_t gfn)
-{
-       print_func_entry();
-       struct litevm_memory_slot *slot = gfn_to_memslot(litevm, gfn);
-       print_func_exit();
-       return (slot) ? slot->phys_mem[gfn - slot->base_gfn] : 0;
-}
-
-int litevm_read_guest(struct litevm_vcpu *vcpu,
-                                         gva_t addr, unsigned long size, void *dest)
-{
-       print_func_entry();
-       unsigned char *host_buf = dest;
-       unsigned long req_size = size;
-
-       while (size) {
-               hpa_t paddr;
-               unsigned now;
-               unsigned offset;
-               hva_t guest_buf;
-
-               paddr = gva_to_hpa(vcpu, addr);
-
-               if (is_error_hpa(paddr))
-                       break;
-               guest_buf = (hva_t) KADDR(paddr);
-               offset = addr & ~PAGE_MASK;
-               guest_buf |= offset;
-               now = MIN(size, PAGE_SIZE - offset);
-               memcpy(host_buf, (void *)guest_buf, now);
-               host_buf += now;
-               addr += now;
-               size -= now;
-       }
-       print_func_exit();
-       return req_size - size;
-}
-
-int litevm_write_guest(struct litevm_vcpu *vcpu,
-                                          gva_t addr, unsigned long size, void *data)
-{
-       print_func_entry();
-       unsigned char *host_buf = data;
-       unsigned long req_size = size;
-
-       while (size) {
-               hpa_t paddr;
-               unsigned now;
-               unsigned offset;
-               hva_t guest_buf;
-
-               paddr = gva_to_hpa(vcpu, addr);
-
-               if (is_error_hpa(paddr))
-                       break;
-
-               guest_buf = (hva_t) KADDR(paddr);
-               offset = addr & ~PAGE_MASK;
-               guest_buf |= offset;
-               now = MIN(size, PAGE_SIZE - offset);
-               memcpy((void *)guest_buf, host_buf, now);
-               host_buf += now;
-               addr += now;
-               size -= now;
-       }
-       print_func_exit();
-       return req_size - size;
-}
-
-static void setup_vmcs_descriptor(void)
-{
-       print_func_entry();
-       uint64_t msr;
-
-       msr = read_msr(MSR_IA32_VMX_BASIC_MSR);
-       vmcs_descriptor.size = (msr >> 32) & 0x1fff;
-       vmcs_descriptor.order = LOG2_UP(vmcs_descriptor.size >> PAGE_SHIFT);
-       vmcs_descriptor.revision_id = (uint32_t) msr;
-       printk("setup_vmcs_descriptor: msr 0x%x, size 0x%x order 0x%x id 0x%x\n",
-                  msr, vmcs_descriptor.size, vmcs_descriptor.order,
-                  vmcs_descriptor.revision_id);
-       print_func_exit();
-};
-
-static void vmcs_clear(struct vmcs *vmcs)
-{
-       print_func_entry();
-       uint64_t phys_addr = PADDR(vmcs);
-       uint8_t error;
-       printk("%d: vmcs %p phys_addr %p\n", core_id(), vmcs, (void *)phys_addr);
-       asm volatile ("vmclear %1; setna %0":"=m" (error):"m"(phys_addr):"cc",
-                                 "memory");
-       if (error)
-               printk("litevm: vmclear fail: %p/%llx\n", vmcs, phys_addr);
-       print_func_exit();
-}
-
-static void __vcpu_clear(struct hw_trapframe *hw_tf, void *arg)
-{
-       print_func_entry();
-       struct litevm_vcpu *vcpu = arg;
-       int cpu = core_id();
-       printd
-               ("__vcpu_clear: cpu %d vcpu->cpu %d currentcpu->vmcs %p vcpu->vmcs %p\n",
-                cpu, vcpu->cpu, currentcpu->vmcs, vcpu->vmcs);
-
-       if (vcpu->cpu == cpu)
-               vmcs_clear(vcpu->vmcs);
-
-       if (currentcpu->vmcs == vcpu->vmcs)
-               currentcpu->vmcs = NULL;
-       print_func_exit();
-}
-
-static int vcpu_slot(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       print_func_exit();
-       return vcpu - vcpu->litevm->vcpus;
-}
-
-/*
- * Switches to specified vcpu, until a matching vcpu_put(), but assumes
- * vcpu mutex is already taken.
- */
-static struct litevm_vcpu *__vcpu_load(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       uint64_t phys_addr = PADDR(vcpu->vmcs);
-       int cpu;
-       cpu = core_id();
-
-       printk("__vcpu_load: vcpu->cpu %d cpu %d\n", vcpu->cpu, cpu);
-       if ((vcpu->cpu != cpu) && (vcpu->cpu != -1)){
-               handler_wrapper_t *w;
-               smp_call_function_single(vcpu->cpu, __vcpu_clear, vcpu, &w);
-               smp_call_wait(w);
-               vcpu->launched = 0;
-       }
-
-       printk("2 ..");
-       if (currentcpu->vmcs != vcpu->vmcs) {
-               uint8_t error;
-
-               currentcpu->vmcs = vcpu->vmcs;
-               asm volatile ("vmptrld %1; setna %0":"=m" (error):"m"(phys_addr):"cc");
-               if (error) {
-                       printk("litevm: vmptrld %p/%llx fail\n", vcpu->vmcs, phys_addr);
-                       error("litevm: vmptrld %p/%llx fail\n", vcpu->vmcs, phys_addr);
-               }
-       }
-
-       printk("3 ..");
-       if (vcpu->cpu != cpu) {
-               struct descriptor_table dt;
-               unsigned long sysenter_esp;
-
-               vcpu->cpu = cpu;
-               /*
-                * Linux uses per-cpu TSS and GDT, so set these when switching
-                * processors.
-                */
-               vmcs_writel(HOST_TR_BASE, read_tr_base());      /* 22.2.4 */
-               get_gdt(&dt);
-               vmcs_writel(HOST_GDTR_BASE, dt.base);   /* 22.2.4 */
-
-               sysenter_esp = read_msr(MSR_IA32_SYSENTER_ESP);
-               vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp);      /* 22.2.3 */
-       }
-       print_func_exit();
-       return vcpu;
-}
-
-/*
- * Switches to specified vcpu, until a matching vcpu_put()
- * And leaves it locked!
- */
-static struct litevm_vcpu *vcpu_load(struct litevm *litevm, int vcpu_slot)
-{
-       struct litevm_vcpu *ret;
-       print_func_entry();
-       struct litevm_vcpu *vcpu = &litevm->vcpus[vcpu_slot];
-
-       printk("vcpu_slot %d vcpu %p\n", vcpu_slot, vcpu);
-
-       QLOCK(&vcpu->mutex);
-       printk("Locked\n");
-       if (!vcpu->vmcs) {
-               QUNLOCK(&vcpu->mutex);
-               printk("vcpu->vmcs for vcpu %p is NULL", vcpu);
-               error("vcpu->vmcs is NULL");
-       }
-       ret = __vcpu_load(vcpu);
-       print_func_exit();
-       return ret;
-}
-
-static void vcpu_put(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       //put_cpu();
-       QUNLOCK(&vcpu->mutex);
-       print_func_exit();
-}
-
-static struct vmcs *alloc_vmcs_cpu(int cpu)
-{
-       print_func_entry();
-       int node = node_id();
-       struct vmcs *vmcs;
-
-       vmcs = get_cont_pages_node(node, vmcs_descriptor.order, KMALLOC_WAIT);
-       if (!vmcs) {
-               print_func_exit();
-               printk("no memory for vcpus");
-               error("no memory for vcpus");
-       }
-       memset(vmcs, 0, vmcs_descriptor.size);
-       vmcs->revision_id = vmcs_descriptor.revision_id;        /* vmcs revision id */
-       print_func_exit();
-       return vmcs;
-}
-
-static struct vmcs *alloc_vmcs(void)
-{
-       struct vmcs *ret;
-       print_func_entry();
-       ret = alloc_vmcs_cpu(core_id());
-       print_func_exit();
-       return ret;
-}
-
-static int cpu_has_litevm_support(void)
-{
-       int ret;
-       print_func_entry();
-       /* sigh ... qemu. */
-       char vid[16];
-       if (vendor_id(vid) < 0)
-               return 0;
-       printk("vendor id is %s\n", vid);
-       if (vid[0] == 'Q') /* qemu */
-               return 0;
-       if (vid[0] == 'A') /* AMD or qemu claiming to be AMD */
-               return 0;
-       uint32_t ecx = cpuid_ecx(1);
-       ret = ecx & (1 << 5);   /* CPUID.1:ECX.VMX[bit 5] -> VT */
-       printk("%s: CPUID.1:ECX.VMX[bit 5] -> VT is%s available\n", __func__, ret ? "" : " NOT");
-       print_func_exit();
-       return ret;
-}
-
-static int vmx_disabled_by_bios(void)
-{
-       print_func_entry();
-       uint64_t msr;
-
-       msr = read_msr(MSR_IA32_FEATURE_CONTROL);
-       print_func_exit();
-       return (msr & 5) == 1;  /* locked but not enabled */
-}
-
-static void vm_enable(struct hw_trapframe *hw_tf, void *garbage)
-{
-       print_func_entry();
-       int cpu = hw_core_id();
-       uint64_t phys_addr;
-       uint64_t old;
-       uint64_t status = 0;
-       currentcpu->vmxarea = get_cont_pages_node(core_id(), vmcs_descriptor.order,
-                                                                                         KMALLOC_WAIT);
-       if (!currentcpu->vmxarea)
-               return;
-       memset(currentcpu->vmxarea, 0, vmcs_descriptor.size);
-       currentcpu->vmxarea->revision_id = vmcs_descriptor.revision_id;
-       phys_addr = PADDR(currentcpu->vmxarea);
-       printk("%d: currentcpu->vmxarea %p phys_addr %p\n", core_id(),
-                  currentcpu->vmxarea, (void *)phys_addr);
-       if (phys_addr & 0xfff) {
-               printk("fix vmxarea alignment!");
-       }
-       printk("%d: CR4 is 0x%x, and VMXE is %x\n", core_id(), rcr4(), CR4_VMXE);
-       old = read_msr(MSR_IA32_FEATURE_CONTROL);
-       printk("%d: vm_enable, old is %d\n", core_id(), old);
-       if ((old & 5) == 0) {
-               /* enable and lock */
-               write_msr(MSR_IA32_FEATURE_CONTROL, old | 5);
-               old = read_msr(MSR_IA32_FEATURE_CONTROL);
-               printk("%d:vm_enable, tried to set 5, old is %d\n", core_id(), old);
-       }
-       printk("%d:CR4 is 0x%x, and VMXE is %x\n", core_id(), rcr4(), CR4_VMXE);
-       lcr4(rcr4() | CR4_VMXE);        /* FIXME: not cpu hotplug safe */
-       printk("%d:CR4 is 0x%x, and VMXE is %x\n", core_id(), rcr4(), CR4_VMXE);
-       printk("%d:cr0 is %x\n", core_id(), rcr0());
-       lcr0(rcr0() | 0x20);
-       printk("%d:cr0 is %x\n", core_id(), rcr0());
-       printk("%d:A20 is %d (0x2 should be set)\n", core_id(), inb(0x92));
-       outb(0x92, inb(0x92) | 2);
-       printk("%d:A20 is %d (0x2 should be set)\n", core_id(), inb(0x92));
-       asm volatile ("vmxon %1\njbe 1f\nmovl $1, %0\n1:":"=m" (status):"m"
-                                 (phys_addr):"memory", "cc");
-       printk("%d:vmxon status is %d\n", core_id(), status);
-       printk("%d:CR4 is 0x%x, and VMXE is %x\n", core_id(), rcr4(), CR4_VMXE);
-       if (!status) {
-               printk("%d:vm_enable: status says fail\n", core_id());
-       }
-       print_func_exit();
-}
-
-static void litevm_disable(void *garbage)
-{
-       print_func_entry();
-       asm volatile ("vmxoff":::"cc");
-       print_func_exit();
-}
-
-struct litevm *vmx_open(void)
-{
-       print_func_entry();
-       struct litevm *litevm = kzmalloc(sizeof(struct litevm), KMALLOC_WAIT);
-       int i;
-
-       printk("vmx_open: litevm is %p\n", litevm);
-       if (!litevm) {
-               printk("NO LITEVM! MAKES NO SENSE!\n");
-               error("litevm alloc failed");
-               print_func_exit();
-               return 0;
-       }
-
-       SPLI_irqsave(&litevm->lock);
-       LIST_INIT(&litevm->link);
-       for (i = 0; i < LITEVM_MAX_VCPUS; ++i) {
-               struct litevm_vcpu *vcpu = &litevm->vcpus[i];
-               printk("init vcpu %p\n", vcpu);
-
-               QLOCK_init(&vcpu->mutex);
-               vcpu->mmu.root_hpa = INVALID_PAGE;
-               vcpu->litevm = litevm;
-               LIST_INIT(&vcpu->link);
-       }
-       printk("vmx_open: busy %d\n", litevm->busy);
-       printk("return %p\n", litevm);
-       print_func_exit();
-       return litevm;
-}
-
-/*
- * Free any memory in @free but not in @dont.
- */
-static void litevm_free_physmem_slot(struct litevm_memory_slot *free,
-                                                                        struct litevm_memory_slot *dont)
-{
-       print_func_entry();
-       int i;
-
-       if (!dont || free->phys_mem != dont->phys_mem)
-               if (free->phys_mem) {
-                       for (i = 0; i < free->npages; ++i) {
-                               page_t *page = free->phys_mem[i];
-                               page_decref(page);
-                               assert(page_is_free(page2ppn(page)));
-                       }
-                       kfree(free->phys_mem);
-               }
-
-       if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
-               kfree(free->dirty_bitmap);
-
-       free->phys_mem = 0;
-       free->npages = 0;
-       free->dirty_bitmap = 0;
-       print_func_exit();
-}
-
-static void litevm_free_physmem(struct litevm *litevm)
-{
-       print_func_entry();
-       int i;
-
-       for (i = 0; i < litevm->nmemslots; ++i)
-               litevm_free_physmem_slot(&litevm->memslots[i], 0);
-       print_func_exit();
-}
-
-static void litevm_free_vmcs(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       if (vcpu->vmcs) {
-               handler_wrapper_t *w;
-               smp_call_function_all(__vcpu_clear, vcpu, &w);
-               smp_call_wait(w);
-               //free_vmcs(vcpu->vmcs);
-               vcpu->vmcs = 0;
-       }
-       print_func_exit();
-}
-
-static void litevm_free_vcpu(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       litevm_free_vmcs(vcpu);
-       litevm_mmu_destroy(vcpu);
-       print_func_exit();
-}
-
-static void litevm_free_vcpus(struct litevm *litevm)
-{
-       print_func_entry();
-       unsigned int i;
-
-       for (i = 0; i < LITEVM_MAX_VCPUS; ++i)
-               litevm_free_vcpu(&litevm->vcpus[i]);
-       print_func_exit();
-}
-
-static int litevm_dev_release(struct litevm *litevm)
-{
-       print_func_entry();
-
-       litevm_free_vcpus(litevm);
-       litevm_free_physmem(litevm);
-       kfree(litevm);
-       print_func_exit();
-       return 0;
-}
-
-unsigned long vmcs_readl(unsigned long field)
-{
-       unsigned long value;
-
-       asm volatile ("vmread %1, %0":"=g" (value):"r"(field):"cc");
-       return value;
-}
-
-void vmcs_writel(unsigned long field, unsigned long value)
-{
-       uint8_t error;
-
-       asm volatile ("vmwrite %1, %2; setna %0":"=g" (error):"r"(value),
-                                 "r"(field):"cc");
-       if (error)
-               printk("vmwrite error: reg %lx value %lx (err %d)\n",
-                          field, value, vmcs_read32(VM_INSTRUCTION_ERROR));
-}
-
-static void vmcs_write16(unsigned long field, uint16_t value)
-{
-       vmcs_writel(field, value);
-}
-
-static void vmcs_write64(unsigned long field, uint64_t value)
-{
-       print_func_entry();
-#ifdef __x86_64__
-       vmcs_writel(field, value);
-#else
-       vmcs_writel(field, value);
-       asm volatile ("");
-       vmcs_writel(field + 1, value >> 32);
-#endif
-       print_func_exit();
-}
-
-static void inject_gp(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       printd("inject_general_protection: rip 0x%lx\n", vmcs_readl(GUEST_RIP));
-       vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, 0);
-       vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
-                                GP_VECTOR |
-                                INTR_TYPE_EXCEPTION |
-                                INTR_INFO_DELIVER_CODE_MASK | INTR_INFO_VALID_MASK);
-       print_func_exit();
-}
-
-static void update_exception_bitmap(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       if (vcpu->rmode.active)
-               vmcs_write32(EXCEPTION_BITMAP, ~0);
-       else
-               vmcs_write32(EXCEPTION_BITMAP, 1 << PF_VECTOR);
-       print_func_exit();
-}
-
-static void enter_pmode(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       unsigned long flags;
-
-       vcpu->rmode.active = 0;
-
-       vmcs_writel(GUEST_TR_BASE, vcpu->rmode.tr.base);
-       vmcs_write32(GUEST_TR_LIMIT, vcpu->rmode.tr.limit);
-       vmcs_write32(GUEST_TR_AR_BYTES, vcpu->rmode.tr.ar);
-
-       flags = vmcs_readl(GUEST_RFLAGS);
-       flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
-       flags |= (vcpu->rmode.save_iopl << IOPL_SHIFT);
-       vmcs_writel(GUEST_RFLAGS, flags);
-
-       vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~CR4_VME_MASK) |
-                               (vmcs_readl(CR0_READ_SHADOW) & CR4_VME_MASK));
-
-       update_exception_bitmap(vcpu);
-
-#define FIX_PMODE_DATASEG(seg, save) {                         \
-                       vmcs_write16(GUEST_##seg##_SELECTOR, 0);        \
-                       vmcs_writel(GUEST_##seg##_BASE, 0);             \
-                       vmcs_write32(GUEST_##seg##_LIMIT, 0xffff);      \
-                       vmcs_write32(GUEST_##seg##_AR_BYTES, 0x93);     \
-       }
-
-       FIX_PMODE_DATASEG(SS, vcpu->rmode.ss);
-       FIX_PMODE_DATASEG(ES, vcpu->rmode.es);
-       FIX_PMODE_DATASEG(DS, vcpu->rmode.ds);
-       FIX_PMODE_DATASEG(GS, vcpu->rmode.gs);
-       FIX_PMODE_DATASEG(FS, vcpu->rmode.fs);
-
-       vmcs_write16(GUEST_CS_SELECTOR,
-                                vmcs_read16(GUEST_CS_SELECTOR) & ~SELECTOR_RPL_MASK);
-       vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
-       print_func_exit();
-}
-
-static int rmode_tss_base(struct litevm *litevm)
-{
-       print_func_entry();
-       gfn_t base_gfn =
-               litevm->memslots[0].base_gfn + litevm->memslots[0].npages - 3;
-       print_func_exit();
-       return base_gfn << PAGE_SHIFT;
-}
-
-static void enter_rmode(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       unsigned long flags;
-
-       vcpu->rmode.active = 1;
-
-       vcpu->rmode.tr.base = vmcs_readl(GUEST_TR_BASE);
-       vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->litevm));
-
-       vcpu->rmode.tr.limit = vmcs_read32(GUEST_TR_LIMIT);
-       vmcs_write32(GUEST_TR_LIMIT, RMODE_TSS_SIZE - 1);
-
-       vcpu->rmode.tr.ar = vmcs_read32(GUEST_TR_AR_BYTES);
-       vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
-
-       flags = vmcs_readl(GUEST_RFLAGS);
-       vcpu->rmode.save_iopl = (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
-
-       flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
-
-       printk("FLAGS 0x%x\n", flags);
-       vmcs_writel(GUEST_RFLAGS, flags);
-       vmcs_writel(GUEST_CR4, vmcs_readl(GUEST_CR4) | CR4_VME_MASK);
-       update_exception_bitmap(vcpu);
-
-#define FIX_RMODE_SEG(seg, save) {                                \
-               vmcs_write16(GUEST_##seg##_SELECTOR,                       \
-                                       vmcs_readl(GUEST_##seg##_BASE) >> 4); \
-               vmcs_write32(GUEST_##seg##_LIMIT, 0xffff);                 \
-               vmcs_write32(GUEST_##seg##_AR_BYTES, 0xf3);                \
-       }
-
-       vmcs_write32(GUEST_CS_AR_BYTES, 0xf3);
-       vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4);
-
-       FIX_RMODE_SEG(ES, vcpu->rmode.es);
-       FIX_RMODE_SEG(DS, vcpu->rmode.ds);
-       FIX_RMODE_SEG(SS, vcpu->rmode.ss);
-       FIX_RMODE_SEG(GS, vcpu->rmode.gs);
-       FIX_RMODE_SEG(FS, vcpu->rmode.fs);
-       print_func_exit();
-}
-
-static int init_rmode_tss(struct litevm *litevm)
-{
-       print_func_entry();
-       struct page *p1, *p2, *p3;
-       gfn_t fn = rmode_tss_base(litevm) >> PAGE_SHIFT;
-       char *page;
-
-       p1 = _gfn_to_page(litevm, fn++);
-       p2 = _gfn_to_page(litevm, fn++);
-       p3 = _gfn_to_page(litevm, fn);
-
-       if (!p1 || !p2 || !p3) {
-               printk("%s: gfn_to_page failed\n", __FUNCTION__);
-               print_func_exit();
-               return 0;
-       }
-
-       page = page2kva(p1);
-       memset(page, 0, PAGE_SIZE);
-       *(uint16_t *) (page + 0x66) = TSS_BASE_SIZE + TSS_REDIRECTION_SIZE;
-
-       page = page2kva(p2);
-       memset(page, 0, PAGE_SIZE);
-
-       page = page2kva(p3);
-       memset(page, 0, PAGE_SIZE);
-       *(page + RMODE_TSS_SIZE - 2 * PAGE_SIZE - 1) = ~0;
-
-       print_func_exit();
-       return 1;
-}
-
-#ifdef __x86_64__
-
-static void __set_efer(struct litevm_vcpu *vcpu, uint64_t efer)
-{
-       print_func_entry();
-       struct vmx_msr_entry *msr = find_msr_entry(vcpu, MSR_EFER);
-
-       vcpu->shadow_efer = efer;
-       if (efer & EFER_LMA) {
-               vmcs_write32(VM_ENTRY_CONTROLS,
-                                        vmcs_read32(VM_ENTRY_CONTROLS) |
-                                        VM_ENTRY_CONTROLS_IA32E_MASK);
-               msr->value = efer;
-
-       } else {
-               vmcs_write32(VM_ENTRY_CONTROLS,
-                                        vmcs_read32(VM_ENTRY_CONTROLS) &
-                                        ~VM_ENTRY_CONTROLS_IA32E_MASK);
-
-               msr->value = efer & ~EFER_LME;
-       }
-       print_func_exit();
-}
-
-static void enter_lmode(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       uint32_t guest_tr_ar;
-
-       guest_tr_ar = vmcs_read32(GUEST_TR_AR_BYTES);
-       if ((guest_tr_ar & AR_TYPE_MASK) != AR_TYPE_BUSY_64_TSS) {
-               printd("%s: tss fixup for long mode. \n", __FUNCTION__);
-               vmcs_write32(GUEST_TR_AR_BYTES, (guest_tr_ar & ~AR_TYPE_MASK)
-                                        | AR_TYPE_BUSY_64_TSS);
-       }
-
-       vcpu->shadow_efer |= EFER_LMA;
-
-       find_msr_entry(vcpu, MSR_EFER)->value |= EFER_LMA | EFER_LME;
-       vmcs_write32(VM_ENTRY_CONTROLS, vmcs_read32(VM_ENTRY_CONTROLS)
-                                | VM_ENTRY_CONTROLS_IA32E_MASK);
-       print_func_exit();
-}
-
-static void exit_lmode(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       vcpu->shadow_efer &= ~EFER_LMA;
-
-       vmcs_write32(VM_ENTRY_CONTROLS, vmcs_read32(VM_ENTRY_CONTROLS)
-                                & ~VM_ENTRY_CONTROLS_IA32E_MASK);
-       print_func_exit();
-}
-
-#endif
-
-static void __set_cr0(struct litevm_vcpu *vcpu, unsigned long cr0)
-{
-       print_func_entry();
-       if (vcpu->rmode.active && (cr0 & CR0_PE_MASK))
-               enter_pmode(vcpu);
-
-       if (!vcpu->rmode.active && !(cr0 & CR0_PE_MASK))
-               enter_rmode(vcpu);
-
-#ifdef __x86_64__
-       if (vcpu->shadow_efer & EFER_LME) {
-               if (!is_paging() && (cr0 & CR0_PG_MASK))
-                       enter_lmode(vcpu);
-               if (is_paging() && !(cr0 & CR0_PG_MASK))
-                       exit_lmode(vcpu);
-       }
-#endif
-
-       vmcs_writel(CR0_READ_SHADOW, cr0);
-       vmcs_writel(GUEST_CR0, cr0 | LITEVM_VM_CR0_ALWAYS_ON);
-       print_func_exit();
-}
-
-static int pdptrs_have_reserved_bits_set(struct litevm_vcpu *vcpu,
-                                                                                unsigned long cr3)
-{
-       print_func_entry();
-       gfn_t pdpt_gfn = cr3 >> PAGE_SHIFT;
-       unsigned offset = (cr3 & (PAGE_SIZE - 1)) >> 5;
-       int i;
-       uint64_t pdpte;
-       uint64_t *pdpt;
-       struct litevm_memory_slot *memslot;
-
-       SPLL(&vcpu->litevm->lock);
-       memslot = gfn_to_memslot(vcpu->litevm, pdpt_gfn);
-       /* FIXME: !memslot - emulate? 0xff? */
-       pdpt = page2kva(gfn_to_page(memslot, pdpt_gfn));
-
-       for (i = 0; i < 4; ++i) {
-               pdpte = pdpt[offset + i];
-               if ((pdpte & 1) && (pdpte & 0xfffffff0000001e6ull))
-                       break;
-       }
-
-       SPLU(&vcpu->litevm->lock);
-
-       print_func_exit();
-       return i != 4;
-}
-
-static void set_cr0(struct litevm_vcpu *vcpu, unsigned long cr0)
-{
-       print_func_entry();
-       if (cr0 & CR0_RESEVED_BITS) {
-               printd("set_cr0: 0x%lx #GP, reserved bits 0x%lx\n", cr0, guest_cr0());
-               inject_gp(vcpu);
-               print_func_exit();
-               return;
-       }
-
-       if ((cr0 & CR0_NW_MASK) && !(cr0 & CR0_CD_MASK)) {
-               printd("set_cr0: #GP, CD == 0 && NW == 1\n");
-               inject_gp(vcpu);
-               print_func_exit();
-               return;
-       }
-
-       if ((cr0 & CR0_PG_MASK) && !(cr0 & CR0_PE_MASK)) {
-               printd("set_cr0: #GP, set PG flag " "and a clear PE flag\n");
-               inject_gp(vcpu);
-               print_func_exit();
-               return;
-       }
-
-       if (!is_paging() && (cr0 & CR0_PG_MASK)) {
-#ifdef __x86_64__
-               if ((vcpu->shadow_efer & EFER_LME)) {
-                       uint32_t guest_cs_ar;
-                       if (!is_pae()) {
-                               printd("set_cr0: #GP, start paging "
-                                          "in long mode while PAE is disabled\n");
-                               inject_gp(vcpu);
-                               print_func_exit();
-                               return;
-                       }
-                       guest_cs_ar = vmcs_read32(GUEST_CS_AR_BYTES);
-                       if (guest_cs_ar & SEGMENT_AR_L_MASK) {
-                               printd("set_cr0: #GP, start paging "
-                                          "in long mode while CS.L == 1\n");
-                               inject_gp(vcpu);
-                               print_func_exit();
-                               return;
-
-                       }
-               } else
-#endif
-               if (is_pae() && pdptrs_have_reserved_bits_set(vcpu, vcpu->cr3)) {
-                       printd("set_cr0: #GP, pdptrs " "reserved bits\n");
-                       inject_gp(vcpu);
-                       print_func_exit();
-                       return;
-               }
-
-       }
-
-       __set_cr0(vcpu, cr0);
-       litevm_mmu_reset_context(vcpu);
-       print_func_exit();
-       return;
-}
-
-static void lmsw(struct litevm_vcpu *vcpu, unsigned long msw)
-{
-       print_func_entry();
-       unsigned long cr0 = guest_cr0();
-
-       if ((msw & CR0_PE_MASK) && !(cr0 & CR0_PE_MASK)) {
-               enter_pmode(vcpu);
-               vmcs_writel(CR0_READ_SHADOW, cr0 | CR0_PE_MASK);
-
-       } else
-               printd("lmsw: unexpected\n");
-
-       vmcs_writel(GUEST_CR0, (vmcs_readl(GUEST_CR0) & ~LMSW_GUEST_MASK)
-                               | (msw & LMSW_GUEST_MASK));
-       print_func_exit();
-}
-
-static void __set_cr4(struct litevm_vcpu *vcpu, unsigned long cr4)
-{
-       print_func_entry();
-       vmcs_writel(CR4_READ_SHADOW, cr4);
-       vmcs_writel(GUEST_CR4, cr4 | (vcpu->rmode.active ?
-                                                                 LITEVM_RMODE_VM_CR4_ALWAYS_ON :
-                                                                 LITEVM_PMODE_VM_CR4_ALWAYS_ON));
-       print_func_exit();
-}
-
-static void set_cr4(struct litevm_vcpu *vcpu, unsigned long cr4)
-{
-       print_func_entry();
-       if (cr4 & CR4_RESEVED_BITS) {
-               printd("set_cr4: #GP, reserved bits\n");
-               inject_gp(vcpu);
-               print_func_exit();
-               return;
-       }
-
-       if (is_long_mode()) {
-               if (!(cr4 & CR4_PAE_MASK)) {
-                       printd("set_cr4: #GP, clearing PAE while " "in long mode\n");
-                       inject_gp(vcpu);
-                       print_func_exit();
-                       return;
-               }
-       } else if (is_paging() && !is_pae() && (cr4 & CR4_PAE_MASK)
-                          && pdptrs_have_reserved_bits_set(vcpu, vcpu->cr3)) {
-               printd("set_cr4: #GP, pdptrs reserved bits\n");
-               inject_gp(vcpu);
-       }
-
-       if (cr4 & CR4_VMXE_MASK) {
-               printd("set_cr4: #GP, setting VMXE\n");
-               inject_gp(vcpu);
-               print_func_exit();
-               return;
-       }
-       __set_cr4(vcpu, cr4);
-       SPLL(&vcpu->litevm->lock);
-       litevm_mmu_reset_context(vcpu);
-       SPLU(&vcpu->litevm->lock);
-       print_func_exit();
-}
-
-static void set_cr3(struct litevm_vcpu *vcpu, unsigned long cr3)
-{
-       print_func_entry();
-       if (is_long_mode()) {
-               if (cr3 & CR3_L_MODE_RESEVED_BITS) {
-                       printd("set_cr3: #GP, reserved bits\n");
-                       inject_gp(vcpu);
-                       print_func_exit();
-                       return;
-               }
-       } else {
-               if (cr3 & CR3_RESEVED_BITS) {
-                       printd("set_cr3: #GP, reserved bits\n");
-                       inject_gp(vcpu);
-                       print_func_exit();
-                       return;
-               }
-               if (is_paging() && is_pae() && pdptrs_have_reserved_bits_set(vcpu, cr3)) {
-                       printd("set_cr3: #GP, pdptrs " "reserved bits\n");
-                       inject_gp(vcpu);
-                       print_func_exit();
-                       return;
-               }
-       }
-
-       vcpu->cr3 = cr3;
-       SPLL(&vcpu->litevm->lock);
-       vcpu->mmu.new_cr3(vcpu);
-       SPLU(&vcpu->litevm->lock);
-       print_func_exit();
-}
-
-static void set_cr8(struct litevm_vcpu *vcpu, unsigned long cr8)
-{
-       print_func_entry();
-       if (cr8 & CR8_RESEVED_BITS) {
-               printd("set_cr8: #GP, reserved bits 0x%lx\n", cr8);
-               inject_gp(vcpu);
-               print_func_exit();
-               return;
-       }
-       vcpu->cr8 = cr8;
-       print_func_exit();
-}
-
-static uint32_t get_rdx_init_val(void)
-{
-       print_func_entry();
-       uint32_t val;
-
-asm("movl $1, %%eax \n\t" "movl %%eax, %0 \n\t":"=g"(val));
-       print_func_exit();
-       return val;
-
-}
-
-static void fx_init(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       struct __attribute__ ((__packed__)) fx_image_s {
-               uint16_t control;               //fcw
-               uint16_t status;                //fsw
-               uint16_t tag;                   // ftw
-               uint16_t opcode;                //fop
-               uint64_t ip;                    // fpu ip
-               uint64_t operand;               // fpu dp
-               uint32_t mxcsr;
-               uint32_t mxcsr_mask;
-
-       } *fx_image;
-
-       fx_save(vcpu->host_fx_image);
-       fpu_init();
-       fx_save(vcpu->guest_fx_image);
-       fx_restore(vcpu->host_fx_image);
-
-       fx_image = (struct fx_image_s *)vcpu->guest_fx_image;
-       fx_image->mxcsr = 0x1f80;
-       memset(vcpu->guest_fx_image + sizeof(struct fx_image_s),
-                  0, FX_IMAGE_SIZE - sizeof(struct fx_image_s));
-       print_func_exit();
-}
-
-static void vmcs_write32_fixedbits(uint32_t msr, uint32_t vmcs_field,
-                                                                  uint32_t val)
-{
-       uint32_t msr_high, msr_low;
-       uint64_t msrval;
-
-       msrval = read_msr(msr);
-       msr_low = msrval;
-       msr_high = (msrval >> 32);
-
-       val &= msr_high;
-       val |= msr_low;
-       vmcs_write32(vmcs_field, val);
-}
-
-/*
- * Sets up the vmcs for emulated real mode.
- */
-static int litevm_vcpu_setup(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-
-/* no op on x86_64 */
-#define asmlinkage
-       extern asmlinkage void litevm_vmx_return(void);
-       uint32_t host_sysenter_cs;
-       uint32_t junk;
-       uint64_t a;
-       struct descriptor_table dt;
-       int i;
-       int ret;
-       uint64_t tsc;
-       int nr_good_msrs;
-
-       memset(vcpu->regs, 0, sizeof(vcpu->regs));
-       vcpu->regs[VCPU_REGS_RDX] = get_rdx_init_val();
-       vcpu->cr8 = 0;
-       vcpu->apic_base = 0xfee00000 |
-               /*for vcpu 0 */ MSR_IA32_APICBASE_BSP |
-               MSR_IA32_APICBASE_ENABLE;
-
-       fx_init(vcpu);
-
-#define SEG_SETUP(seg) do {                                    \
-               vmcs_write16(GUEST_##seg##_SELECTOR, 0);        \
-               vmcs_writel(GUEST_##seg##_BASE, 0);             \
-               vmcs_write32(GUEST_##seg##_LIMIT, 0xffff);      \
-               vmcs_write32(GUEST_##seg##_AR_BYTES, 0x93);     \
-       } while (0)
-
-       /*
-        * GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode
-        * insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4.  Sigh.
-        */
-       vmcs_write16(GUEST_CS_SELECTOR, 0xf000);
-       vmcs_writel(GUEST_CS_BASE, 0x000f0000);
-       vmcs_write32(GUEST_CS_LIMIT, 0xffff);
-       vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
-
-       SEG_SETUP(DS);
-       SEG_SETUP(ES);
-       SEG_SETUP(FS);
-       SEG_SETUP(GS);
-       SEG_SETUP(SS);
-
-       vmcs_write16(GUEST_TR_SELECTOR, 0);
-       vmcs_writel(GUEST_TR_BASE, 0);
-       vmcs_write32(GUEST_TR_LIMIT, 0xffff);
-       vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
-
-       vmcs_write16(GUEST_LDTR_SELECTOR, 0);
-       vmcs_writel(GUEST_LDTR_BASE, 0);
-       vmcs_write32(GUEST_LDTR_LIMIT, 0xffff);
-       vmcs_write32(GUEST_LDTR_AR_BYTES, 0x00082);
-
-       vmcs_write32(GUEST_SYSENTER_CS, 0);
-       vmcs_writel(GUEST_SYSENTER_ESP, 0);
-       vmcs_writel(GUEST_SYSENTER_EIP, 0);
-
-       vmcs_writel(GUEST_RFLAGS, 0x02);
-       vmcs_writel(GUEST_RIP, 0xfff0);
-       vmcs_writel(GUEST_RSP, 0);
-
-       vmcs_writel(GUEST_CR3, 0);
-
-       //todo: dr0 = dr1 = dr2 = dr3 = 0; dr6 = 0xffff0ff0
-       vmcs_writel(GUEST_DR7, 0x400);
-
-       vmcs_writel(GUEST_GDTR_BASE, 0);
-       vmcs_write32(GUEST_GDTR_LIMIT, 0xffff);
-
-       vmcs_writel(GUEST_IDTR_BASE, 0);
-       vmcs_write32(GUEST_IDTR_LIMIT, 0xffff);
-
-       vmcs_write32(GUEST_ACTIVITY_STATE, 0);
-       vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0);
-       vmcs_write32(GUEST_PENDING_DBG_EXCEPTIONS, 0);
-
-       /* I/O */
-       vmcs_write64(IO_BITMAP_A, 0);
-       vmcs_write64(IO_BITMAP_B, 0);
-
-       tsc = read_tsc();
-       vmcs_write64(TSC_OFFSET, -tsc);
-
-       vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */
-
-       /* Special registers */
-       vmcs_write64(GUEST_IA32_DEBUGCTL, 0);
-
-       /* Control */
-       vmcs_write32_fixedbits(MSR_IA32_VMX_PINBASED_CTLS_MSR, PIN_BASED_VM_EXEC_CONTROL, PIN_BASED_EXT_INTR_MASK       /* 20.6.1 */
-                                                  | PIN_BASED_NMI_EXITING      /* 20.6.1 */
-               );
-       vmcs_write32_fixedbits(MSR_IA32_VMX_PROCBASED_CTLS_MSR, CPU_BASED_VM_EXEC_CONTROL, CPU_BASED_HLT_EXITING        /* 20.6.2 */
-                                                  | CPU_BASED_CR8_LOAD_EXITING /* 20.6.2 */
-                                                  | CPU_BASED_CR8_STORE_EXITING        /* 20.6.2 */
-                                                  | CPU_BASED_UNCOND_IO_EXITING        /* 20.6.2 */
-                                                  | CPU_BASED_INVDPG_EXITING | CPU_BASED_MOV_DR_EXITING | CPU_BASED_USE_TSC_OFFSETING  /* 21.3 */
-               );
-
-       vmcs_write32(EXCEPTION_BITMAP, 1 << PF_VECTOR);
-       vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, 0);
-       vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, 0);
-       vmcs_write32(CR3_TARGET_COUNT, 0);      /* 22.2.1 */
-
-       vmcs_writel(HOST_CR0, rcr0());  /* 22.2.3 */
-       vmcs_writel(HOST_CR4, rcr4());  /* 22.2.3, 22.2.5 */
-       vmcs_writel(HOST_CR3, rcr3());  /* 22.2.3  FIXME: shadow tables */
-
-       vmcs_write16(HOST_CS_SELECTOR, GD_KT);  /* 22.2.4 */
-       vmcs_write16(HOST_DS_SELECTOR, GD_KD);  /* 22.2.4 */
-       vmcs_write16(HOST_ES_SELECTOR, GD_KD);  /* 22.2.4 */
-       vmcs_write16(HOST_FS_SELECTOR, read_fs());      /* 22.2.4 */
-       vmcs_write16(HOST_GS_SELECTOR, read_gs());      /* 22.2.4 */
-       vmcs_write16(HOST_SS_SELECTOR, GD_KD);  /* 22.2.4 */
-
-#ifdef __x86_64__
-       a = read_msr(MSR_FS_BASE);
-       vmcs_writel(HOST_FS_BASE, a);   /* 22.2.4 */
-       a = read_msr(MSR_GS_BASE);
-       vmcs_writel(HOST_GS_BASE, a);   /* 22.2.4 */
-#else
-       vmcs_writel(HOST_FS_BASE, 0);   /* 22.2.4 */
-       vmcs_writel(HOST_GS_BASE, 0);   /* 22.2.4 */
-#endif
-
-       vmcs_write16(HOST_TR_SELECTOR, GD_TSS * 8);     /* 22.2.4 */
-
-       get_idt(&dt);
-       vmcs_writel(HOST_IDTR_BASE, dt.base);   /* 22.2.4 */
-
-       vmcs_writel(HOST_RIP, (unsigned long)litevm_vmx_return);        /* 22.2.5 */
-
-       /* it's the HIGH 32 bits! */
-       host_sysenter_cs = read_msr(MSR_IA32_SYSENTER_CS) >> 32;
-       vmcs_write32(HOST_IA32_SYSENTER_CS, host_sysenter_cs);
-       a = read_msr(MSR_IA32_SYSENTER_ESP);
-       vmcs_writel(HOST_IA32_SYSENTER_ESP, a); /* 22.2.3 */
-       a = read_msr(MSR_IA32_SYSENTER_EIP);
-       vmcs_writel(HOST_IA32_SYSENTER_EIP, a); /* 22.2.3 */
-
-       ret = -ENOMEM;
-       vcpu->guest_msrs = kmalloc(PAGE_SIZE, KMALLOC_WAIT);
-       if (!vcpu->guest_msrs)
-               error("guest_msrs kmalloc failed");
-       vcpu->host_msrs = kmalloc(PAGE_SIZE, KMALLOC_WAIT);
-       if (!vcpu->host_msrs)
-               error("vcpu->host_msrs kmalloc failed -- storage leaked");
-
-       for (i = 0; i < NR_VMX_MSR; ++i) {
-               uint32_t index = vmx_msr_index[i];
-               uint32_t data_low, data_high;
-               uint64_t data;
-               int j = vcpu->nmsrs;
-
-#warning "need readmsr_safe"
-//      if (rdmsr_safe(index, &data_low, &data_high) < 0)
-//          continue;
-               data = read_msr(index);
-               vcpu->host_msrs[j].index = index;
-               vcpu->host_msrs[j].reserved = 0;
-               vcpu->host_msrs[j].value = data;
-               vcpu->guest_msrs[j] = vcpu->host_msrs[j];
-               ++vcpu->nmsrs;
-       }
-       printk("msrs: %d\n", vcpu->nmsrs);
-
-       nr_good_msrs = vcpu->nmsrs - NR_BAD_MSRS;
-       vmcs_writel(VM_ENTRY_MSR_LOAD_ADDR, PADDR(vcpu->guest_msrs + NR_BAD_MSRS));
-       vmcs_writel(VM_EXIT_MSR_STORE_ADDR, PADDR(vcpu->guest_msrs + NR_BAD_MSRS));
-       vmcs_writel(VM_EXIT_MSR_LOAD_ADDR, PADDR(vcpu->host_msrs + NR_BAD_MSRS));
-       vmcs_write32_fixedbits(MSR_IA32_VMX_EXIT_CTLS_MSR, VM_EXIT_CONTROLS, (HOST_IS_64 << 9));        /* 22.2,1, 20.7.1 */
-       vmcs_write32(VM_EXIT_MSR_STORE_COUNT, nr_good_msrs);    /* 22.2.2 */
-       vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, nr_good_msrs);     /* 22.2.2 */
-       vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, nr_good_msrs);    /* 22.2.2 */
-
-       /* 22.2.1, 20.8.1 */
-       vmcs_write32_fixedbits(MSR_IA32_VMX_ENTRY_CTLS_MSR, VM_ENTRY_CONTROLS, 0);
-       vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, 0);      /* 22.2.1 */
-
-       vmcs_writel(VIRTUAL_APIC_PAGE_ADDR, 0);
-       vmcs_writel(TPR_THRESHOLD, 0);
-
-       vmcs_writel(CR0_GUEST_HOST_MASK, LITEVM_GUEST_CR0_MASK);
-       vmcs_writel(CR4_GUEST_HOST_MASK, LITEVM_GUEST_CR4_MASK);
-
-       __set_cr0(vcpu, 0x60000010);    // enter rmode
-       __set_cr4(vcpu, 0);
-#ifdef __x86_64__
-       __set_efer(vcpu, 0);
-#endif
-
-       ret = litevm_mmu_init(vcpu);
-
-       print_func_exit();
-       return ret;
-
-out_free_guest_msrs:
-       kfree(vcpu->guest_msrs);
-out:
-       return ret;
-}
-
-/*
- * Sync the rsp and rip registers into the vcpu structure.  This allows
- * registers to be accessed by indexing vcpu->regs.
- */
-static void vcpu_load_rsp_rip(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       vcpu->regs[VCPU_REGS_RSP] = vmcs_readl(GUEST_RSP);
-       vcpu->rip = vmcs_readl(GUEST_RIP);
-       print_func_exit();
-}
-
-/*
- * Syncs rsp and rip back into the vmcs.  Should be called after possible
- * modification.
- */
-static void vcpu_put_rsp_rip(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       vmcs_writel(GUEST_RSP, vcpu->regs[VCPU_REGS_RSP]);
-       vmcs_writel(GUEST_RIP, vcpu->rip);
-       print_func_exit();
-}
-
-/*
- * Creates some virtual cpus.  Good luck creating more than one.
- */
-int vmx_create_vcpu(struct litevm *litevm, int n)
-{
-       print_func_entry();
-       ERRSTACK(2);
-       int r;
-       struct litevm_vcpu *vcpu;
-       struct vmcs *vmcs;
-       char *errstring = NULL;
-
-       if (n < 0 || n >= LITEVM_MAX_VCPUS) {
-               printk("%d is out of range; LITEVM_MAX_VCPUS is %d", n,
-                          LITEVM_MAX_VCPUS);
-               error("%d is out of range; LITEVM_MAX_VCPUS is %d", n,
-                         LITEVM_MAX_VCPUS);
-       }
-       printk("LOCK %p, locked %d\n", &litevm->lock, spin_locked(&litevm->lock));
-       vcpu = &litevm->vcpus[n];
-
-       printk("vmx_create_vcpu: @%d, %p\n", n, vcpu);
-       QLOCK(&vcpu->mutex);
-
-       if (vcpu->vmcs) {
-               QUNLOCK(&vcpu->mutex);
-               printk("VM already exists\n");
-               error("VM already exists");
-       }
-       printk("LOCK %p, locked %d\n", &litevm->lock, spin_locked(&litevm->lock));
-       /* I'm a bad person */
-       //ALIGN(vcpu->fx_buf, FX_IMAGE_ALIGN);
-       uint64_t a = (uint64_t) vcpu->fx_buf;
-       a += FX_IMAGE_ALIGN - 1;
-       a /= FX_IMAGE_ALIGN;
-       a *= FX_IMAGE_ALIGN;
-
-       vcpu->host_fx_image = (char *)a;
-       vcpu->guest_fx_image = vcpu->host_fx_image + FX_IMAGE_SIZE;
-
-       vcpu->cpu = -1; /* First load will set up TR */
-       vcpu->litevm = litevm;
-       printk("LOCK %p, locked %d\n", &litevm->lock, spin_locked(&litevm->lock));
-       if (waserror()){
-               printk("ERR 1 in %s, %s\n", __func__, current_errstr());
-               QUNLOCK(&vcpu->mutex);
-               litevm_free_vcpu(vcpu);
-               nexterror();
-       }
-       printk("LOCK %p, locked %d\n", &litevm->lock, spin_locked(&litevm->lock));
-       vmcs = alloc_vmcs();
-       vmcs_clear(vmcs);
-       printk("LOCK %p, locked %d\n", &litevm->lock, spin_locked(&litevm->lock));
-       printk("after vmcs_clear\n");
-       vcpu->vmcs = vmcs;
-       printk("vcpu %p set vmcs to %p\n", vcpu, vmcs);
-       vcpu->launched = 0;
-       printk("vcpu %p slot %d vmcs is %p\n", vcpu, n, vmcs);
-
-       __vcpu_load(vcpu);
-
-       printk("PAST vcpu_load\n");
-       if (waserror()) {
-               /* we really need to fix waserror() */
-               printk("vcpu_setup failed: %s\n", current_errstr());
-               QUNLOCK(&vcpu->mutex);
-               nexterror();
-       }
-
-       /* need memory for the rmode_tss. I have no idea how this happened
-        * originally in kvm.
-        */
-       /* this sucks. */
-       QUNLOCK(&vcpu->mutex);
-       void *v;
-       struct litevm_memory_region vmr;
-       vmr.slot = 0;
-       vmr.flags = 0;
-       vmr.guest_phys_addr = /* guess. */ 0x1000000;
-       vmr.memory_size = 0x10000;
-       vmr.init_data = NULL;
-       if (vm_set_memory_region(litevm, &vmr))
-               printk("vm_set_memory_region failed");
-
-       printk("set memory region done\n");
-
-       if (!init_rmode_tss(litevm)) {
-               error("vcpu_setup: init_rmode_tss failed");
-       }
-
-
-       QLOCK(&vcpu->mutex);
-       r = litevm_vcpu_setup(vcpu);
-
-       vcpu_put(vcpu);
-
-       printk("r is %d\n", r);
-
-       if (!r) {
-               poperror();
-               print_func_exit();
-               return 0;
-       }
-
-       errstring = "vcup set failed";
-
-out_free_vcpus:
-out:
-       print_func_exit();
-       return r;
-}
-
-/*
- * Allocate some memory and give it an address in the guest physical address
- * space.
- *
- * Discontiguous memory is allowed, mostly for framebuffers.
- */
-int vm_set_memory_region(struct litevm *litevm,
-                                                struct litevm_memory_region *mem)
-{
-       print_func_entry();
-       ERRSTACK(2);
-       int r;
-       gfn_t base_gfn;
-       unsigned long npages;
-       unsigned long i;
-       struct litevm_memory_slot *memslot;
-       struct litevm_memory_slot old, new;
-       int memory_config_version;
-       void *init_data = mem->init_data;
-       int pass = 1;
-       printk("%s: slot %d base %08x npages %d\n", 
-               __func__, 
-              mem->slot, mem->guest_phys_addr, 
-              mem->memory_size);
-       /* should not happen but ... */
-       if (!litevm)
-               error("NULL litevm in %s", __func__);
-
-       if (!mem)
-               error("NULL mem in %s", __func__);
-       /* I don't care right now. *
-       if (litevm->busy)
-               error("litevm->busy is set! 0x%x\n", litevm->busy);
-       */
-       r = -EINVAL;
-       /* General sanity checks */
-       if (mem->memory_size & (PAGE_SIZE - 1))
-               error("mem->memory_size %lld is not page-aligned", mem->memory_size);
-       if (mem->guest_phys_addr & (PAGE_SIZE - 1))
-               error("guest_phys_addr 0x%llx is not page-aligned",
-                         mem->guest_phys_addr);
-       if (mem->slot >= LITEVM_MEMORY_SLOTS)
-               error("Slot %d is >= %d", mem->slot, LITEVM_MEMORY_SLOTS);
-       if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr)
-               error("0x%x + 0x%x is < 0x%x",
-                         mem->guest_phys_addr, mem->memory_size, mem->guest_phys_addr);
-
-       memslot = &litevm->memslots[mem->slot];
-       base_gfn = mem->guest_phys_addr >> PAGE_SHIFT;
-       npages = mem->memory_size >> PAGE_SHIFT;
-
-       if (!npages)
-               mem->flags &= ~LITEVM_MEM_LOG_DIRTY_PAGES;
-
-       /* this is actually a very tricky for loop. The use of
-        * error is a bit dangerous, so we don't use it much.
-        * consider a rewrite. Would be nice if akaros could do the
-        * allocation of a bunch of pages for us.
-        */
-raced:
-       printk("raced: pass %d\n", pass);
-       printk("LOCK %p, locked %d\n", &litevm->lock, spin_locked(&litevm->lock));
-       void monitor(void *);
-       monitor(NULL);
-       SPLL(&litevm->lock);
-       printk("locked\n");
-
-       if (waserror()) {
-               printk("error in %s, %s\n", __func__, current_errstr());
-               SPLU(&litevm->lock);
-               nexterror();
-       }
-
-       memory_config_version = litevm->memory_config_version;
-       new = old = *memslot;
-       printk("memory_config_version %d\n", memory_config_version);
-
-       new.base_gfn = base_gfn;
-       new.npages = npages;
-       new.flags = mem->flags;
-
-       /* Disallow changing a memory slot's size. */
-       r = -EINVAL;
-       if (npages && old.npages && npages != old.npages)
-               error("npages is %d, old.npages is %d, can't change",
-                         npages, old.npages);
-
-       /* Check for overlaps */
-       r = -EEXIST;
-       for (i = 0; i < LITEVM_MEMORY_SLOTS; ++i) {
-               struct litevm_memory_slot *s = &litevm->memslots[i];
-printk("Region %d: base gfn 0x%x npages %d\n", s->base_gfn, s->npages);
-               if (s == memslot)
-                       continue;
-               if (!((base_gfn + npages <= s->base_gfn) ||
-                         (base_gfn >= s->base_gfn + s->npages)))
-                       error("Overlap");
-       }
-       /*
-        * Do memory allocations outside lock.  memory_config_version will
-        * detect any races.
-        */
-       SPLU(&litevm->lock);
-       printk("unlocked\n");
-       poperror();
-
-       /* Deallocate if slot is being removed */
-       if (!npages)
-               new.phys_mem = 0;
-
-       /* Free page dirty bitmap if unneeded */
-       if (!(new.flags & LITEVM_MEM_LOG_DIRTY_PAGES))
-               new.dirty_bitmap = 0;
-
-       r = -ENOMEM;
-
-       /* Allocate if a slot is being created */
-       if (npages && !new.phys_mem) {
-               new.phys_mem = kzmalloc(npages * sizeof(struct page *), KMALLOC_WAIT);
-
-               if (!new.phys_mem)
-                       goto out_free;
-
-               for (i = 0; i < npages; ++i) {
-                       int ret;
-                       ret = kpage_alloc(&new.phys_mem[i]);
-                       printk("PAGEALLOC: va %p pa %p\n",page2kva(new.phys_mem[i]),page2pa(new.phys_mem[i]));
-                       if (ret != ESUCCESS)
-                               goto out_free;
-                       if (init_data) {
-                               printk("init data memcpy(%p,%p,4096);\n",
-                                          page2kva(new.phys_mem[i]), init_data);
-                               memcpy(page2kva(new.phys_mem[i]), init_data, PAGE_SIZE);
-                               init_data += PAGE_SIZE;
-                       } else {
-                               int j;
-                               //memset(page2kva(new.phys_mem[i]), 0xf4 /* hlt */, PAGE_SIZE);
-                               uint8_t *cp = page2kva(new.phys_mem[i]);
-                               memset(cp, 0, PAGE_SIZE);
-                               if (base_gfn < 0x100000){
-                               for(j = 0; j < PAGE_SIZE; j += 2){
-                                       // XORL %RAX, %RAX
-                                       cp[j] = 0x31; cp[j+1] = 0xc0;
-                               }
-                               // 1: jmp 1b
-                               cp[4094] = 0xeb;
-                               cp[4095] = 0xfe;
-                               }
-                                       
-                               init_data += PAGE_SIZE;
-                       }
-               }
-       }
-
-       /* Allocate page dirty bitmap if needed */
-       if ((new.flags & LITEVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) {
-               unsigned dirty_bytes;   //ALIGN(npages, BITS_PER_LONG) / 8;
-               dirty_bytes =
-                       (((npages + BITS_PER_LONG -
-                          1) / BITS_PER_LONG) * BITS_PER_LONG) / 8;
-
-               new.dirty_bitmap = kzmalloc(dirty_bytes, KMALLOC_WAIT);
-               if (!new.dirty_bitmap) {
-                       printk("VM: alloc of %d bytes for map failed\n", dirty_bytes);
-                       goto out_free;
-               }
-       }
-
-       SPLL(&litevm->lock);
-       printk("locked\n");
-       if (memory_config_version != litevm->memory_config_version) {
-               SPLU(&litevm->lock);
-               printk("unlocked, try again\n");
-               litevm_free_physmem_slot(&new, &old);
-               goto raced;
-       }
-
-       r = -EAGAIN;
-       if (litevm->busy) {
-               printk("BUSY!\n");
-               goto out_unlock;
-       }
-
-       if (mem->slot >= litevm->nmemslots)
-               litevm->nmemslots = mem->slot + 1;
-
-       *memslot = new;
-       ++litevm->memory_config_version;
-
-       SPLU(&litevm->lock);
-       printk("unlocked\n");
-       for (i = 0; i < LITEVM_MAX_VCPUS; ++i) {
-               struct litevm_vcpu *vcpu;
-
-               vcpu = vcpu_load(litevm, i);
-               if (!vcpu){
-                       printk("%s: no cpu %d\n", __func__, i);
-                       continue;
-               }
-               litevm_mmu_reset_context(vcpu);
-               vcpu_put(vcpu);
-       }
-
-       litevm_free_physmem_slot(&old, &new);
-       print_func_exit();
-       return 0;
-
-out_unlock:
-       SPLU(&litevm->lock);
-       printk("out_unlock\n");
-out_free:
-       printk("out_free\n");
-       litevm_free_physmem_slot(&new, &old);
-out:
-       printk("vm_set_memory_region: return %d\n", r);
-       print_func_exit();
-       return r;
-}
-
-#if 0
-/*
- * Get (and clear) the dirty memory log for a memory slot.
- */
-static int litevm_dev_ioctl_get_dirty_log(struct litevm *litevm,
-                                                                                 struct litevm_dirty_log *log)
-{
-       struct litevm_memory_slot *memslot;
-       int r, i;
-       int n;
-       unsigned long any = 0;
-
-       SPLL(&litevm->lock);
-
-       /*
-        * Prevent changes to guest memory configuration even while the lock
-        * is not taken.
-        */
-       ++litevm->busy;
-       SPLU(&litevm->lock);
-       r = -EINVAL;
-       if (log->slot >= LITEVM_MEMORY_SLOTS)
-               goto out;
-
-       memslot = &litevm->memslots[log->slot];
-       r = -ENOENT;
-       if (!memslot->dirty_bitmap)
-               goto out;
-
-       n = ALIGN(memslot->npages, 8) / 8;
-
-       for (i = 0; !any && i < n; ++i)
-               any = memslot->dirty_bitmap[i];
-
-       r = -EFAULT;
-       if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n))
-               goto out;
-
-       if (any) {
-               SPLL(&litevm->lock);
-               litevm_mmu_slot_remove_write_access(litevm, log->slot);
-               SPLU(&litevm->lock);
-               memset(memslot->dirty_bitmap, 0, n);
-               for (i = 0; i < LITEVM_MAX_VCPUS; ++i) {
-                       struct litevm_vcpu *vcpu = vcpu_load(litevm, i);
-
-                       if (!vcpu)
-                               continue;
-                       flush_guest_tlb(vcpu);
-                       vcpu_put(vcpu);
-               }
-       }
-
-       r = 0;
-
-out:
-       SPLL(&litevm->lock);
-       --litevm->busy;
-       SPLU(&litevm->lock);
-       return r;
-}
-#endif
-
-struct litevm_memory_slot *gfn_to_memslot(struct litevm *litevm, gfn_t gfn)
-{
-       print_func_entry();
-       int i;
-
-       printk("%s: litevm %p gfn %d\n", litevm, gfn);
-       for (i = 0; i < litevm->nmemslots; ++i) {
-               struct litevm_memory_slot *memslot = &litevm->memslots[i];
-
-               printk("%s: slot %d gfn 0x%lx base_gfn %lx npages %x\n", 
-                       __func__, i, gfn,memslot->base_gfn, memslot->npages);
-               if (gfn >= memslot->base_gfn
-                       && gfn < memslot->base_gfn + memslot->npages) {
-                       print_func_exit();
-                       return memslot;
-               }
-       }
-       print_func_exit();
-       return 0;
-}
-
-void mark_page_dirty(struct litevm *litevm, gfn_t gfn)
-{
-       print_func_entry();
-       int i;
-       struct litevm_memory_slot *memslot = 0;
-       unsigned long rel_gfn;
-
-       for (i = 0; i < litevm->nmemslots; ++i) {
-               memslot = &litevm->memslots[i];
-
-               if (gfn >= memslot->base_gfn
-                       && gfn < memslot->base_gfn + memslot->npages) {
-
-                       if (!memslot || !memslot->dirty_bitmap) {
-                               print_func_exit();
-                               return;
-                       }
-
-                       rel_gfn = gfn - memslot->base_gfn;
-
-                       /* avoid RMW */
-                       if (!GET_BITMASK_BIT(memslot->dirty_bitmap, rel_gfn))
-                               SET_BITMASK_BIT_ATOMIC(memslot->dirty_bitmap, rel_gfn);
-                       print_func_exit();
-                       return;
-               }
-       }
-       print_func_exit();
-}
-
-static void skip_emulated_instruction(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       unsigned long rip;
-       uint32_t interruptibility;
-
-       rip = vmcs_readl(GUEST_RIP);
-       rip += vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
-       vmcs_writel(GUEST_RIP, rip);
-
-       /*
-        * We emulated an instruction, so temporary interrupt blocking
-        * should be removed, if set.
-        */
-       interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
-       if (interruptibility & 3)
-               vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, interruptibility & ~3);
-       print_func_exit();
-}
-
-static int emulator_read_std(unsigned long addr,
-                                                        unsigned long *val,
-                                                        unsigned int bytes, struct x86_emulate_ctxt *ctxt)
-{
-       print_func_entry();
-       struct litevm_vcpu *vcpu = ctxt->vcpu;
-       void *data = val;
-
-       while (bytes) {
-               gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);
-               unsigned offset = addr & (PAGE_SIZE - 1);
-               unsigned tocopy = bytes < (unsigned)PAGE_SIZE - offset ?
-                       bytes : (unsigned)PAGE_SIZE - offset;
-               unsigned long pfn;
-               struct litevm_memory_slot *memslot;
-               void *page;
-
-               if (gpa == UNMAPPED_GVA) {
-                       print_func_exit();
-                       return X86EMUL_PROPAGATE_FAULT;
-               }
-               pfn = gpa >> PAGE_SHIFT;
-               memslot = gfn_to_memslot(vcpu->litevm, pfn);
-               if (!memslot) {
-                       print_func_exit();
-                       return X86EMUL_UNHANDLEABLE;
-               }
-               page = page2kva(gfn_to_page(memslot, pfn));
-
-               memcpy(data, page + offset, tocopy);
-
-               bytes -= tocopy;
-               data += tocopy;
-               addr += tocopy;
-       }
-
-       print_func_exit();
-       return X86EMUL_CONTINUE;
-}
-
-static int emulator_write_std(unsigned long addr,
-                                                         unsigned long val,
-                                                         unsigned int bytes, struct x86_emulate_ctxt *ctxt)
-{
-       print_func_entry();
-       printk("emulator_write_std: addr %lx n %d\n", addr, bytes);
-       print_func_exit();
-       return X86EMUL_UNHANDLEABLE;
-}
-
-static int emulator_read_emulated(unsigned long addr,
-                                                                 unsigned long *val,
-                                                                 unsigned int bytes,
-                                                                 struct x86_emulate_ctxt *ctxt)
-{
-       print_func_entry();
-       struct litevm_vcpu *vcpu = ctxt->vcpu;
-
-       if (vcpu->mmio_read_completed) {
-               memcpy(val, vcpu->mmio_data, bytes);
-               vcpu->mmio_read_completed = 0;
-               print_func_exit();
-               return X86EMUL_CONTINUE;
-       } else if (emulator_read_std(addr, val, bytes, ctxt)
-                          == X86EMUL_CONTINUE) {
-               print_func_exit();
-               return X86EMUL_CONTINUE;
-       } else {
-               gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);
-               if (gpa == UNMAPPED_GVA) {
-                       print_func_exit();
-                       return vcpu_printf(vcpu, "not present\n"), X86EMUL_PROPAGATE_FAULT;
-               }
-               vcpu->mmio_needed = 1;
-               vcpu->mmio_phys_addr = gpa;
-               vcpu->mmio_size = bytes;
-               vcpu->mmio_is_write = 0;
-
-               print_func_exit();
-               return X86EMUL_UNHANDLEABLE;
-       }
-}
-
-static int emulator_write_emulated(unsigned long addr,
-                                                                  unsigned long val,
-                                                                  unsigned int bytes,
-                                                                  struct x86_emulate_ctxt *ctxt)
-{
-       print_func_entry();
-       struct litevm_vcpu *vcpu = ctxt->vcpu;
-       gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr);
-
-       if (gpa == UNMAPPED_GVA) {
-               print_func_exit();
-               return X86EMUL_PROPAGATE_FAULT;
-       }
-
-       vcpu->mmio_needed = 1;
-       vcpu->mmio_phys_addr = gpa;
-       vcpu->mmio_size = bytes;
-       vcpu->mmio_is_write = 1;
-       memcpy(vcpu->mmio_data, &val, bytes);
-
-       print_func_exit();
-       return X86EMUL_CONTINUE;
-}
-
-static int emulator_cmpxchg_emulated(unsigned long addr,
-                                                                        unsigned long old,
-                                                                        unsigned long new,
-                                                                        unsigned int bytes,
-                                                                        struct x86_emulate_ctxt *ctxt)
-{
-       print_func_entry();
-       static int reported;
-
-       if (!reported) {
-               reported = 1;
-               printk("litevm: emulating exchange as write\n");
-       }
-       print_func_exit();
-       return emulator_write_emulated(addr, new, bytes, ctxt);
-}
-
-static void report_emulation_failure(struct x86_emulate_ctxt *ctxt)
-{
-       print_func_entry();
-       static int reported;
-       uint8_t opcodes[4];
-       unsigned long rip = vmcs_readl(GUEST_RIP);
-       unsigned long rip_linear = rip + vmcs_readl(GUEST_CS_BASE);
-
-       if (reported) {
-               print_func_exit();
-               return;
-       }
-
-       emulator_read_std(rip_linear, (void *)opcodes, 4, ctxt);
-
-       printk("emulation failed but !mmio_needed?"
-                  " rip %lx %02x %02x %02x %02x\n",
-                  rip, opcodes[0], opcodes[1], opcodes[2], opcodes[3]);
-       reported = 1;
-       print_func_exit();
-}
-
-struct x86_emulate_ops emulate_ops = {
-       .read_std = emulator_read_std,
-       .write_std = emulator_write_std,
-       .read_emulated = emulator_read_emulated,
-       .write_emulated = emulator_write_emulated,
-       .cmpxchg_emulated = emulator_cmpxchg_emulated,
-};
-
-enum emulation_result {
-       EMULATE_DONE,                           /* no further processing */
-       EMULATE_DO_MMIO,                        /* litevm_run filled with mmio request */
-       EMULATE_FAIL,                           /* can't emulate this instruction */
-};
-
-static int emulate_instruction(struct litevm_vcpu *vcpu,
-                                                          struct litevm_run *run,
-                                                          unsigned long cr2, uint16_t error_code)
-{
-       print_func_entry();
-       struct x86_emulate_ctxt emulate_ctxt;
-       int r;
-       uint32_t cs_ar;
-
-       vcpu_load_rsp_rip(vcpu);
-
-       cs_ar = vmcs_read32(GUEST_CS_AR_BYTES);
-
-       emulate_ctxt.vcpu = vcpu;
-       emulate_ctxt.eflags = vmcs_readl(GUEST_RFLAGS);
-       emulate_ctxt.cr2 = cr2;
-       emulate_ctxt.mode = (emulate_ctxt.eflags & X86_EFLAGS_VM)
-               ? X86EMUL_MODE_REAL : (cs_ar & AR_L_MASK)
-               ? X86EMUL_MODE_PROT64 : (cs_ar & AR_DB_MASK)
-               ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
-
-       if (emulate_ctxt.mode == X86EMUL_MODE_PROT64) {
-               emulate_ctxt.cs_base = 0;
-               emulate_ctxt.ds_base = 0;
-               emulate_ctxt.es_base = 0;
-               emulate_ctxt.ss_base = 0;
-               emulate_ctxt.gs_base = 0;
-               emulate_ctxt.fs_base = 0;
-       } else {
-               emulate_ctxt.cs_base = vmcs_readl(GUEST_CS_BASE);
-               emulate_ctxt.ds_base = vmcs_readl(GUEST_DS_BASE);
-               emulate_ctxt.es_base = vmcs_readl(GUEST_ES_BASE);
-               emulate_ctxt.ss_base = vmcs_readl(GUEST_SS_BASE);
-               emulate_ctxt.gs_base = vmcs_readl(GUEST_GS_BASE);
-               emulate_ctxt.fs_base = vmcs_readl(GUEST_FS_BASE);
-       }
-
-       vcpu->mmio_is_write = 0;
-       r = x86_emulate_memop(&emulate_ctxt, &emulate_ops);
-
-       if ((r || vcpu->mmio_is_write) && run) {
-               run->mmio.phys_addr = vcpu->mmio_phys_addr;
-               memcpy(run->mmio.data, vcpu->mmio_data, 8);
-               run->mmio.len = vcpu->mmio_size;
-               run->mmio.is_write = vcpu->mmio_is_write;
-       }
-
-       if (r) {
-               if (!vcpu->mmio_needed) {
-                       report_emulation_failure(&emulate_ctxt);
-                       print_func_exit();
-                       return EMULATE_FAIL;
-               }
-               print_func_exit();
-               return EMULATE_DO_MMIO;
-       }
-
-       vcpu_put_rsp_rip(vcpu);
-       vmcs_writel(GUEST_RFLAGS, emulate_ctxt.eflags);
-
-       if (vcpu->mmio_is_write) {
-               print_func_exit();
-               return EMULATE_DO_MMIO;
-       }
-
-       print_func_exit();
-       return EMULATE_DONE;
-}
-
-static uint64_t mk_cr_64(uint64_t curr_cr, uint32_t new_val)
-{
-       print_func_entry();
-       print_func_exit();
-       return (curr_cr & ~((1ULL << 32) - 1)) | new_val;
-}
-
-void realmode_lgdt(struct litevm_vcpu *vcpu, uint16_t limit, unsigned long base)
-{
-       print_func_entry();
-       vmcs_writel(GUEST_GDTR_BASE, base);
-       vmcs_write32(GUEST_GDTR_LIMIT, limit);
-       print_func_exit();
-}
-
-void realmode_lidt(struct litevm_vcpu *vcpu, uint16_t limit, unsigned long base)
-{
-       print_func_entry();
-       vmcs_writel(GUEST_IDTR_BASE, base);
-       vmcs_write32(GUEST_IDTR_LIMIT, limit);
-       print_func_exit();
-}
-
-void realmode_lmsw(struct litevm_vcpu *vcpu, unsigned long msw,
-                                  unsigned long *rflags)
-{
-       print_func_entry();
-       lmsw(vcpu, msw);
-       *rflags = vmcs_readl(GUEST_RFLAGS);
-       print_func_exit();
-}
-
-unsigned long realmode_get_cr(struct litevm_vcpu *vcpu, int cr)
-{
-       print_func_entry();
-       switch (cr) {
-               case 0:
-                       print_func_exit();
-                       return guest_cr0();
-               case 2:
-                       print_func_exit();
-                       return vcpu->cr2;
-               case 3:
-                       print_func_exit();
-                       return vcpu->cr3;
-               case 4:
-                       print_func_exit();
-                       return guest_cr4();
-               default:
-                       vcpu_printf(vcpu, "%s: unexpected cr %u\n", __FUNCTION__, cr);
-                       print_func_exit();
-                       return 0;
-       }
-}
-
-void realmode_set_cr(struct litevm_vcpu *vcpu, int cr, unsigned long val,
-                                        unsigned long *rflags)
-{
-       print_func_entry();
-       switch (cr) {
-               case 0:
-                       set_cr0(vcpu, mk_cr_64(guest_cr0(), val));
-                       *rflags = vmcs_readl(GUEST_RFLAGS);
-                       break;
-               case 2:
-                       vcpu->cr2 = val;
-                       break;
-               case 3:
-                       set_cr3(vcpu, val);
-                       break;
-               case 4:
-                       set_cr4(vcpu, mk_cr_64(guest_cr4(), val));
-                       break;
-               default:
-                       vcpu_printf(vcpu, "%s: unexpected cr %u\n", __FUNCTION__, cr);
-       }
-       print_func_exit();
-}
-
-static int handle_rmode_exception(struct litevm_vcpu *vcpu,
-                                                                 int vec, uint32_t err_code)
-{
-       print_func_entry();
-       if (!vcpu->rmode.active) {
-               print_func_exit();
-               return 0;
-       }
-
-       if (vec == GP_VECTOR && err_code == 0)
-               if (emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE) {
-                       print_func_exit();
-                       return 1;
-               }
-       print_func_exit();
-       return 0;
-}
-
-static int handle_exception(struct litevm_vcpu *vcpu,
-                                                       struct litevm_run *litevm_run)
-{
-       print_func_entry();
-       uint32_t intr_info, error_code;
-       unsigned long cr2, rip;
-       uint32_t vect_info;
-       enum emulation_result er;
-
-       vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
-       intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
-printk("vect_info %x intro_info %x\n", vect_info, intr_info);
-printk("page fault? %d\n", is_page_fault(intr_info));
-
-       if ((vect_info & VECTORING_INFO_VALID_MASK) && !is_page_fault(intr_info)) {
-               printk("%s: unexpected, vectoring info 0x%x "
-                          "intr info 0x%x\n", __FUNCTION__, vect_info, intr_info);
-       }
-
-       if (is_external_interrupt(vect_info)) {
-printk("extern interrupt\n");
-               int irq = vect_info & VECTORING_INFO_VECTOR_MASK;
-               SET_BITMASK_BIT_ATOMIC(((uint8_t *) & vcpu->irq_pending), irq);
-               SET_BITMASK_BIT_ATOMIC(((uint8_t *) & vcpu->irq_summary),
-                                                          irq / BITS_PER_LONG);
-       }
-
-       if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) {  /* nmi */
-printk("nmi\n");
-               asm("int $2");
-               print_func_exit();
-               return 1;
-       }
-       error_code = 0;
-       rip = vmcs_readl(GUEST_RIP);
-printk("GUEST_RIP %x\n", rip);
-       if (intr_info & INTR_INFO_DELIVER_CODE_MASK)
-               error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
-       if (is_page_fault(intr_info)) {
-printk("PAGE FAULT!\n");
-               cr2 = vmcs_readl(EXIT_QUALIFICATION);
-
-               SPLL(&vcpu->litevm->lock);
-               if (!vcpu->mmu.page_fault(vcpu, cr2, error_code)) {
-                       SPLU(&vcpu->litevm->lock);
-                       print_func_exit();
-                       return 1;
-               }
-
-               er = emulate_instruction(vcpu, litevm_run, cr2, error_code);
-               SPLU(&vcpu->litevm->lock);
-
-               switch (er) {
-                       case EMULATE_DONE:
-                               print_func_exit();
-                               return 1;
-                       case EMULATE_DO_MMIO:
-                               ++litevm_stat.mmio_exits;
-                               litevm_run->exit_reason = LITEVM_EXIT_MMIO;
-                               print_func_exit();
-                               return 0;
-                       case EMULATE_FAIL:
-                               vcpu_printf(vcpu, "%s: emulate fail\n", __FUNCTION__);
-                               break;
-                       default:
-                               assert(0);
-               }
-       }
-
-       if (vcpu->rmode.active &&
-               handle_rmode_exception(vcpu, intr_info & INTR_INFO_VECTOR_MASK,
-                                                          error_code)) {
-           printk("RMODE EXCEPTION might have been handled\n");
-               print_func_exit();
-               return 1;
-       }
-
-       if ((intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK)) ==
-               (INTR_TYPE_EXCEPTION | 1)) {
-               litevm_run->exit_reason = LITEVM_EXIT_DEBUG;
-               print_func_exit();
-               return 0;
-       }
-       litevm_run->exit_reason = LITEVM_EXIT_EXCEPTION;
-       litevm_run->ex.exception = intr_info & INTR_INFO_VECTOR_MASK;
-       litevm_run->ex.error_code = error_code;
-       print_func_exit();
-       return 0;
-}
-
-static int handle_external_interrupt(struct litevm_vcpu *vcpu,
-                                                                        struct litevm_run *litevm_run)
-{
-       //print_func_entry();
-       ++litevm_stat.irq_exits;
-       //print_func_exit();
-       return 1;
-}
-
-static int get_io_count(struct litevm_vcpu *vcpu, uint64_t * count)
-{
-       print_func_entry();
-       uint64_t inst;
-       gva_t rip;
-       int countr_size;
-       int i, n;
-
-       if ((vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_VM)) {
-               countr_size = 2;
-       } else {
-               uint32_t cs_ar = vmcs_read32(GUEST_CS_AR_BYTES);
-
-               countr_size = (cs_ar & AR_L_MASK) ? 8 : (cs_ar & AR_DB_MASK) ? 4 : 2;
-       }
-
-       rip = vmcs_readl(GUEST_RIP);
-       if (countr_size != 8)
-               rip += vmcs_readl(GUEST_CS_BASE);
-
-       n = litevm_read_guest(vcpu, rip, sizeof(inst), &inst);
-
-       for (i = 0; i < n; i++) {
-               switch (((uint8_t *) & inst)[i]) {
-                       case 0xf0:
-                       case 0xf2:
-                       case 0xf3:
-                       case 0x2e:
-                       case 0x36:
-                       case 0x3e:
-                       case 0x26:
-                       case 0x64:
-                       case 0x65:
-                       case 0x66:
-                               break;
-                       case 0x67:
-                               countr_size = (countr_size == 2) ? 4 : (countr_size >> 1);
-                       default:
-                               goto done;
-               }
-       }
-       print_func_exit();
-       return 0;
-done:
-       countr_size *= 8;
-       *count = vcpu->regs[VCPU_REGS_RCX] & (~0ULL >> (64 - countr_size));
-       print_func_exit();
-       return 1;
-}
-
-static int handle_io(struct litevm_vcpu *vcpu, struct litevm_run *litevm_run)
-{
-       print_func_entry();
-       uint64_t exit_qualification;
-
-       ++litevm_stat.io_exits;
-       exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
-       litevm_run->exit_reason = LITEVM_EXIT_IO;
-       if (exit_qualification & 8)
-               litevm_run->io.direction = LITEVM_EXIT_IO_IN;
-       else
-               litevm_run->io.direction = LITEVM_EXIT_IO_OUT;
-       litevm_run->io.size = (exit_qualification & 7) + 1;
-       litevm_run->io.string = (exit_qualification & 16) != 0;
-       litevm_run->io.string_down
-               = (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_DF) != 0;
-       litevm_run->io.rep = (exit_qualification & 32) != 0;
-       litevm_run->io.port = exit_qualification >> 16;
-       if (litevm_run->io.string) {
-               if (!get_io_count(vcpu, &litevm_run->io.count)) {
-                       print_func_exit();
-                       return 1;
-               }
-               litevm_run->io.address = vmcs_readl(GUEST_LINEAR_ADDRESS);
-       } else
-               litevm_run->io.value = vcpu->regs[VCPU_REGS_RAX];       /* rax */
-       print_func_exit();
-       return 0;
-}
-
-static int handle_invlpg(struct litevm_vcpu *vcpu,
-                                                struct litevm_run *litevm_run)
-{
-       print_func_entry();
-       uint64_t address = vmcs_read64(EXIT_QUALIFICATION);
-       int instruction_length = vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
-       SPLL(&vcpu->litevm->lock);
-       vcpu->mmu.inval_page(vcpu, address);
-       SPLU(&vcpu->litevm->lock);
-       vmcs_writel(GUEST_RIP, vmcs_readl(GUEST_RIP) + instruction_length);
-       print_func_exit();
-       return 1;
-}
-
-static int handle_cr(struct litevm_vcpu *vcpu, struct litevm_run *litevm_run)
-{
-       print_func_entry();
-       uint64_t exit_qualification;
-       int cr;
-       int reg;
-
-#ifdef LITEVM_DEBUG
-       if (guest_cpl() != 0) {
-               vcpu_printf(vcpu, "%s: not supervisor\n", __FUNCTION__);
-               inject_gp(vcpu);
-               print_func_exit();
-               return 1;
-       }
-#endif
-
-       exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
-       cr = exit_qualification & 15;
-       reg = (exit_qualification >> 8) & 15;
-       switch ((exit_qualification >> 4) & 3) {
-               case 0: /* mov to cr */
-                       switch (cr) {
-                               case 0:
-                                       vcpu_load_rsp_rip(vcpu);
-                                       set_cr0(vcpu, vcpu->regs[reg]);
-                                       skip_emulated_instruction(vcpu);
-                                       print_func_exit();
-                                       return 1;
-                               case 3:
-                                       vcpu_load_rsp_rip(vcpu);
-                                       set_cr3(vcpu, vcpu->regs[reg]);
-                                       skip_emulated_instruction(vcpu);
-                                       print_func_exit();
-                                       return 1;
-                               case 4:
-                                       vcpu_load_rsp_rip(vcpu);
-                                       set_cr4(vcpu, vcpu->regs[reg]);
-                                       skip_emulated_instruction(vcpu);
-                                       print_func_exit();
-                                       return 1;
-                               case 8:
-                                       vcpu_load_rsp_rip(vcpu);
-                                       set_cr8(vcpu, vcpu->regs[reg]);
-                                       skip_emulated_instruction(vcpu);
-                                       print_func_exit();
-                                       return 1;
-                       };
-                       break;
-               case 1: /*mov from cr */
-                       switch (cr) {
-                               case 3:
-                                       vcpu_load_rsp_rip(vcpu);
-                                       vcpu->regs[reg] = vcpu->cr3;
-                                       vcpu_put_rsp_rip(vcpu);
-                                       skip_emulated_instruction(vcpu);
-                                       print_func_exit();
-                                       return 1;
-                               case 8:
-                                       printd("handle_cr: read CR8 " "cpu erratum AA15\n");
-                                       vcpu_load_rsp_rip(vcpu);
-                                       vcpu->regs[reg] = vcpu->cr8;
-                                       vcpu_put_rsp_rip(vcpu);
-                                       skip_emulated_instruction(vcpu);
-                                       print_func_exit();
-                                       return 1;
-                       }
-                       break;
-               case 3: /* lmsw */
-                       lmsw(vcpu, (exit_qualification >> LMSW_SOURCE_DATA_SHIFT) & 0x0f);
-
-                       skip_emulated_instruction(vcpu);
-                       print_func_exit();
-                       return 1;
-               default:
-                       break;
-       }
-       litevm_run->exit_reason = 0;
-       printk("litevm: unhandled control register: op %d cr %d\n",
-                  (int)(exit_qualification >> 4) & 3, cr);
-       print_func_exit();
-       return 0;
-}
-
-static int handle_dr(struct litevm_vcpu *vcpu, struct litevm_run *litevm_run)
-{
-       print_func_entry();
-       uint64_t exit_qualification;
-       unsigned long val;
-       int dr, reg;
-
-       /*
-        * FIXME: this code assumes the host is debugging the guest.
-        *        need to deal with guest debugging itself too.
-        */
-       exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
-       dr = exit_qualification & 7;
-       reg = (exit_qualification >> 8) & 15;
-       vcpu_load_rsp_rip(vcpu);
-       if (exit_qualification & 16) {
-               /* mov from dr */
-               switch (dr) {
-                       case 6:
-                               val = 0xffff0ff0;
-                               break;
-                       case 7:
-                               val = 0x400;
-                               break;
-                       default:
-                               val = 0;
-               }
-               vcpu->regs[reg] = val;
-       } else {
-               /* mov to dr */
-       }
-       vcpu_put_rsp_rip(vcpu);
-       skip_emulated_instruction(vcpu);
-       print_func_exit();
-       return 1;
-}
-
-static int handle_cpuid(struct litevm_vcpu *vcpu, struct litevm_run *litevm_run)
-{
-       print_func_entry();
-       litevm_run->exit_reason = LITEVM_EXIT_CPUID;
-       print_func_exit();
-       return 0;
-}
-
-static int handle_rdmsr(struct litevm_vcpu *vcpu, struct litevm_run *litevm_run)
-{
-       print_func_entry();
-       uint32_t ecx = vcpu->regs[VCPU_REGS_RCX];
-       struct vmx_msr_entry *msr = find_msr_entry(vcpu, ecx);
-       uint64_t data;
-
-       if (guest_cpl() != 0) {
-               vcpu_printf(vcpu, "%s: not supervisor\n", __FUNCTION__);
-               inject_gp(vcpu);
-               print_func_exit();
-               return 1;
-       }
-
-       switch (ecx) {
-               case MSR_FS_BASE:
-                       data = vmcs_readl(GUEST_FS_BASE);
-                       break;
-               case MSR_GS_BASE:
-                       data = vmcs_readl(GUEST_GS_BASE);
-                       break;
-               case MSR_IA32_SYSENTER_CS:
-                       data = vmcs_read32(GUEST_SYSENTER_CS);
-                       break;
-               case MSR_IA32_SYSENTER_EIP:
-                       data = vmcs_read32(GUEST_SYSENTER_EIP);
-                       break;
-               case MSR_IA32_SYSENTER_ESP:
-                       data = vmcs_read32(GUEST_SYSENTER_ESP);
-                       break;
-               case MSR_IA32_MC0_CTL:
-               case MSR_IA32_MCG_STATUS:
-               case MSR_IA32_MCG_CAP:
-               case MSR_IA32_MC0_MISC:
-               case MSR_IA32_MC0_MISC + 4:
-               case MSR_IA32_MC0_MISC + 8:
-               case MSR_IA32_MC0_MISC + 12:
-               case MSR_IA32_MC0_MISC + 16:
-               case MSR_IA32_UCODE_REV:
-                       /* MTRR registers */
-               case 0xfe:
-               case 0x200 ... 0x2ff:
-                       data = 0;
-                       break;
-               case MSR_IA32_APICBASE:
-                       data = vcpu->apic_base;
-                       break;
-               default:
-                       if (msr) {
-                               data = msr->value;
-                               break;
-                       }
-                       printk("litevm: unhandled rdmsr: %x\n", ecx);
-                       inject_gp(vcpu);
-                       print_func_exit();
-                       return 1;
-       }
-
-       /* FIXME: handling of bits 32:63 of rax, rdx */
-       vcpu->regs[VCPU_REGS_RAX] = data & -1u;
-       vcpu->regs[VCPU_REGS_RDX] = (data >> 32) & -1u;
-       skip_emulated_instruction(vcpu);
-       print_func_exit();
-       return 1;
-}
-
-#ifdef __x86_64__
-
-static void set_efer(struct litevm_vcpu *vcpu, uint64_t efer)
-{
-       print_func_entry();
-       struct vmx_msr_entry *msr;
-
-       if (efer & EFER_RESERVED_BITS) {
-               printd("set_efer: 0x%llx #GP, reserved bits\n", efer);
-               inject_gp(vcpu);
-               print_func_exit();
-               return;
-       }
-
-       if (is_paging() && (vcpu->shadow_efer & EFER_LME) != (efer & EFER_LME)) {
-               printd("set_efer: #GP, change LME while paging\n");
-               inject_gp(vcpu);
-               print_func_exit();
-               return;
-       }
-
-       efer &= ~EFER_LMA;
-       efer |= vcpu->shadow_efer & EFER_LMA;
-
-       vcpu->shadow_efer = efer;
-
-       msr = find_msr_entry(vcpu, MSR_EFER);
-
-       if (!(efer & EFER_LMA))
-               efer &= ~EFER_LME;
-       msr->value = efer;
-       skip_emulated_instruction(vcpu);
-       print_func_exit();
-}
-
-#endif
-
-#define MSR_IA32_TIME_STAMP_COUNTER 0x10
-
-static int handle_wrmsr(struct litevm_vcpu *vcpu, struct litevm_run *litevm_run)
-{
-       print_func_entry();
-       uint32_t ecx = vcpu->regs[VCPU_REGS_RCX];
-       struct vmx_msr_entry *msr;
-       uint64_t data = (vcpu->regs[VCPU_REGS_RAX] & -1u)
-               | ((uint64_t) (vcpu->regs[VCPU_REGS_RDX] & -1u) << 32);
-
-       if (guest_cpl() != 0) {
-               vcpu_printf(vcpu, "%s: not supervisor\n", __FUNCTION__);
-               inject_gp(vcpu);
-               print_func_exit();
-               return 1;
-       }
-
-       switch (ecx) {
-               case MSR_FS_BASE:
-                       vmcs_writel(GUEST_FS_BASE, data);
-                       break;
-               case MSR_GS_BASE:
-                       vmcs_writel(GUEST_GS_BASE, data);
-                       break;
-               case MSR_IA32_SYSENTER_CS:
-                       vmcs_write32(GUEST_SYSENTER_CS, data);
-                       break;
-               case MSR_IA32_SYSENTER_EIP:
-                       vmcs_write32(GUEST_SYSENTER_EIP, data);
-                       break;
-               case MSR_IA32_SYSENTER_ESP:
-                       vmcs_write32(GUEST_SYSENTER_ESP, data);
-                       break;
-               case MSR_EFER:
-                       set_efer(vcpu, data);
-                       print_func_exit();
-                       return 1;
-               case MSR_IA32_MC0_STATUS:
-                       printk("%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n", __FUNCTION__, data);
-                       break;
-               case MSR_IA32_TIME_STAMP_COUNTER:{
-                               uint64_t tsc;
-
-                               tsc = read_tsc();
-                               vmcs_write64(TSC_OFFSET, data - tsc);
-                               break;
-                       }
-               case MSR_IA32_UCODE_REV:
-               case MSR_IA32_UCODE_WRITE:
-               case 0x200 ... 0x2ff:   /* MTRRs */
-                       break;
-               case MSR_IA32_APICBASE:
-                       vcpu->apic_base = data;
-                       break;
-               default:
-                       msr = find_msr_entry(vcpu, ecx);
-                       if (msr) {
-                               msr->value = data;
-                               break;
-                       }
-                       printk("litevm: unhandled wrmsr: %x\n", ecx);
-                       inject_gp(vcpu);
-                       print_func_exit();
-                       return 1;
-       }
-       skip_emulated_instruction(vcpu);
-       print_func_exit();
-       return 1;
-}
-
-static int handle_interrupt_window(struct litevm_vcpu *vcpu,
-                                                                  struct litevm_run *litevm_run)
-{
-       print_func_entry();
-       /* Turn off interrupt window reporting. */
-       vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
-                                vmcs_read32(CPU_BASED_VM_EXEC_CONTROL)
-                                & ~CPU_BASED_VIRTUAL_INTR_PENDING);
-       print_func_exit();
-       return 1;
-}
-
-static int handle_halt(struct litevm_vcpu *vcpu, struct litevm_run *litevm_run)
-{
-       print_func_entry();
-       skip_emulated_instruction(vcpu);
-       if (vcpu->irq_summary && (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF)) {
-               print_func_exit();
-               return 1;
-       }
-
-       litevm_run->exit_reason = LITEVM_EXIT_HLT;
-       print_func_exit();
-       return 0;
-}
-
-/*
- * The exit handlers return 1 if the exit was handled fully and guest execution
- * may resume.  Otherwise they set the litevm_run parameter to indicate what needs
- * to be done to userspace and return 0.
- */
-static int (*litevm_vmx_exit_handlers[]) (struct litevm_vcpu * vcpu,
-                                                                                 struct litevm_run * litevm_run) = {
-[EXIT_REASON_EXCEPTION_NMI] = handle_exception,
-               [EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt,
-               [EXIT_REASON_IO_INSTRUCTION] = handle_io,
-               [EXIT_REASON_INVLPG] = handle_invlpg,
-               [EXIT_REASON_CR_ACCESS] = handle_cr,
-               [EXIT_REASON_DR_ACCESS] = handle_dr,
-               [EXIT_REASON_CPUID] = handle_cpuid,
-               [EXIT_REASON_MSR_READ] = handle_rdmsr,
-               [EXIT_REASON_MSR_WRITE] = handle_wrmsr,
-               [EXIT_REASON_PENDING_INTERRUPT] = handle_interrupt_window,
-               [EXIT_REASON_HLT] = handle_halt,};
-
-static const int litevm_vmx_max_exit_handlers =
-       sizeof(litevm_vmx_exit_handlers) / sizeof(*litevm_vmx_exit_handlers);
-
-/*
- * The guest has exited.  See if we can fix it or if we need userspace
- * assistance.
- */
-static int litevm_handle_exit(struct litevm_run *litevm_run,
-                                                         struct litevm_vcpu *vcpu)
-{
-       //print_func_entry();
-       uint32_t vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
-       uint32_t exit_reason = vmcs_read32(VM_EXIT_REASON);
-
-//printk("vectoring_info %08x exit_reason %x\n", vectoring_info, exit_reason);
-       if ((vectoring_info & VECTORING_INFO_VALID_MASK) &&
-               exit_reason != EXIT_REASON_EXCEPTION_NMI)
-               printk("%s: unexpected, valid vectoring info and "
-                          "exit reason is 0x%x\n", __FUNCTION__, exit_reason);
-       litevm_run->instruction_length = vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
-       if (exit_reason < litevm_vmx_max_exit_handlers
-               && litevm_vmx_exit_handlers[exit_reason]) {
-//printk("reason is KNOWN\n");
-               //print_func_exit();
-               return litevm_vmx_exit_handlers[exit_reason] (vcpu, litevm_run);
-       } else {
-printk("reason is UNKNOWN\n");
-               litevm_run->exit_reason = LITEVM_EXIT_UNKNOWN;
-               litevm_run->hw.hardware_exit_reason = exit_reason;
-       }
-       //print_func_exit();
-       return 0;
-}
-
-static void inject_rmode_irq(struct litevm_vcpu *vcpu, int irq)
-{
-       print_func_entry();
-       uint16_t ent[2];
-       uint16_t cs;
-       uint16_t ip;
-       unsigned long flags;
-       unsigned long ss_base = vmcs_readl(GUEST_SS_BASE);
-       uint16_t sp = vmcs_readl(GUEST_RSP);
-       uint32_t ss_limit = vmcs_read32(GUEST_SS_LIMIT);
-
-       /* This is the 'does it wrap' test. */
-       /* This original test elicited complaints from the C compiler. 
-        * It's a bit too Klever for me.
-       if (sp > ss_limit || ((sp - 6) > sp)) {
-       */
-       if (sp > ss_limit || (sp < 6)) {
-               vcpu_printf(vcpu, "%s: #SS, rsp 0x%lx ss 0x%lx limit 0x%x\n",
-                                       __FUNCTION__,
-                                       vmcs_readl(GUEST_RSP),
-                                       vmcs_readl(GUEST_SS_BASE), vmcs_read32(GUEST_SS_LIMIT));
-               print_func_exit();
-               return;
-       }
-
-       if (litevm_read_guest(vcpu, irq * sizeof(ent), sizeof(ent), &ent) !=
-               sizeof(ent)) {
-               //vcpu_printf(vcpu, "%s: read guest err\n", __FUNCTION__);
-               print_func_exit();
-               return;
-       }
-
-       flags = vmcs_readl(GUEST_RFLAGS);
-       cs = vmcs_readl(GUEST_CS_BASE) >> 4;
-       ip = vmcs_readl(GUEST_RIP);
-
-       if (litevm_write_guest(vcpu, ss_base + sp - 2, 2, &flags) != 2 ||
-               litevm_write_guest(vcpu, ss_base + sp - 4, 2, &cs) != 2 ||
-               litevm_write_guest(vcpu, ss_base + sp - 6, 2, &ip) != 2) {
-               //vcpu_printf(vcpu, "%s: write guest err\n", __FUNCTION__);
-               print_func_exit();
-               return;
-       }
-
-       vmcs_writel(GUEST_RFLAGS, flags &
-                               ~(X86_EFLAGS_IF | X86_EFLAGS_AC | X86_EFLAGS_TF));
-       vmcs_write16(GUEST_CS_SELECTOR, ent[1]);
-       vmcs_writel(GUEST_CS_BASE, ent[1] << 4);
-       vmcs_writel(GUEST_RIP, ent[0]);
-       vmcs_writel(GUEST_RSP, (vmcs_readl(GUEST_RSP) & ~0xffff) | (sp - 6));
-       print_func_exit();
-}
-
-static void litevm_do_inject_irq(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       int word_index = __ffs(vcpu->irq_summary);
-       int bit_index = __ffs(vcpu->irq_pending[word_index]);
-       int irq = word_index * BITS_PER_LONG + bit_index;
-
-       /* don't have clear_bit and I'm not sure the akaros
-        * bitops are really going to work.
-        */
-       vcpu->irq_pending[word_index] &= ~(1 << bit_index);
-       if (!vcpu->irq_pending[word_index])
-               vcpu->irq_summary &= ~(1 << word_index);
-
-       if (vcpu->rmode.active) {
-               inject_rmode_irq(vcpu, irq);
-               print_func_exit();
-               return;
-       }
-       vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
-                                irq | INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK);
-       print_func_exit();
-}
-
-static void litevm_try_inject_irq(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       if ((vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF)
-               && (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0)
-               /*
-                * Interrupts enabled, and not blocked by sti or mov ss. Good.
-                */
-               litevm_do_inject_irq(vcpu);
-       else
-               /*
-                * Interrupts blocked.  Wait for unblock.
-                */
-               vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
-                                        vmcs_read32(CPU_BASED_VM_EXEC_CONTROL)
-                                        | CPU_BASED_VIRTUAL_INTR_PENDING);
-       print_func_exit();
-}
-
-static void litevm_guest_debug_pre(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       struct litevm_guest_debug *dbg = &vcpu->guest_debug;
-
-/*
-       set_debugreg(dbg->bp[0], 0);
-       set_debugreg(dbg->bp[1], 1);
-       set_debugreg(dbg->bp[2], 2);
-       set_debugreg(dbg->bp[3], 3);
-*/
-
-       if (dbg->singlestep) {
-               unsigned long flags;
-
-               flags = vmcs_readl(GUEST_RFLAGS);
-               flags |= X86_EFLAGS_TF | X86_EFLAGS_RF;
-               vmcs_writel(GUEST_RFLAGS, flags);
-       }
-       print_func_exit();
-}
-
-static void load_msrs(struct vmx_msr_entry *e, int n)
-{
-       //print_func_entry();
-       int i;
-
-       if (! e) {
-               printk("LOAD MSR WITH NULL POINTER?");
-               error("LOAD MSR WITH NULL POINTER?");
-       }
-       for (i = 0; i < n; ++i) {
-               //printk("Load MSR (%lx), with %lx\n", e[i].index, e[i].data);
-               write_msr(e[i].index, e[i].value);
-               //printk("Done\n");
-       }
-       //print_func_exit();
-}
-
-static void save_msrs(struct vmx_msr_entry *e, int n)
-{
-       //print_func_entry();
-       int i;
-
-       for (i = 0; i < n; ++i)
-               e[i].value = read_msr(e[i].index);
-       //print_func_exit();
-}
-
-int vm_run(struct litevm *litevm, struct litevm_run *litevm_run)
-{
-       print_func_entry();
-       struct litevm_vcpu *vcpu;
-       uint8_t fail;
-       uint16_t fs_sel, gs_sel, ldt_sel;
-       int fs_gs_ldt_reload_needed;
-
-       if (litevm_run->vcpu < 0 || litevm_run->vcpu >= LITEVM_MAX_VCPUS)
-               error("vcpu is %d but must be in the range %d..%d\n",
-                         litevm_run->vcpu, LITEVM_MAX_VCPUS);
-
-       vcpu = vcpu_load(litevm, litevm_run->vcpu);
-       if (!vcpu)
-               error("vcpu_load failed");
-       printk("Loaded\n");
-
-       if (litevm_run->emulated) {
-               skip_emulated_instruction(vcpu);
-               litevm_run->emulated = 0;
-       }
-       printk("Emulated\n");
-
-       if (litevm_run->mmio_completed) {
-               memcpy(vcpu->mmio_data, litevm_run->mmio.data, 8);
-               vcpu->mmio_read_completed = 1;
-       }
-       printk("mmio completed\n");
-
-       vcpu->mmio_needed = 0;
-
-again:
-       /*
-        * Set host fs and gs selectors.  Unfortunately, 22.2.3 does not
-        * allow segment selectors with cpl > 0 or ti == 1.
-        */
-       fs_sel = read_fs();
-       //printk("fs_sel %x\n", fs_sel);
-       gs_sel = read_gs();
-       //printk("gs_sel %x\n", gs_sel);
-       ldt_sel = read_ldt();
-       //printk("ldt_sel %x\n", ldt_sel);
-       fs_gs_ldt_reload_needed = (fs_sel & 7) | (gs_sel & 7) | ldt_sel;
-       if (!fs_gs_ldt_reload_needed) {
-               vmcs_write16(HOST_FS_SELECTOR, fs_sel);
-               vmcs_write16(HOST_GS_SELECTOR, gs_sel);
-       } else {
-               vmcs_write16(HOST_FS_SELECTOR, 0);
-               vmcs_write16(HOST_GS_SELECTOR, 0);
-       }
-       //printk("reloaded gs and gs\n");
-
-#ifdef __x86_64__
-       vmcs_writel(HOST_FS_BASE, read_msr(MSR_FS_BASE));
-       vmcs_writel(HOST_GS_BASE, read_msr(MSR_GS_BASE));
-       //printk("Set FS_BASE and GS_BASE");
-#endif
-
-       if (vcpu->irq_summary &&
-               !(vmcs_read32(VM_ENTRY_INTR_INFO_FIELD) & INTR_INFO_VALID_MASK))
-               litevm_try_inject_irq(vcpu);
-
-       if (vcpu->guest_debug.enabled)
-               litevm_guest_debug_pre(vcpu);
-
-       fx_save(vcpu->host_fx_image);
-       fx_restore(vcpu->guest_fx_image);
-
-       save_msrs(vcpu->host_msrs, vcpu->nmsrs);
-       load_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
-
-       printk("GO FOR IT! %08lx\n", vmcs_readl(GUEST_RIP));
-       asm(
-                  /* Store host registers */
-                  "pushf \n\t"
-#ifdef __x86_64__
-                  "push %%rax; push %%rbx; push %%rdx;"
-                  "push %%rsi; push %%rdi; push %%rbp;"
-                  "push %%r8;  push %%r9;  push %%r10; push %%r11;"
-                  "push %%r12; push %%r13; push %%r14; push %%r15;"
-                  "push %%rcx \n\t" "vmwrite %%rsp, %2 \n\t"
-#else
-                  "pusha; push %%ecx \n\t" "vmwrite %%esp, %2 \n\t"
-#endif
-                  /* Check if vmlaunch of vmresume is needed */
-                  "cmp $0, %1 \n\t"
-                  /* Load guest registers.  Don't clobber flags. */
-#ifdef __x86_64__
-                  "mov %c[cr2](%3), %%rax \n\t" "mov %%rax, %%cr2 \n\t" "mov %c[rax](%3), %%rax \n\t" "mov %c[rbx](%3), %%rbx \n\t" "mov %c[rdx](%3), %%rdx \n\t" "mov %c[rsi](%3), %%rsi \n\t" "mov %c[rdi](%3), %%rdi \n\t" "mov %c[rbp](%3), %%rbp \n\t" "mov %c[r8](%3),  %%r8  \n\t" "mov %c[r9](%3),  %%r9  \n\t" "mov %c[r10](%3), %%r10 \n\t" "mov %c[r11](%3), %%r11 \n\t" "mov %c[r12](%3), %%r12 \n\t" "mov %c[r13](%3), %%r13 \n\t" "mov %c[r14](%3), %%r14 \n\t" "mov %c[r15](%3), %%r15 \n\t" "mov %c[rcx](%3), %%rcx \n\t"      /* kills %3 (rcx) */
-#else
-                  "mov %c[cr2](%3), %%eax \n\t" "mov %%eax,   %%cr2 \n\t" "mov %c[rax](%3), %%eax \n\t" "mov %c[rbx](%3), %%ebx \n\t" "mov %c[rdx](%3), %%edx \n\t" "mov %c[rsi](%3), %%esi \n\t" "mov %c[rdi](%3), %%edi \n\t" "mov %c[rbp](%3), %%ebp \n\t" "mov %c[rcx](%3), %%ecx \n\t"    /* kills %3 (ecx) */
-#endif
-                  /* Enter guest mode */
-                  "jne launched \n\t"
-                  "vmlaunch \n\t"
-                  "jmp litevm_vmx_return \n\t"
-                  "launched: vmresume \n\t"
-                  ".globl litevm_vmx_return \n\t" "litevm_vmx_return: "
-                  /* Save guest registers, load host registers, keep flags */
-#ifdef __x86_64__
-                  "xchg %3,     0(%%rsp) \n\t"
-                  "mov %%rax, %c[rax](%3) \n\t"
-                  "mov %%rbx, %c[rbx](%3) \n\t"
-                  "pushq 0(%%rsp); popq %c[rcx](%3) \n\t"
-                  "mov %%rdx, %c[rdx](%3) \n\t"
-                  "mov %%rsi, %c[rsi](%3) \n\t"
-                  "mov %%rdi, %c[rdi](%3) \n\t"
-                  "mov %%rbp, %c[rbp](%3) \n\t"
-                  "mov %%r8,  %c[r8](%3) \n\t"
-                  "mov %%r9,  %c[r9](%3) \n\t"
-                  "mov %%r10, %c[r10](%3) \n\t"
-                  "mov %%r11, %c[r11](%3) \n\t"
-                  "mov %%r12, %c[r12](%3) \n\t"
-                  "mov %%r13, %c[r13](%3) \n\t"
-                  "mov %%r14, %c[r14](%3) \n\t"
-                  "mov %%r15, %c[r15](%3) \n\t"
-                  "mov %%cr2, %%rax   \n\t"
-                  "mov %%rax, %c[cr2](%3) \n\t"
-                  "mov 0(%%rsp), %3 \n\t"
-                  "pop  %%rcx; pop  %%r15; pop  %%r14; pop  %%r13; pop  %%r12;"
-                  "pop  %%r11; pop  %%r10; pop  %%r9;  pop  %%r8;"
-                  "pop  %%rbp; pop  %%rdi; pop  %%rsi;"
-                  "pop  %%rdx; pop  %%rbx; pop  %%rax \n\t"
-#else
-                  "xchg %3, 0(%%esp) \n\t"
-                  "mov %%eax, %c[rax](%3) \n\t"
-                  "mov %%ebx, %c[rbx](%3) \n\t"
-                  "pushl 0(%%esp); popl %c[rcx](%3) \n\t"
-                  "mov %%edx, %c[rdx](%3) \n\t"
-                  "mov %%esi, %c[rsi](%3) \n\t"
-                  "mov %%edi, %c[rdi](%3) \n\t"
-                  "mov %%ebp, %c[rbp](%3) \n\t"
-                  "mov %%cr2, %%eax  \n\t"
-                  "mov %%eax, %c[cr2](%3) \n\t"
-                  "mov 0(%%esp), %3 \n\t" "pop %%ecx; popa \n\t"
-#endif
-"setbe %0 \n\t" "popf \n\t":"=g"(fail)
-:                 "r"(vcpu->launched), "r"((unsigned long)HOST_RSP),
-                  "c"(vcpu),
-                  [rax] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_RAX])),
-                  [rbx] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_RBX])),
-                  [rcx] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_RCX])),
-                  [rdx] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_RDX])),
-                  [rsi] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_RSI])),
-                  [rdi] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_RDI])),
-                  [rbp] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_RBP])),
-#ifdef __x86_64__
-                  [r8] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_R8])),
-                  [r9] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_R9])),
-                  [r10] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_R10])),
-                  [r11] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_R11])),
-                  [r12] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_R12])),
-                  [r13] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_R13])),
-                  [r14] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_R14])),
-                  [r15] "i"(offsetof(struct litevm_vcpu, regs[VCPU_REGS_R15])),
-#endif
-                  [cr2] "i"(offsetof(struct litevm_vcpu, cr2))
-                  :"cc", "memory");
-
-       ++litevm_stat.exits;
-       printk("vm_run exits! %08lx flags %08lx\n", vmcs_readl(GUEST_RIP),
-               vmcs_readl(GUEST_RFLAGS));
-       save_msrs(vcpu->guest_msrs, NR_BAD_MSRS);
-       load_msrs(vcpu->host_msrs, NR_BAD_MSRS);
-
-       fx_save(vcpu->guest_fx_image);
-       fx_restore(vcpu->host_fx_image);
-
-#ifndef __x86_64__
-asm("mov %0, %%ds; mov %0, %%es": :"r"(__USER_DS));
-#endif
-
-       litevm_run->exit_type = 0;
-       if (fail) {
-printk("FAIL\n");
-               litevm_run->exit_type = LITEVM_EXIT_TYPE_FAIL_ENTRY;
-               litevm_run->exit_reason = vmcs_read32(VM_INSTRUCTION_ERROR);
-printk("reason %d\n", litevm_run->exit_reason);
-       } else {
-printk("NOT FAIL\n");
-               if (fs_gs_ldt_reload_needed) {
-                       load_ldt(ldt_sel);
-                       load_fs(fs_sel);
-                       /*
-                        * If we have to reload gs, we must take care to
-                        * preserve our gs base.
-                        */
-                       disable_irq();
-                       load_gs(gs_sel);
-#ifdef __x86_64__
-                       write_msr(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE));
-#endif
-                       enable_irq();
-
-                       reload_tss();
-               }
-               vcpu->launched = 1;
-               litevm_run->exit_type = LITEVM_EXIT_TYPE_VM_EXIT;
-//printk("Let's see why it exited\n");
-               if (litevm_handle_exit(litevm_run, vcpu)) {
-                       /* Give scheduler a change to reschedule. */
-#if 0
-                       vcpu_put(vcpu);
-#warning "how to tell if signal is pending"
-/*
-                       if (signal_pending(current)) {
-                               ++litevm_stat.signal_exits;
-                               return -EINTR;
-                       }
-*/
-                       consider getting rid of this for now. 
-                       Maybe it is just breaking things.
-                       kthread_yield();
-                       /* Cannot fail -  no vcpu unplug yet. */
-                       vcpu_load(litevm, vcpu_slot(vcpu));
-#endif
-                       monitor(NULL);
-                       goto again;
-               }
-       }
-done: 
-
-       printk("vm_run exits! %08lx flags %08lx\n", vmcs_readl(GUEST_RIP),
-               vmcs_readl(GUEST_RFLAGS));
-       vcpu_put(vcpu);
-       printk("vm_run returns\n");
-       print_func_exit();
-       return 0;
-}
-
-static int litevm_dev_ioctl_get_regs(struct litevm *litevm,
-                                                                        struct litevm_regs *regs)
-{
-       print_func_entry();
-       struct litevm_vcpu *vcpu;
-
-       if (regs->vcpu < 0 || regs->vcpu >= LITEVM_MAX_VCPUS) {
-               print_func_exit();
-               return -EINVAL;
-       }
-
-       vcpu = vcpu_load(litevm, regs->vcpu);
-       if (!vcpu) {
-               print_func_exit();
-               return -ENOENT;
-       }
-
-       regs->rax = vcpu->regs[VCPU_REGS_RAX];
-       regs->rbx = vcpu->regs[VCPU_REGS_RBX];
-       regs->rcx = vcpu->regs[VCPU_REGS_RCX];
-       regs->rdx = vcpu->regs[VCPU_REGS_RDX];
-       regs->rsi = vcpu->regs[VCPU_REGS_RSI];
-       regs->rdi = vcpu->regs[VCPU_REGS_RDI];
-       regs->rsp = vmcs_readl(GUEST_RSP);
-       regs->rbp = vcpu->regs[VCPU_REGS_RBP];
-#ifdef __x86_64__
-       regs->r8 = vcpu->regs[VCPU_REGS_R8];
-       regs->r9 = vcpu->regs[VCPU_REGS_R9];
-       regs->r10 = vcpu->regs[VCPU_REGS_R10];
-       regs->r11 = vcpu->regs[VCPU_REGS_R11];
-       regs->r12 = vcpu->regs[VCPU_REGS_R12];
-       regs->r13 = vcpu->regs[VCPU_REGS_R13];
-       regs->r14 = vcpu->regs[VCPU_REGS_R14];
-       regs->r15 = vcpu->regs[VCPU_REGS_R15];
-#endif
-
-       regs->rip = vmcs_readl(GUEST_RIP);
-       regs->rflags = vmcs_readl(GUEST_RFLAGS);
-
-       /*
-        * Don't leak debug flags in case they were set for guest debugging
-        */
-       if (vcpu->guest_debug.enabled && vcpu->guest_debug.singlestep)
-               regs->rflags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF);
-
-       vcpu_put(vcpu);
-
-       print_func_exit();
-       return 0;
-}
-
-static int litevm_dev_ioctl_set_regs(struct litevm *litevm,
-                                                                        struct litevm_regs *regs)
-{
-       print_func_entry();
-       struct litevm_vcpu *vcpu;
-
-       if (regs->vcpu < 0 || regs->vcpu >= LITEVM_MAX_VCPUS) {
-               print_func_exit();
-               return -EINVAL;
-       }
-
-       vcpu = vcpu_load(litevm, regs->vcpu);
-       if (!vcpu) {
-               print_func_exit();
-               return -ENOENT;
-       }
-
-       vcpu->regs[VCPU_REGS_RAX] = regs->rax;
-       vcpu->regs[VCPU_REGS_RBX] = regs->rbx;
-       vcpu->regs[VCPU_REGS_RCX] = regs->rcx;
-       vcpu->regs[VCPU_REGS_RDX] = regs->rdx;
-       vcpu->regs[VCPU_REGS_RSI] = regs->rsi;
-       vcpu->regs[VCPU_REGS_RDI] = regs->rdi;
-       vmcs_writel(GUEST_RSP, regs->rsp);
-       vcpu->regs[VCPU_REGS_RBP] = regs->rbp;
-#ifdef __x86_64__
-       vcpu->regs[VCPU_REGS_R8] = regs->r8;
-       vcpu->regs[VCPU_REGS_R9] = regs->r9;
-       vcpu->regs[VCPU_REGS_R10] = regs->r10;
-       vcpu->regs[VCPU_REGS_R11] = regs->r11;
-       vcpu->regs[VCPU_REGS_R12] = regs->r12;
-       vcpu->regs[VCPU_REGS_R13] = regs->r13;
-       vcpu->regs[VCPU_REGS_R14] = regs->r14;
-       vcpu->regs[VCPU_REGS_R15] = regs->r15;
-#endif
-
-       vmcs_writel(GUEST_RIP, regs->rip);
-       vmcs_writel(GUEST_RFLAGS, regs->rflags);
-
-       vcpu_put(vcpu);
-
-       print_func_exit();
-       return 0;
-}
-
-static int litevm_dev_ioctl_get_sregs(struct litevm *litevm,
-                                                                         struct litevm_sregs *sregs)
-{
-       print_func_entry();
-       struct litevm_vcpu *vcpu;
-
-       if (sregs->vcpu < 0 || sregs->vcpu >= LITEVM_MAX_VCPUS) {
-               print_func_exit();
-               return -EINVAL;
-       }
-       vcpu = vcpu_load(litevm, sregs->vcpu);
-       if (!vcpu) {
-               print_func_exit();
-               return -ENOENT;
-       }
-#define get_segment(var, seg) \
-       do { \
-               uint32_t ar; \
-               \
-               sregs->var.base = vmcs_readl(GUEST_##seg##_BASE); \
-               sregs->var.limit = vmcs_read32(GUEST_##seg##_LIMIT); \
-               sregs->var.selector = vmcs_read16(GUEST_##seg##_SELECTOR); \
-               ar = vmcs_read32(GUEST_##seg##_AR_BYTES); \
-               if (ar & AR_UNUSABLE_MASK) ar = 0; \
-               sregs->var.type = ar & 15; \
-               sregs->var.s = (ar >> 4) & 1; \
-               sregs->var.dpl = (ar >> 5) & 3; \
-               sregs->var.present = (ar >> 7) & 1; \
-               sregs->var.avl = (ar >> 12) & 1; \
-               sregs->var.l = (ar >> 13) & 1; \
-               sregs->var.db = (ar >> 14) & 1; \
-               sregs->var.g = (ar >> 15) & 1; \
-               sregs->var.unusable = (ar >> 16) & 1; \
-       } while (0);
-
-       get_segment(cs, CS);
-       get_segment(ds, DS);
-       get_segment(es, ES);
-       get_segment(fs, FS);
-       get_segment(gs, GS);
-       get_segment(ss, SS);
-
-       get_segment(tr, TR);
-       get_segment(ldt, LDTR);
-#undef get_segment
-
-#define get_dtable(var, table) \
-       sregs->var.limit = vmcs_read32(GUEST_##table##_LIMIT), \
-               sregs->var.base = vmcs_readl(GUEST_##table##_BASE)
-
-       get_dtable(idt, IDTR);
-       get_dtable(gdt, GDTR);
-#undef get_dtable
-
-       sregs->cr0 = guest_cr0();
-       sregs->cr2 = vcpu->cr2;
-       sregs->cr3 = vcpu->cr3;
-       sregs->cr4 = guest_cr4();
-       sregs->cr8 = vcpu->cr8;
-       sregs->efer = vcpu->shadow_efer;
-       sregs->apic_base = vcpu->apic_base;
-
-       sregs->pending_int = vcpu->irq_summary != 0;
-
-       vcpu_put(vcpu);
-
-       print_func_exit();
-       return 0;
-}
-
-static int litevm_dev_ioctl_set_sregs(struct litevm *litevm,
-                                                                         struct litevm_sregs *sregs)
-{
-       print_func_entry();
-       struct litevm_vcpu *vcpu;
-       int mmu_reset_needed = 0;
-
-       if (sregs->vcpu < 0 || sregs->vcpu >= LITEVM_MAX_VCPUS) {
-               print_func_exit();
-               return -EINVAL;
-       }
-       vcpu = vcpu_load(litevm, sregs->vcpu);
-       if (!vcpu) {
-               print_func_exit();
-               return -ENOENT;
-       }
-#define set_segment(var, seg) \
-       do { \
-               uint32_t ar; \
-               \
-               vmcs_writel(GUEST_##seg##_BASE, sregs->var.base);  \
-               vmcs_write32(GUEST_##seg##_LIMIT, sregs->var.limit); \
-               vmcs_write16(GUEST_##seg##_SELECTOR, sregs->var.selector); \
-               if (sregs->var.unusable) { \
-                       ar = (1 << 16); \
-               } else { \
-                       ar = (sregs->var.type & 15); \
-                       ar |= (sregs->var.s & 1) << 4; \
-                       ar |= (sregs->var.dpl & 3) << 5; \
-                       ar |= (sregs->var.present & 1) << 7; \
-                       ar |= (sregs->var.avl & 1) << 12; \
-                       ar |= (sregs->var.l & 1) << 13; \
-                       ar |= (sregs->var.db & 1) << 14; \
-                       ar |= (sregs->var.g & 1) << 15; \
-               } \
-               vmcs_write32(GUEST_##seg##_AR_BYTES, ar); \
-       } while (0);
-
-       set_segment(cs, CS);
-       set_segment(ds, DS);
-       set_segment(es, ES);
-       set_segment(fs, FS);
-       set_segment(gs, GS);
-       set_segment(ss, SS);
-
-       set_segment(tr, TR);
-
-       set_segment(ldt, LDTR);
-#undef set_segment
-
-#define set_dtable(var, table) \
-       vmcs_write32(GUEST_##table##_LIMIT, sregs->var.limit), \
-       vmcs_writel(GUEST_##table##_BASE, sregs->var.base)
-
-       set_dtable(idt, IDTR);
-       set_dtable(gdt, GDTR);
-#undef set_dtable
-
-       vcpu->cr2 = sregs->cr2;
-       mmu_reset_needed |= vcpu->cr3 != sregs->cr3;
-       vcpu->cr3 = sregs->cr3;
-
-       vcpu->cr8 = sregs->cr8;
-
-       mmu_reset_needed |= vcpu->shadow_efer != sregs->efer;
-#ifdef __x86_64__
-       __set_efer(vcpu, sregs->efer);
-#endif
-       vcpu->apic_base = sregs->apic_base;
-
-       mmu_reset_needed |= guest_cr0() != sregs->cr0;
-       vcpu->rmode.active = ((sregs->cr0 & CR0_PE_MASK) == 0);
-       update_exception_bitmap(vcpu);
-       vmcs_writel(CR0_READ_SHADOW, sregs->cr0);
-       vmcs_writel(GUEST_CR0, sregs->cr0 | LITEVM_VM_CR0_ALWAYS_ON);
-
-       mmu_reset_needed |= guest_cr4() != sregs->cr4;
-       __set_cr4(vcpu, sregs->cr4);
-
-       if (mmu_reset_needed)
-               litevm_mmu_reset_context(vcpu);
-       vcpu_put(vcpu);
-
-       print_func_exit();
-       return 0;
-}
-
-/*
- * Translate a guest virtual address to a guest physical address.
- */
-static int litevm_dev_ioctl_translate(struct litevm *litevm,
-                                                                         struct litevm_translation *tr)
-{
-       print_func_entry();
-       unsigned long vaddr = tr->linear_address;
-       struct litevm_vcpu *vcpu;
-       gpa_t gpa;
-
-       vcpu = vcpu_load(litevm, tr->vcpu);
-       if (!vcpu) {
-               print_func_exit();
-               return -ENOENT;
-       }
-       SPLL(&litevm->lock);
-       gpa = vcpu->mmu.gva_to_gpa(vcpu, vaddr);
-       tr->physical_address = gpa;
-       tr->valid = gpa != UNMAPPED_GVA;
-       tr->writeable = 1;
-       tr->usermode = 0;
-       SPLU(&litevm->lock);
-       vcpu_put(vcpu);
-
-       print_func_exit();
-       return 0;
-}
-
-#if 0
-static int litevm_dev_ioctl_interrupt(struct litevm *litevm,
-                                                                         struct litevm_interrupt *irq)
-{
-       struct litevm_vcpu *vcpu;
-
-       if (irq->vcpu < 0 || irq->vcpu >= LITEVM_MAX_VCPUS)
-               return -EINVAL;
-       if (irq->irq < 0 || irq->irq >= 256)
-               return -EINVAL;
-       vcpu = vcpu_load(litevm, irq->vcpu);
-       if (!vcpu)
-               return -ENOENT;
-
-       set_bit(irq->irq, vcpu->irq_pending);
-       set_bit(irq->irq / BITS_PER_LONG, &vcpu->irq_summary);
-
-       vcpu_put(vcpu);
-
-       return 0;
-}
-#endif
-
-#if 0
-static int litevm_dev_ioctl_debug_guest(struct litevm *litevm,
-                                                                               struct litevm_debug_guest *dbg)
-{
-       struct litevm_vcpu *vcpu;
-       unsigned long dr7 = 0x400;
-       uint32_t exception_bitmap;
-       int old_singlestep;
-
-       if (dbg->vcpu < 0 || dbg->vcpu >= LITEVM_MAX_VCPUS)
-               return -EINVAL;
-       vcpu = vcpu_load(litevm, dbg->vcpu);
-       if (!vcpu)
-               return -ENOENT;
-
-       exception_bitmap = vmcs_read32(EXCEPTION_BITMAP);
-       old_singlestep = vcpu->guest_debug.singlestep;
-
-       vcpu->guest_debug.enabled = dbg->enabled;
-       if (vcpu->guest_debug.enabled) {
-               int i;
-
-               dr7 |= 0x200;   /* exact */
-               for (i = 0; i < 4; ++i) {
-                       if (!dbg->breakpoints[i].enabled)
-                               continue;
-                       vcpu->guest_debug.bp[i] = dbg->breakpoints[i].address;
-                       dr7 |= 2 << (i * 2);    /* global enable */
-                       dr7 |= 0 << (i * 4 + 16);       /* execution breakpoint */
-               }
-
-               exception_bitmap |= (1u << 1);  /* Trap debug exceptions */
-
-               vcpu->guest_debug.singlestep = dbg->singlestep;
-       } else {
-               exception_bitmap &= ~(1u << 1); /* Ignore debug exceptions */
-               vcpu->guest_debug.singlestep = 0;
-       }
-
-       if (old_singlestep && !vcpu->guest_debug.singlestep) {
-               unsigned long flags;
-
-               flags = vmcs_readl(GUEST_RFLAGS);
-               flags &= ~(X86_EFLAGS_TF | X86_EFLAGS_RF);
-               vmcs_writel(GUEST_RFLAGS, flags);
-       }
-
-       vmcs_write32(EXCEPTION_BITMAP, exception_bitmap);
-       vmcs_writel(GUEST_DR7, dr7);
-
-       vcpu_put(vcpu);
-
-       return 0;
-}
-#endif
-
-#if 0
-long litevm_control(struct litevm *litevm, int command, unsigned long arg)
-{
-       int r = -EINVAL;
-
-       switch (command) {
-               case LITEVM_CREATE_VCPU:{
-                               r = create_vcpu(litevm, arg);
-                               if (r)
-                                       goto out;
-                               break;
-                       }
-               case LITEVM_RUN:{
-                               struct litevm_run litevm_run;
-
-                               r = -EFAULT;
-                               if (copy_from_user(&litevm_run, (void *)arg, sizeof litevm_run))
-                                       goto out;
-                               r = litevm_dev_ioctl_run(litevm, &litevm_run);
-                               if (r < 0)
-                                       goto out;
-                               r = -EFAULT;
-                               if (copy_to_user((void *)arg, &litevm_run, sizeof litevm_run))
-                                       goto out;
-                               r = 0;
-                               break;
-                       }
-               case LITEVM_GET_REGS:{
-                               struct litevm_regs litevm_regs;
-
-                               r = -EFAULT;
-                               if (copy_from_user
-                                       (&litevm_regs, (void *)arg, sizeof litevm_regs))
-                                       goto out;
-                               r = litevm_dev_ioctl_get_regs(litevm, &litevm_regs);
-                               if (r)
-                                       goto out;
-                               r = -EFAULT;
-                               if (copy_to_user((void *)arg, &litevm_regs, sizeof litevm_regs))
-                                       goto out;
-                               r = 0;
-                               break;
-                       }
-               case LITEVM_SET_REGS:{
-                               struct litevm_regs litevm_regs;
-
-                               r = -EFAULT;
-                               if (copy_from_user
-                                       (&litevm_regs, (void *)arg, sizeof litevm_regs))
-                                       goto out;
-                               r = litevm_dev_ioctl_set_regs(litevm, &litevm_regs);
-                               if (r)
-                                       goto out;
-                               r = 0;
-                               break;
-                       }
-               case LITEVM_GET_SREGS:{
-                               struct litevm_sregs litevm_sregs;
-
-                               r = -EFAULT;
-                               if (copy_from_user
-                                       (&litevm_sregs, (void *)arg, sizeof litevm_sregs))
-                                       goto out;
-                               r = litevm_dev_ioctl_get_sregs(litevm, &litevm_sregs);
-                               if (r)
-                                       goto out;
-                               r = -EFAULT;
-                               if (copy_to_user
-                                       ((void *)arg, &litevm_sregs, sizeof litevm_sregs))
-                                       goto out;
-                               r = 0;
-                               break;
-                       }
-               case LITEVM_SET_SREGS:{
-                               struct litevm_sregs litevm_sregs;
-
-                               r = -EFAULT;
-                               if (copy_from_user
-                                       (&litevm_sregs, (void *)arg, sizeof litevm_sregs))
-                                       goto out;
-                               r = litevm_dev_ioctl_set_sregs(litevm, &litevm_sregs);
-                               if (r)
-                                       goto out;
-                               r = 0;
-                               break;
-                       }
-               case LITEVM_TRANSLATE:{
-                               struct litevm_translation tr;
-
-                               r = -EFAULT;
-                               if (copy_from_user(&tr, (void *)arg, sizeof tr))
-                                       goto out;
-                               r = litevm_dev_ioctl_translate(litevm, &tr);
-                               if (r)
-                                       goto out;
-                               r = -EFAULT;
-                               if (copy_to_user((void *)arg, &tr, sizeof tr))
-                                       goto out;
-                               r = 0;
-                               break;
-                       }
-               case LITEVM_INTERRUPT:{
-                               struct litevm_interrupt irq;
-
-                               r = -EFAULT;
-                               if (copy_from_user(&irq, (void *)arg, sizeof irq))
-                                       goto out;
-                               r = litevm_dev_ioctl_interrupt(litevm, &irq);
-                               if (r)
-                                       goto out;
-                               r = 0;
-                               break;
-                       }
-               case LITEVM_DEBUG_GUEST:{
-                               struct litevm_debug_guest dbg;
-
-                               r = -EFAULT;
-                               if (copy_from_user(&dbg, (void *)arg, sizeof dbg))
-                                       goto out;
-                               r = litevm_dev_ioctl_debug_guest(litevm, &dbg);
-                               if (r)
-                                       goto out;
-                               r = 0;
-                               break;
-                       }
-               case LITEVM_SET_MEMORY_REGION:{
-                               struct litevm_memory_region litevm_mem;
-
-                               r = -EFAULT;
-                               if (copy_from_user(&litevm_mem, (void *)arg, sizeof litevm_mem))
-                                       goto out;
-                               r = litevm_dev_ioctl_set_memory_region(litevm, &litevm_mem);
-                               if (r)
-                                       goto out;
-                               break;
-                       }
-               case LITEVM_GET_DIRTY_LOG:{
-                               struct litevm_dirty_log log;
-
-                               r = -EFAULT;
-                               if (copy_from_user(&log, (void *)arg, sizeof log))
-                                       goto out;
-                               r = litevm_dev_ioctl_get_dirty_log(litevm, &log);
-                               if (r)
-                                       goto out;
-                               break;
-                       }
-               default:
-                       ;
-       }
-out:
-       return r;
-}
-#endif
-
-#if 0
-static int litevm_dev_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-       struct litevm *litevm = vma->vm_file->private_data;
-       struct litevm_memory_slot *slot;
-       struct page *page;
-
-       slot = gfn_to_memslot(litevm, vmf->pgoff);
-       if (!slot)
-               return VM_FAULT_SIGBUS;
-       page = gfn_to_page(slot, vmf->pgoff);
-       if (!page)
-               return VM_FAULT_SIGBUS;
-
-       get_page(page);
-       vmf->page = page;
-       return 0;
-}
-#endif
-
-#if 0
-static int litevm_reboot(struct notifier_block *notifier, unsigned long val,
-                                                void *v)
-{
-       panic("litevm_reboot");
-       if (val == SYS_RESTART) {
-               /*
-                * Some (well, at least mine) BIOSes hang on reboot if
-                * in vmx root mode.
-                */
-               printk("litevm: exiting vmx mode\n");
-               handler_wrapper_t *w;
-               smp_call_function_all(litevm_disable, 0, &w);
-               smp_call_wait(w);
-       }
-       return NOTIFY_OK;
-       return 0;
-}
-#endif
-
-hpa_t bad_page_address;
-
-int vmx_init(void)
-{
-       print_func_entry();
-       handler_wrapper_t *w;
-       int r = 0;
-
-       if (!cpu_has_litevm_support()) {
-               printk("litevm: no hardware support\n");
-               print_func_exit();
-               return -EOPNOTSUPP;
-       }
-       if (vmx_disabled_by_bios()) {
-               printk("litevm: disabled by bios\n");
-               print_func_exit();
-               return -EOPNOTSUPP;
-       }
-
-       setup_vmcs_descriptor();
-       smp_call_function_all(vm_enable, 0, &w);
-       if (smp_call_wait(w)) {
-               printk("litevm_init. smp_call_wait failed. Expect a panic.\n");
-       }
-
-       if ((bad_page_address = PADDR(kpage_zalloc_addr())) == 0ULL) {
-               r = -ENOMEM;
-       }
-
-       print_func_exit();
-       return r;
-}
-
-static void litevm_exit(void)
-{
-       print_func_entry();
-       //free_litevm_area();
-       //__free_page(pfn_to_page(bad_page_address >> PAGE_SHIFT));
-       print_func_exit();
-}
diff --git a/kern/arch/x86/vmx.h b/kern/arch/x86/vmx.h
deleted file mode 100644 (file)
index 10c506e..0000000
+++ /dev/null
@@ -1,545 +0,0 @@
-#ifndef VMX_H
-#define VMX_H
-
-/*
- * vmx.h: VMX Architecture related definitions
- * Copyright (c) 2004, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * A few random additions are:
- * Copyright (C) 2006 Qumranet
- *    Avi Kivity <avi@qumranet.com>
- *    Yaniv Kamay <yaniv@qumranet.com>
- *
- */
-
-#define CPU_BASED_VIRTUAL_INTR_PENDING  0x00000004
-#define CPU_BASED_USE_TSC_OFFSETING     0x00000008
-#define CPU_BASED_HLT_EXITING           0x00000080
-#define CPU_BASED_INVDPG_EXITING        0x00000200
-#define CPU_BASED_MWAIT_EXITING         0x00000400
-#define CPU_BASED_RDPMC_EXITING         0x00000800
-#define CPU_BASED_RDTSC_EXITING         0x00001000
-#define CPU_BASED_CR8_LOAD_EXITING      0x00080000
-#define CPU_BASED_CR8_STORE_EXITING     0x00100000
-#define CPU_BASED_TPR_SHADOW            0x00200000
-#define CPU_BASED_MOV_DR_EXITING        0x00800000
-#define CPU_BASED_UNCOND_IO_EXITING     0x01000000
-#define CPU_BASED_ACTIVATE_IO_BITMAP    0x02000000
-#define CPU_BASED_MSR_BITMAPS           0x10000000
-#define CPU_BASED_MONITOR_EXITING       0x20000000
-#define CPU_BASED_PAUSE_EXITING         0x40000000
-
-/*
- * Definitions of Primary Processor-Based VM-Execution Controls.
- */
-#define CPU_BASED_VIRTUAL_INTR_PENDING          0x00000004
-#define CPU_BASED_USE_TSC_OFFSETING             0x00000008
-#define CPU_BASED_HLT_EXITING                   0x00000080
-#define CPU_BASED_INVLPG_EXITING                0x00000200
-#define CPU_BASED_MWAIT_EXITING                 0x00000400
-#define CPU_BASED_RDPMC_EXITING                 0x00000800
-#define CPU_BASED_RDTSC_EXITING                 0x00001000
-#define CPU_BASED_CR3_LOAD_EXITING             0x00008000
-#define CPU_BASED_CR3_STORE_EXITING            0x00010000
-#define CPU_BASED_CR8_LOAD_EXITING              0x00080000
-#define CPU_BASED_CR8_STORE_EXITING             0x00100000
-#define CPU_BASED_TPR_SHADOW                    0x00200000
-#define CPU_BASED_VIRTUAL_NMI_PENDING          0x00400000
-#define CPU_BASED_MOV_DR_EXITING                0x00800000
-#define CPU_BASED_UNCOND_IO_EXITING             0x01000000
-#define CPU_BASED_USE_IO_BITMAPS                0x02000000
-#define CPU_BASED_USE_MSR_BITMAPS               0x10000000
-#define CPU_BASED_MONITOR_EXITING               0x20000000
-#define CPU_BASED_PAUSE_EXITING                 0x40000000
-#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS   0x80000000
-/*
- * Definitions of Secondary Processor-Based VM-Execution Controls.
- */
-#define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
-#define SECONDARY_EXEC_ENABLE_EPT               0x00000002
-#define SECONDARY_EXEC_RDTSCP                  0x00000008
-#define SECONDARY_EXEC_ENABLE_VPID              0x00000020
-#define SECONDARY_EXEC_WBINVD_EXITING          0x00000040
-#define SECONDARY_EXEC_UNRESTRICTED_GUEST      0x00000080
-#define SECONDARY_EXEC_PAUSE_LOOP_EXITING      0x00000400
-#define SECONDARY_EXEC_ENABLE_INVPCID          0x00001000
-
-
-#define PIN_BASED_EXT_INTR_MASK                 0x00000001
-#define PIN_BASED_NMI_EXITING                   0x00000008
-#define PIN_BASED_VIRTUAL_NMIS                  0x00000020
-
-#define VM_EXIT_SAVE_DEBUG_CONTROLS             0x00000002
-#define VM_EXIT_HOST_ADDR_SPACE_SIZE            0x00000200
-#define VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL      0x00001000
-#define VM_EXIT_ACK_INTR_ON_EXIT                0x00008000
-#define VM_EXIT_SAVE_IA32_PAT                  0x00040000
-#define VM_EXIT_LOAD_IA32_PAT                  0x00080000
-#define VM_EXIT_SAVE_IA32_EFER                  0x00100000
-#define VM_EXIT_LOAD_IA32_EFER                  0x00200000
-#define VM_EXIT_SAVE_VMX_PREEMPTION_TIMER       0x00400000
-
-#define VM_ENTRY_LOAD_DEBUG_CONTROLS            0x00000002
-#define VM_ENTRY_IA32E_MODE                     0x00000200
-#define VM_ENTRY_SMM                            0x00000400
-#define VM_ENTRY_DEACT_DUAL_MONITOR             0x00000800
-#define VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL     0x00002000
-#define VM_ENTRY_LOAD_IA32_PAT                 0x00004000
-#define VM_ENTRY_LOAD_IA32_EFER                 0x00008000
-
-/* VMCS Encodings */
-enum vmcs_field {
-       VIRTUAL_PROCESSOR_ID            = 0x00000000,
-       GUEST_ES_SELECTOR               = 0x00000800,
-       GUEST_CS_SELECTOR               = 0x00000802,
-       GUEST_SS_SELECTOR               = 0x00000804,
-       GUEST_DS_SELECTOR               = 0x00000806,
-       GUEST_FS_SELECTOR               = 0x00000808,
-       GUEST_GS_SELECTOR               = 0x0000080a,
-       GUEST_LDTR_SELECTOR             = 0x0000080c,
-       GUEST_TR_SELECTOR               = 0x0000080e,
-       HOST_ES_SELECTOR                = 0x00000c00,
-       HOST_CS_SELECTOR                = 0x00000c02,
-       HOST_SS_SELECTOR                = 0x00000c04,
-       HOST_DS_SELECTOR                = 0x00000c06,
-       HOST_FS_SELECTOR                = 0x00000c08,
-       HOST_GS_SELECTOR                = 0x00000c0a,
-       HOST_TR_SELECTOR                = 0x00000c0c,
-       IO_BITMAP_A                     = 0x00002000,
-       IO_BITMAP_A_HIGH                = 0x00002001,
-       IO_BITMAP_B                     = 0x00002002,
-       IO_BITMAP_B_HIGH                = 0x00002003,
-       MSR_BITMAP                      = 0x00002004,
-       MSR_BITMAP_HIGH                 = 0x00002005,
-       VM_EXIT_MSR_STORE_ADDR          = 0x00002006,
-       VM_EXIT_MSR_STORE_ADDR_HIGH     = 0x00002007,
-       VM_EXIT_MSR_LOAD_ADDR           = 0x00002008,
-       VM_EXIT_MSR_LOAD_ADDR_HIGH      = 0x00002009,
-       VM_ENTRY_MSR_LOAD_ADDR          = 0x0000200a,
-       VM_ENTRY_MSR_LOAD_ADDR_HIGH     = 0x0000200b,
-       TSC_OFFSET                      = 0x00002010,
-       TSC_OFFSET_HIGH                 = 0x00002011,
-       VIRTUAL_APIC_PAGE_ADDR          = 0x00002012,
-       VIRTUAL_APIC_PAGE_ADDR_HIGH     = 0x00002013,
-       APIC_ACCESS_ADDR                = 0x00002014,
-       APIC_ACCESS_ADDR_HIGH           = 0x00002015,
-       EPT_POINTER                     = 0x0000201a,
-       EPT_POINTER_HIGH                = 0x0000201b,
-       GUEST_PHYSICAL_ADDRESS          = 0x00002400,
-       GUEST_PHYSICAL_ADDRESS_HIGH     = 0x00002401,
-       VMCS_LINK_POINTER               = 0x00002800,
-       VMCS_LINK_POINTER_HIGH          = 0x00002801,
-       GUEST_IA32_DEBUGCTL             = 0x00002802,
-       GUEST_IA32_DEBUGCTL_HIGH        = 0x00002803,
-       GUEST_IA32_PAT                  = 0x00002804,
-       GUEST_IA32_PAT_HIGH             = 0x00002805,
-       GUEST_IA32_EFER                 = 0x00002806,
-       GUEST_IA32_EFER_HIGH            = 0x00002807,
-       GUEST_IA32_PERF_GLOBAL_CTRL     = 0x00002808,
-       GUEST_IA32_PERF_GLOBAL_CTRL_HIGH= 0x00002809,
-       GUEST_PDPTR0                    = 0x0000280a,
-       GUEST_PDPTR0_HIGH               = 0x0000280b,
-       GUEST_PDPTR1                    = 0x0000280c,
-       GUEST_PDPTR1_HIGH               = 0x0000280d,
-       GUEST_PDPTR2                    = 0x0000280e,
-       GUEST_PDPTR2_HIGH               = 0x0000280f,
-       GUEST_PDPTR3                    = 0x00002810,
-       GUEST_PDPTR3_HIGH               = 0x00002811,
-       HOST_IA32_PAT                   = 0x00002c00,
-       HOST_IA32_PAT_HIGH              = 0x00002c01,
-       HOST_IA32_EFER                  = 0x00002c02,
-       HOST_IA32_EFER_HIGH             = 0x00002c03,
-       HOST_IA32_PERF_GLOBAL_CTRL      = 0x00002c04,
-       HOST_IA32_PERF_GLOBAL_CTRL_HIGH = 0x00002c05,
-       PIN_BASED_VM_EXEC_CONTROL       = 0x00004000,
-       CPU_BASED_VM_EXEC_CONTROL       = 0x00004002,
-       EXCEPTION_BITMAP                = 0x00004004,
-       PAGE_FAULT_ERROR_CODE_MASK      = 0x00004006,
-       PAGE_FAULT_ERROR_CODE_MATCH     = 0x00004008,
-       CR3_TARGET_COUNT                = 0x0000400a,
-       VM_EXIT_CONTROLS                = 0x0000400c,
-       VM_EXIT_MSR_STORE_COUNT         = 0x0000400e,
-       VM_EXIT_MSR_LOAD_COUNT          = 0x00004010,
-       VM_ENTRY_CONTROLS               = 0x00004012,
-       VM_ENTRY_MSR_LOAD_COUNT         = 0x00004014,
-       VM_ENTRY_INTR_INFO_FIELD        = 0x00004016,
-       VM_ENTRY_EXCEPTION_ERROR_CODE   = 0x00004018,
-       VM_ENTRY_INSTRUCTION_LEN        = 0x0000401a,
-       TPR_THRESHOLD                   = 0x0000401c,
-       SECONDARY_VM_EXEC_CONTROL       = 0x0000401e,
-       PLE_GAP                         = 0x00004020,
-       PLE_WINDOW                      = 0x00004022,
-       VM_INSTRUCTION_ERROR            = 0x00004400,
-       VM_EXIT_REASON                  = 0x00004402,
-       VM_EXIT_INTR_INFO               = 0x00004404,
-       VM_EXIT_INTR_ERROR_CODE         = 0x00004406,
-       IDT_VECTORING_INFO_FIELD        = 0x00004408,
-       IDT_VECTORING_ERROR_CODE        = 0x0000440a,
-       VM_EXIT_INSTRUCTION_LEN         = 0x0000440c,
-       VMX_INSTRUCTION_INFO            = 0x0000440e,
-       GUEST_ES_LIMIT                  = 0x00004800,
-       GUEST_CS_LIMIT                  = 0x00004802,
-       GUEST_SS_LIMIT                  = 0x00004804,
-       GUEST_DS_LIMIT                  = 0x00004806,
-       GUEST_FS_LIMIT                  = 0x00004808,
-       GUEST_GS_LIMIT                  = 0x0000480a,
-       GUEST_LDTR_LIMIT                = 0x0000480c,
-       GUEST_TR_LIMIT                  = 0x0000480e,
-       GUEST_GDTR_LIMIT                = 0x00004810,
-       GUEST_IDTR_LIMIT                = 0x00004812,
-       GUEST_ES_AR_BYTES               = 0x00004814,
-       GUEST_CS_AR_BYTES               = 0x00004816,
-       GUEST_SS_AR_BYTES               = 0x00004818,
-       GUEST_DS_AR_BYTES               = 0x0000481a,
-       GUEST_FS_AR_BYTES               = 0x0000481c,
-       GUEST_GS_AR_BYTES               = 0x0000481e,
-       GUEST_LDTR_AR_BYTES             = 0x00004820,
-       GUEST_TR_AR_BYTES               = 0x00004822,
-       GUEST_INTERRUPTIBILITY_INFO     = 0x00004824,
-       GUEST_ACTIVITY_STATE            = 0X00004826,
-       GUEST_SYSENTER_CS               = 0x0000482A,
-       HOST_IA32_SYSENTER_CS           = 0x00004c00,
-       CR0_GUEST_HOST_MASK             = 0x00006000,
-       CR4_GUEST_HOST_MASK             = 0x00006002,
-       CR0_READ_SHADOW                 = 0x00006004,
-       CR4_READ_SHADOW                 = 0x00006006,
-       CR3_TARGET_VALUE0               = 0x00006008,
-       CR3_TARGET_VALUE1               = 0x0000600a,
-       CR3_TARGET_VALUE2               = 0x0000600c,
-       CR3_TARGET_VALUE3               = 0x0000600e,
-       EXIT_QUALIFICATION              = 0x00006400,
-       GUEST_LINEAR_ADDRESS            = 0x0000640a,
-       GUEST_CR0                       = 0x00006800,
-       GUEST_CR3                       = 0x00006802,
-       GUEST_CR4                       = 0x00006804,
-       GUEST_ES_BASE                   = 0x00006806,
-       GUEST_CS_BASE                   = 0x00006808,
-       GUEST_SS_BASE                   = 0x0000680a,
-       GUEST_DS_BASE                   = 0x0000680c,
-       GUEST_FS_BASE                   = 0x0000680e,
-       GUEST_GS_BASE                   = 0x00006810,
-       GUEST_LDTR_BASE                 = 0x00006812,
-       GUEST_TR_BASE                   = 0x00006814,
-       GUEST_GDTR_BASE                 = 0x00006816,
-       GUEST_IDTR_BASE                 = 0x00006818,
-       GUEST_DR7                       = 0x0000681a,
-       GUEST_RSP                       = 0x0000681c,
-       GUEST_RIP                       = 0x0000681e,
-       GUEST_RFLAGS                    = 0x00006820,
-       GUEST_PENDING_DBG_EXCEPTIONS    = 0x00006822,
-       GUEST_SYSENTER_ESP              = 0x00006824,
-       GUEST_SYSENTER_EIP              = 0x00006826,
-       HOST_CR0                        = 0x00006c00,
-       HOST_CR3                        = 0x00006c02,
-       HOST_CR4                        = 0x00006c04,
-       HOST_FS_BASE                    = 0x00006c06,
-       HOST_GS_BASE                    = 0x00006c08,
-       HOST_TR_BASE                    = 0x00006c0a,
-       HOST_GDTR_BASE                  = 0x00006c0c,
-       HOST_IDTR_BASE                  = 0x00006c0e,
-       HOST_IA32_SYSENTER_ESP          = 0x00006c10,
-       HOST_IA32_SYSENTER_EIP          = 0x00006c12,
-       HOST_RSP                        = 0x00006c14,
-       HOST_RIP                        = 0x00006c16,
-};
-
-#define VMX_EXIT_REASONS_FAILED_VMENTRY         0x80000000
-
-#define EXIT_REASON_EXCEPTION_NMI       0
-#define EXIT_REASON_EXTERNAL_INTERRUPT  1
-#define EXIT_REASON_TRIPLE_FAULT        2
-
-#define EXIT_REASON_PENDING_INTERRUPT   7
-#define EXIT_REASON_NMI_WINDOW          8
-#define EXIT_REASON_TASK_SWITCH         9
-#define EXIT_REASON_CPUID               10
-#define EXIT_REASON_HLT                 12
-#define EXIT_REASON_INVD                13
-#define EXIT_REASON_INVLPG              14
-#define EXIT_REASON_RDPMC               15
-#define EXIT_REASON_RDTSC               16
-#define EXIT_REASON_VMCALL              18
-#define EXIT_REASON_VMCLEAR             19
-#define EXIT_REASON_VMLAUNCH            20
-#define EXIT_REASON_VMPTRLD             21
-#define EXIT_REASON_VMPTRST             22
-#define EXIT_REASON_VMREAD              23
-#define EXIT_REASON_VMRESUME            24
-#define EXIT_REASON_VMWRITE             25
-#define EXIT_REASON_VMOFF               26
-#define EXIT_REASON_VMON                27
-#define EXIT_REASON_CR_ACCESS           28
-#define EXIT_REASON_DR_ACCESS           29
-#define EXIT_REASON_IO_INSTRUCTION      30
-#define EXIT_REASON_MSR_READ            31
-#define EXIT_REASON_MSR_WRITE           32
-#define EXIT_REASON_INVALID_STATE       33
-#define EXIT_REASON_MWAIT_INSTRUCTION   36
-#define EXIT_REASON_MONITOR_INSTRUCTION 39
-#define EXIT_REASON_PAUSE_INSTRUCTION   40
-#define EXIT_REASON_MCE_DURING_VMENTRY  41
-#define EXIT_REASON_TPR_BELOW_THRESHOLD 43
-#define EXIT_REASON_APIC_ACCESS         44
-#define EXIT_REASON_EPT_VIOLATION       48
-#define EXIT_REASON_EPT_MISCONFIG       49
-#define EXIT_REASON_WBINVD              54
-#define EXIT_REASON_XSETBV              55
-#define EXIT_REASON_INVPCID             58
-
-#define VMX_EXIT_REASONS \
-       { EXIT_REASON_EXCEPTION_NMI,         "EXCEPTION_NMI" }, \
-       { EXIT_REASON_EXTERNAL_INTERRUPT,    "EXTERNAL_INTERRUPT" }, \
-       { EXIT_REASON_TRIPLE_FAULT,          "TRIPLE_FAULT" }, \
-       { EXIT_REASON_PENDING_INTERRUPT,     "PENDING_INTERRUPT" }, \
-       { EXIT_REASON_NMI_WINDOW,            "NMI_WINDOW" }, \
-       { EXIT_REASON_TASK_SWITCH,           "TASK_SWITCH" }, \
-       { EXIT_REASON_CPUID,                 "CPUID" }, \
-       { EXIT_REASON_HLT,                   "HLT" }, \
-       { EXIT_REASON_INVLPG,                "INVLPG" }, \
-       { EXIT_REASON_RDPMC,                 "RDPMC" }, \
-       { EXIT_REASON_RDTSC,                 "RDTSC" }, \
-       { EXIT_REASON_VMCALL,                "VMCALL" }, \
-       { EXIT_REASON_VMCLEAR,               "VMCLEAR" }, \
-       { EXIT_REASON_VMLAUNCH,              "VMLAUNCH" }, \
-       { EXIT_REASON_VMPTRLD,               "VMPTRLD" }, \
-       { EXIT_REASON_VMPTRST,               "VMPTRST" }, \
-       { EXIT_REASON_VMREAD,                "VMREAD" }, \
-       { EXIT_REASON_VMRESUME,              "VMRESUME" }, \
-       { EXIT_REASON_VMWRITE,               "VMWRITE" }, \
-       { EXIT_REASON_VMOFF,                 "VMOFF" }, \
-       { EXIT_REASON_VMON,                  "VMON" }, \
-       { EXIT_REASON_CR_ACCESS,             "CR_ACCESS" }, \
-       { EXIT_REASON_DR_ACCESS,             "DR_ACCESS" }, \
-       { EXIT_REASON_IO_INSTRUCTION,        "IO_INSTRUCTION" }, \
-       { EXIT_REASON_MSR_READ,              "MSR_READ" }, \
-       { EXIT_REASON_MSR_WRITE,             "MSR_WRITE" }, \
-       { EXIT_REASON_MWAIT_INSTRUCTION,     "MWAIT_INSTRUCTION" }, \
-       { EXIT_REASON_MONITOR_INSTRUCTION,   "MONITOR_INSTRUCTION" }, \
-       { EXIT_REASON_PAUSE_INSTRUCTION,     "PAUSE_INSTRUCTION" }, \
-       { EXIT_REASON_MCE_DURING_VMENTRY,    "MCE_DURING_VMENTRY" }, \
-       { EXIT_REASON_TPR_BELOW_THRESHOLD,   "TPR_BELOW_THRESHOLD" }, \
-       { EXIT_REASON_APIC_ACCESS,           "APIC_ACCESS" }, \
-       { EXIT_REASON_EPT_VIOLATION,         "EPT_VIOLATION" }, \
-       { EXIT_REASON_EPT_MISCONFIG,         "EPT_MISCONFIG" }, \
-       { EXIT_REASON_WBINVD,                "WBINVD" }
-
-/*
- * Interruption-information format
- */
-#define INTR_INFO_VECTOR_MASK           0xff            /* 7:0 */
-#define INTR_INFO_INTR_TYPE_MASK        0x700           /* 10:8 */
-#define INTR_INFO_DELIVER_CODE_MASK     0x800           /* 11 */
-#define INTR_INFO_UNBLOCK_NMI          0x1000          /* 12 */
-#define INTR_INFO_VALID_MASK            0x80000000      /* 31 */
-#define INTR_INFO_RESVD_BITS_MASK       0x7ffff000
-
-#define VECTORING_INFO_VECTOR_MASK             INTR_INFO_VECTOR_MASK
-#define VECTORING_INFO_TYPE_MASK               INTR_INFO_INTR_TYPE_MASK
-#define VECTORING_INFO_DELIEVER_CODE_MASK      INTR_INFO_DELIEVER_CODE_MASK
-#define VECTORING_INFO_VALID_MASK              INTR_INFO_VALID_MASK
-
-#define INTR_TYPE_EXT_INTR              (0 << 8) /* external interrupt */
-#define INTR_TYPE_NMI_INTR             (2 << 8) /* NMI */
-#define INTR_TYPE_HARD_EXCEPTION       (3 << 8) /* processor exception */
-#define INTR_TYPE_EXCEPTION             (3 << 8)       /* processor exception */  
-#define INTR_TYPE_SOFT_INTR             (4 << 8) /* software interrupt */
-#define INTR_TYPE_SOFT_EXCEPTION       (6 << 8) /* software exception */
-
-/* GUEST_INTERRUPTIBILITY_INFO flags. */
-#define GUEST_INTR_STATE_STI           0x00000001
-#define GUEST_INTR_STATE_MOV_SS                0x00000002
-#define GUEST_INTR_STATE_SMI           0x00000004
-#define GUEST_INTR_STATE_NMI           0x00000008
-
-/* GUEST_ACTIVITY_STATE flags */
-#define GUEST_ACTIVITY_ACTIVE          0
-#define GUEST_ACTIVITY_HLT             1
-#define GUEST_ACTIVITY_SHUTDOWN                2
-#define GUEST_ACTIVITY_WAIT_SIPI       3
-
-/*
- * Exit Qualifications for MOV for Control Register Access
- */
-#define CONTROL_REG_ACCESS_NUM          0x7    /* 2:0, number of control register */
-#define CONTROL_REG_ACCESS_TYPE         0x30   /* 5:4, access type */
-#define CONTROL_REG_ACCESS_REG          0xf00  /* 10:8, general purpose register */
-#define LMSW_SOURCE_DATA_SHIFT 16
-#define LMSW_SOURCE_DATA  (0xFFFF << LMSW_SOURCE_DATA_SHIFT)   /* 16:31 lmsw source */
-#define REG_EAX                         (0 << 8)
-#define REG_ECX                         (1 << 8)
-#define REG_EDX                         (2 << 8)
-#define REG_EBX                         (3 << 8)
-#define REG_ESP                         (4 << 8)
-#define REG_EBP                         (5 << 8)
-#define REG_ESI                         (6 << 8)
-#define REG_EDI                         (7 << 8)
-#define REG_R8                         (8 << 8)
-#define REG_R9                         (9 << 8)
-#define REG_R10                        (10 << 8)
-#define REG_R11                        (11 << 8)
-#define REG_R12                        (12 << 8)
-#define REG_R13                        (13 << 8)
-#define REG_R14                        (14 << 8)
-#define REG_R15                        (15 << 8)
-
-/*
- * Exit Qualifications for MOV for Debug Register Access
- */
-#define DEBUG_REG_ACCESS_NUM            0x7    /* 2:0, number of debug register */
-#define DEBUG_REG_ACCESS_TYPE           0x10   /* 4, direction of access */
-#define TYPE_MOV_TO_DR                  (0 << 4)
-#define TYPE_MOV_FROM_DR                (1 << 4)
-#define DEBUG_REG_ACCESS_REG(eq)        (((eq) >> 8) & 0xf) /* 11:8, general purpose reg. */
-
-
-/*
- * Exit Qualifications for APIC-Access
- */
-#define APIC_ACCESS_OFFSET              0xfff   /* 11:0, offset within the APIC page */
-#define APIC_ACCESS_TYPE                0xf000  /* 15:12, access type */
-#define TYPE_LINEAR_APIC_INST_READ      (0 << 12)
-#define TYPE_LINEAR_APIC_INST_WRITE     (1 << 12)
-#define TYPE_LINEAR_APIC_INST_FETCH     (2 << 12)
-#define TYPE_LINEAR_APIC_EVENT          (3 << 12)
-#define TYPE_PHYSICAL_APIC_EVENT        (10 << 12)
-#define TYPE_PHYSICAL_APIC_INST         (15 << 12)
-
-/* segment AR */
-#define SEGMENT_AR_L_MASK (1 << 13)
-
-/* entry controls */
-#define VM_ENTRY_CONTROLS_IA32E_MASK (1 << 9)
-
-#define AR_TYPE_ACCESSES_MASK 1
-#define AR_TYPE_READABLE_MASK (1 << 1)
-#define AR_TYPE_WRITEABLE_MASK (1 << 2)
-#define AR_TYPE_CODE_MASK (1 << 3)
-#define AR_TYPE_MASK 0x0f
-#define AR_TYPE_BUSY_64_TSS 11
-#define AR_TYPE_BUSY_32_TSS 11
-#define AR_TYPE_BUSY_16_TSS 3
-#define AR_TYPE_LDT 2
-
-#define AR_UNUSABLE_MASK (1 << 16)
-#define AR_S_MASK (1 << 4)
-#define AR_P_MASK (1 << 7)
-#define AR_L_MASK (1 << 13)
-#define AR_DB_MASK (1 << 14)
-#define AR_G_MASK (1 << 15)
-#define AR_DPL_SHIFT 5
-#define AR_DPL(ar) (((ar) >> AR_DPL_SHIFT) & 3)
-
-#define AR_RESERVD_MASK 0xfffe0f00
-
-#define TSS_PRIVATE_MEMSLOT                    (KVM_MEMORY_SLOTS + 0)
-#define APIC_ACCESS_PAGE_PRIVATE_MEMSLOT       (KVM_MEMORY_SLOTS + 1)
-#define IDENTITY_PAGETABLE_PRIVATE_MEMSLOT     (KVM_MEMORY_SLOTS + 2)
-
-#define VMX_NR_VPIDS                           (1 << 16)
-#define VMX_VPID_EXTENT_SINGLE_CONTEXT         1
-#define VMX_VPID_EXTENT_ALL_CONTEXT            2
-
-#define VMX_EPT_EXTENT_INDIVIDUAL_ADDR         0
-#define VMX_EPT_EXTENT_CONTEXT                 1
-#define VMX_EPT_EXTENT_GLOBAL                  2
-
-#define VMX_EPT_EXECUTE_ONLY_BIT               (1ull)
-#define VMX_EPT_PAGE_WALK_4_BIT                        (1ull << 6)
-#define VMX_EPTP_UC_BIT                                (1ull << 8)
-#define VMX_EPTP_WB_BIT                                (1ull << 14)
-#define VMX_EPT_2MB_PAGE_BIT                   (1ull << 16)
-#define VMX_EPT_1GB_PAGE_BIT                   (1ull << 17)
-#define VMX_EPT_AD_BIT                             (1ull << 21)
-#define VMX_EPT_EXTENT_CONTEXT_BIT             (1ull << 25)
-#define VMX_EPT_EXTENT_GLOBAL_BIT              (1ull << 26)
-
-#define VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT      (1ull << 9) /* (41 - 32) */
-#define VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT      (1ull << 10) /* (42 - 32) */
-
-#define VMX_EPT_DEFAULT_GAW                    3
-#define VMX_EPT_MAX_GAW                                0x4
-#define VMX_EPT_MT_EPTE_SHIFT                  3
-#define VMX_EPT_GAW_EPTP_SHIFT                 3
-#define VMX_EPT_AD_ENABLE_BIT                  (1ull << 6)
-#define VMX_EPT_DEFAULT_MT                     0x6ull
-#define VMX_EPT_READABLE_MASK                  0x1ull
-#define VMX_EPT_WRITABLE_MASK                  0x2ull
-#define VMX_EPT_EXECUTABLE_MASK                        0x4ull
-#define VMX_EPT_IPAT_BIT                       (1ull << 6)
-#define VMX_EPT_ACCESS_BIT                             (1ull << 8)
-#define VMX_EPT_DIRTY_BIT                              (1ull << 9)
-
-#define VMX_EPT_IDENTITY_PAGETABLE_ADDR                0xfffbc000ul
-
-
-#define ASM_VMX_VMCLEAR_RAX       ".byte 0x66, 0x0f, 0xc7, 0x30"
-#define ASM_VMX_VMLAUNCH          ".byte 0x0f, 0x01, 0xc2"
-#define ASM_VMX_VMRESUME          ".byte 0x0f, 0x01, 0xc3"
-#define ASM_VMX_VMPTRLD_RAX       ".byte 0x0f, 0xc7, 0x30"
-#define ASM_VMX_VMREAD_RDX_RAX    ".byte 0x0f, 0x78, 0xd0"
-#define ASM_VMX_VMWRITE_RAX_RDX   ".byte 0x0f, 0x79, 0xd0"
-#define ASM_VMX_VMWRITE_RSP_RDX   ".byte 0x0f, 0x79, 0xd4"
-#define ASM_VMX_VMXOFF            ".byte 0x0f, 0x01, 0xc4"
-#define ASM_VMX_VMXON_RAX         ".byte 0xf3, 0x0f, 0xc7, 0x30"
-#define ASM_VMX_INVEPT           ".byte 0x66, 0x0f, 0x38, 0x80, 0x08"
-#define ASM_VMX_INVVPID                  ".byte 0x66, 0x0f, 0x38, 0x81, 0x08"
-
-struct vmx_msr_entry {
-       uint32_t index;
-       uint32_t reserved;
-       uint64_t value;
-} __attribute__((aligned(16))) ;
-
-/*
- * Exit Qualifications for entry failure during or after loading guest state
- */
-#define ENTRY_FAIL_DEFAULT             0
-#define ENTRY_FAIL_PDPTE               2
-#define ENTRY_FAIL_NMI                 3
-#define ENTRY_FAIL_VMCS_LINK_PTR       4
-
-/*
- * VM-instruction error numbers
- */
-enum vm_instruction_error_number {
-       VMXERR_VMCALL_IN_VMX_ROOT_OPERATION = 1,
-       VMXERR_VMCLEAR_INVALID_ADDRESS = 2,
-       VMXERR_VMCLEAR_VMXON_POINTER = 3,
-       VMXERR_VMLAUNCH_NONCLEAR_VMCS = 4,
-       VMXERR_VMRESUME_NONLAUNCHED_VMCS = 5,
-       VMXERR_VMRESUME_AFTER_VMXOFF = 6,
-       VMXERR_ENTRY_INVALID_CONTROL_FIELD = 7,
-       VMXERR_ENTRY_INVALID_HOST_STATE_FIELD = 8,
-       VMXERR_VMPTRLD_INVALID_ADDRESS = 9,
-       VMXERR_VMPTRLD_VMXON_POINTER = 10,
-       VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID = 11,
-       VMXERR_UNSUPPORTED_VMCS_COMPONENT = 12,
-       VMXERR_VMWRITE_READ_ONLY_VMCS_COMPONENT = 13,
-       VMXERR_VMXON_IN_VMX_ROOT_OPERATION = 15,
-       VMXERR_ENTRY_INVALID_EXECUTIVE_VMCS_POINTER = 16,
-       VMXERR_ENTRY_NONLAUNCHED_EXECUTIVE_VMCS = 17,
-       VMXERR_ENTRY_EXECUTIVE_VMCS_POINTER_NOT_VMXON_POINTER = 18,
-       VMXERR_VMCALL_NONCLEAR_VMCS = 19,
-       VMXERR_VMCALL_INVALID_VM_EXIT_CONTROL_FIELDS = 20,
-       VMXERR_VMCALL_INCORRECT_MSEG_REVISION_ID = 22,
-       VMXERR_VMXOFF_UNDER_DUAL_MONITOR_TREATMENT_OF_SMIS_AND_SMM = 23,
-       VMXERR_VMCALL_INVALID_SMM_MONITOR_FEATURES = 24,
-       VMXERR_ENTRY_INVALID_VM_EXECUTION_CONTROL_FIELDS_IN_EXECUTIVE_VMCS = 25,
-       VMXERR_ENTRY_EVENTS_BLOCKED_BY_MOV_SS = 26,
-       VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID = 28,
-};
-
-#endif
diff --git a/kern/arch/x86/vmx_mmu.c b/kern/arch/x86/vmx_mmu.c
deleted file mode 100644 (file)
index b65fc12..0000000
+++ /dev/null
@@ -1,842 +0,0 @@
-/*
- * 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.
- *
- * MMU support
- *
- * Copyright (C) 2006 Qumranet, Inc.
- *
- * Authors:
- *   Yaniv Kamay  <yaniv@qumranet.com>
- *   Avi Kivity   <avi@qumranet.com>
- *
- */
-#define DEBUG
-#include <kmalloc.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <error.h>
-#include <pmap.h>
-#include <sys/queue.h>
-#include <smp.h>
-#include <kref.h>
-#include <atomic.h>
-#include <alarm.h>
-#include <event.h>
-#include <umem.h>
-#include <devalarm.h>
-#include <arch/types.h>
-#include <arch/vm.h>
-#include <arch/emulate.h>
-#include <arch/vmdebug.h>
-#include <arch/msr-index.h>
-
-#define pgprintk(x...) do { } while (0)
-
-#define ASSERT(x)                                                      \
-       if (!(x)) {                                                     \
-               printd( "assertion failed %s:%d: %s\n", \
-                      __FILE__, __LINE__, #x);                         \
-       }
-
-#define PT64_ENT_PER_PAGE 512
-#define PT32_ENT_PER_PAGE 1024
-
-#define PT_WRITABLE_SHIFT 1
-
-#define PT_PRESENT_MASK (1ULL << 0)
-#define PT_WRITABLE_MASK (1ULL << PT_WRITABLE_SHIFT)
-#define PT_USER_MASK (1ULL << 2)
-#define PT_PWT_MASK (1ULL << 3)
-#define PT_PCD_MASK (1ULL << 4)
-#define PT_ACCESSED_MASK (1ULL << 5)
-#define PT_DIRTY_MASK (1ULL << 6)
-#define PT_PAGE_SIZE_MASK (1ULL << 7)
-#define PT_PAT_MASK (1ULL << 7)
-#define PT_GLOBAL_MASK (1ULL << 8)
-#define PT64_NX_MASK (1ULL << 63)
-
-#define PT_PAT_SHIFT 7
-#define PT_DIR_PAT_SHIFT 12
-#define PT_DIR_PAT_MASK (1ULL << PT_DIR_PAT_SHIFT)
-
-#define PT32_DIR_PSE36_SIZE 4
-#define PT32_DIR_PSE36_SHIFT 13
-#define PT32_DIR_PSE36_MASK (((1ULL << PT32_DIR_PSE36_SIZE) - 1) << PT32_DIR_PSE36_SHIFT)
-
-#define PT32_PTE_COPY_MASK \
-       (PT_PRESENT_MASK | PT_PWT_MASK | PT_PCD_MASK | \
-       PT_ACCESSED_MASK | PT_DIRTY_MASK | PT_PAT_MASK | \
-       PT_GLOBAL_MASK )
-
-#define PT32_NON_PTE_COPY_MASK \
-       (PT_PRESENT_MASK | PT_PWT_MASK | PT_PCD_MASK | \
-       PT_ACCESSED_MASK | PT_DIRTY_MASK)
-
-#define PT64_PTE_COPY_MASK \
-       (PT64_NX_MASK | PT32_PTE_COPY_MASK)
-
-#define PT64_NON_PTE_COPY_MASK \
-       (PT64_NX_MASK | PT32_NON_PTE_COPY_MASK)
-
-#define PT_FIRST_AVAIL_BITS_SHIFT 9
-#define PT64_SECOND_AVAIL_BITS_SHIFT 52
-
-#define PT_SHADOW_PS_MARK (1ULL << PT_FIRST_AVAIL_BITS_SHIFT)
-#define PT_SHADOW_IO_MARK (1ULL << PT_FIRST_AVAIL_BITS_SHIFT)
-
-#define PT_SHADOW_WRITABLE_SHIFT (PT_FIRST_AVAIL_BITS_SHIFT + 1)
-#define PT_SHADOW_WRITABLE_MASK (1ULL << PT_SHADOW_WRITABLE_SHIFT)
-
-#define PT_SHADOW_USER_SHIFT (PT_SHADOW_WRITABLE_SHIFT + 1)
-#define PT_SHADOW_USER_MASK (1ULL << (PT_SHADOW_USER_SHIFT))
-
-#define PT_SHADOW_BITS_OFFSET (PT_SHADOW_WRITABLE_SHIFT - PT_WRITABLE_SHIFT)
-
-#define VALID_PAGE(x) ((x) != INVALID_PAGE)
-
-#define PT64_LEVEL_BITS 9
-
-#define PT64_LEVEL_SHIFT(level) \
-               ( PAGE_SHIFT + (level - 1) * PT64_LEVEL_BITS )
-
-#define PT64_LEVEL_MASK(level) \
-               (((1ULL << PT64_LEVEL_BITS) - 1) << PT64_LEVEL_SHIFT(level))
-
-#define PT64_INDEX(address, level)\
-       (((address) >> PT64_LEVEL_SHIFT(level)) & ((1 << PT64_LEVEL_BITS) - 1))
-
-#define PT32_LEVEL_BITS 10
-
-#define PT32_LEVEL_SHIFT(level) \
-               ( PAGE_SHIFT + (level - 1) * PT32_LEVEL_BITS )
-
-#define PT32_LEVEL_MASK(level) \
-               (((1ULL << PT32_LEVEL_BITS) - 1) << PT32_LEVEL_SHIFT(level))
-
-#define PT32_INDEX(address, level)\
-       (((address) >> PT32_LEVEL_SHIFT(level)) & ((1 << PT32_LEVEL_BITS) - 1))
-
-#define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & PAGE_MASK)
-#define PT64_DIR_BASE_ADDR_MASK \
-       (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + PT64_LEVEL_BITS)) - 1))
-
-#define PT32_BASE_ADDR_MASK PAGE_MASK
-#define PT32_DIR_BASE_ADDR_MASK \
-       (PAGE_MASK & ~((1ULL << (PAGE_SHIFT + PT32_LEVEL_BITS)) - 1))
-
-#define PFERR_PRESENT_MASK (1U << 0)
-#define PFERR_WRITE_MASK (1U << 1)
-#define PFERR_USER_MASK (1U << 2)
-
-#define PT64_ROOT_LEVEL 4
-#define PT32_ROOT_LEVEL 2
-#define PT32E_ROOT_LEVEL 3
-
-#define PT_DIRECTORY_LEVEL 2
-#define PT_PAGE_TABLE_LEVEL 1
-
-static int is_write_protection(void)
-{
-       print_func_entry();
-       print_func_exit();
-       return guest_cr0() & CR0_WP_MASK;
-}
-
-static int is_cpuid_PSE36(void)
-{
-       print_func_entry();
-       print_func_exit();
-       return 1;
-}
-
-static int is_present_pte(unsigned long pte)
-{
-       //print_func_entry();
-       //print_func_exit();
-       return pte & PT_PRESENT_MASK;
-}
-
-static int is_writeble_pte(unsigned long pte)
-{
-       //print_func_entry();
-       //print_func_exit();
-       return pte & PT_WRITABLE_MASK;
-}
-
-static int is_io_pte(unsigned long pte)
-{
-       //print_func_entry();
-       //print_func_exit();
-       return pte & PT_SHADOW_IO_MARK;
-}
-
-static void litevm_mmu_free_page(struct litevm_vcpu *vcpu, hpa_t page_hpa)
-{
-       print_func_entry();
-       struct litevm_mmu_page *page_head = page_header(page_hpa);
-
-       LIST_REMOVE(page_head, link);
-       //list_del(&page_head->link);
-       page_head->page_hpa = page_hpa;
-       //list_add(&page_head->link, &vcpu->free_pages);
-       LIST_INSERT_HEAD(&vcpu->link, page_head, link);
-       print_func_exit();
-}
-
-static int is_empty_shadow_page(hpa_t page_hpa)
-{
-       print_func_entry();
-       uint32_t *pos;
-       uint32_t *end;
-       for (pos = KADDR(page_hpa), end = pos + PAGE_SIZE / sizeof(uint32_t);
-                pos != end; pos++)
-               if (*pos != 0) {
-                       print_func_exit();
-                       return 0;
-               }
-       print_func_exit();
-       return 1;
-}
-
-static hpa_t litevm_mmu_alloc_page(struct litevm_vcpu *vcpu,
-                                                                  uint64_t * parent_pte)
-{
-       print_func_entry();
-       struct litevm_mmu_page *page;
-
-       if (LIST_EMPTY(&vcpu->link)) {
-               print_func_exit();
-               return INVALID_PAGE;
-       }
-
-       page = LIST_FIRST(&vcpu->link);
-       LIST_REMOVE(page, link);
-       LIST_INSERT_HEAD(&vcpu->litevm->link, page, link);
-       ASSERT(is_empty_shadow_page(page->page_hpa));
-       page->slot_bitmap = 0;
-       page->global = 1;
-       page->parent_pte = parent_pte;
-       print_func_exit();
-       return page->page_hpa;
-}
-
-static void page_header_update_slot(struct litevm *litevm, void *pte, gpa_t gpa)
-{
-       print_func_entry();
-       int slot = memslot_id(litevm, gfn_to_memslot(litevm, gpa >> PAGE_SHIFT));
-       struct litevm_mmu_page *page_head = page_header(PADDR(pte));
-
-       SET_BITMASK_BIT_ATOMIC((uint8_t *) & page_head->slot_bitmap, slot);
-       print_func_exit();
-}
-
-hpa_t safe_gpa_to_hpa(struct litevm_vcpu *vcpu, gpa_t gpa)
-{
-       print_func_entry();
-       hpa_t hpa = gpa_to_hpa(vcpu, gpa);
-
-       print_func_exit();
-       return is_error_hpa(hpa) ? bad_page_address | (gpa & ~PAGE_MASK) : hpa;
-}
-
-hpa_t gpa_to_hpa(struct litevm_vcpu * vcpu, gpa_t gpa)
-{
-       print_func_entry();
-       struct litevm_memory_slot *slot;
-       struct page *page;
-
-       ASSERT((gpa & HPA_ERR_MASK) == 0);
-       slot = gfn_to_memslot(vcpu->litevm, gpa >> PAGE_SHIFT);
-       printk("GFN %016lx memslot %p\n", gpa>>PAGE_SHIFT, slot);
-       if (!slot) {
-               printk("GFN_TO_MEMSLOT FAILED!\n");
-               print_func_exit();
-               return gpa | HPA_ERR_MASK;
-       }
-       page = gfn_to_page(slot, gpa >> PAGE_SHIFT);
-       printk("Page is %p\n", page);
-       print_func_exit();
-       printk("gpa_to_hpa: return %016lx\n",  ((hpa_t) page2ppn(page) << PAGE_SHIFT)
-               | (gpa & (PAGE_SIZE - 1)));
-       return ((hpa_t) page2ppn(page) << PAGE_SHIFT)
-               | (gpa & (PAGE_SIZE - 1));
-}
-
-hpa_t gva_to_hpa(struct litevm_vcpu * vcpu, gva_t gva)
-{
-       print_func_entry();
-       gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, gva);
-
-       if (gpa == UNMAPPED_GVA) {
-               print_func_exit();
-               return UNMAPPED_GVA;
-       }
-       print_func_exit();
-       return gpa_to_hpa(vcpu, gpa);
-}
-
-static void release_pt_page_64(struct litevm_vcpu *vcpu, hpa_t page_hpa,
-                                                          int level)
-{
-       print_func_entry();
-       ASSERT(vcpu);
-       ASSERT(VALID_PAGE(page_hpa));
-       ASSERT(level <= PT64_ROOT_LEVEL && level > 0);
-
-       if (level == 1)
-               memset(KADDR(page_hpa), 0, PAGE_SIZE);
-       else {
-               uint64_t *pos;
-               uint64_t *end;
-
-               for (pos = KADDR(page_hpa), end = pos + PT64_ENT_PER_PAGE;
-                        pos != end; pos++) {
-                       uint64_t current_ent = *pos;
-
-                       *pos = 0;
-                       if (is_present_pte(current_ent))
-                               release_pt_page_64(vcpu,
-                                                                  current_ent &
-                                                                  PT64_BASE_ADDR_MASK, level - 1);
-               }
-       }
-       litevm_mmu_free_page(vcpu, page_hpa);
-       print_func_exit();
-}
-
-static void nonpaging_new_cr3(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       print_func_exit();
-}
-
-static int nonpaging_map(struct litevm_vcpu *vcpu, gva_t v, hpa_t p)
-{
-       print_func_entry();
-       int level = PT32E_ROOT_LEVEL;
-       hpa_t table_addr = vcpu->mmu.root_hpa;
-printk("nonpaging_map: v %016lx, p %016lx\n", v, p);
-hexdump(KADDR(p), 32);
-
-       for (;; level--) {
-               uint32_t index = PT64_INDEX(v, level);
-               uint64_t *table;
-
-               ASSERT(VALID_PAGE(table_addr));
-               table = KADDR(table_addr);
-
-               if (level == 1) {
-                       mark_page_dirty(vcpu->litevm, v >> PAGE_SHIFT);
-                       page_header_update_slot(vcpu->litevm, table, v);
-                       table[index] = p | PT_PRESENT_MASK | PT_WRITABLE_MASK |
-                               PT_USER_MASK;
-                       print_func_exit();
-                       return 0;
-               }
-
-               if (table[index] == 0) {
-                       hpa_t new_table = litevm_mmu_alloc_page(vcpu, &table[index]);
-
-                       if (!VALID_PAGE(new_table)) {
-                               pgprintk("nonpaging_map: ENOMEM\n");
-                               print_func_exit();
-                               return -ENOMEM;
-                       }
-
-                       if (level == PT32E_ROOT_LEVEL)
-                               table[index] = new_table | PT_PRESENT_MASK;
-                       else
-                               table[index] = new_table | PT_PRESENT_MASK |
-                                       PT_WRITABLE_MASK | PT_USER_MASK;
-               }
-               table_addr = table[index] & PT64_BASE_ADDR_MASK;
-       }
-       print_func_exit();
-}
-
-static void nonpaging_flush(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       hpa_t root = vcpu->mmu.root_hpa;
-
-       ++litevm_stat.tlb_flush;
-       pgprintk("nonpaging_flush\n");
-       ASSERT(VALID_PAGE(root));
-       release_pt_page_64(vcpu, root, vcpu->mmu.shadow_root_level);
-       root = litevm_mmu_alloc_page(vcpu, 0);
-       ASSERT(VALID_PAGE(root));
-       vcpu->mmu.root_hpa = root;
-       if (is_paging())
-               root |= (vcpu->cr3 & (CR3_PCD_MASK | CR3_WPT_MASK));
-       vmcs_writel(GUEST_CR3, root);
-       print_func_exit();
-}
-
-static gpa_t nonpaging_gva_to_gpa(struct litevm_vcpu *vcpu, gva_t vaddr)
-{
-       print_func_entry();
-       print_func_exit();
-       return vaddr;
-}
-
-static int nonpaging_page_fault(struct litevm_vcpu *vcpu, gva_t gva,
-                                                               uint32_t error_code)
-{
-       print_func_entry();
-       int ret;
-       gpa_t addr = gva;
-
-printk("nonpaging_page_fault: %016llx\n", gva);
-       ASSERT(vcpu);
-       ASSERT(VALID_PAGE(vcpu->mmu.root_hpa));
-
-       for (;;) {
-               hpa_t paddr;
-
-               paddr = gpa_to_hpa(vcpu, addr & PT64_BASE_ADDR_MASK);
-
-               if (is_error_hpa(paddr)) {
-                       print_func_exit();
-                       return 1;
-               }
-
-               ret = nonpaging_map(vcpu, addr & PAGE_MASK, paddr);
-               if (ret) {
-                       nonpaging_flush(vcpu);
-                       continue;
-               }
-               break;
-       }
-       print_func_exit();
-       return ret;
-}
-
-static void nonpaging_inval_page(struct litevm_vcpu *vcpu, gva_t addr)
-{
-       print_func_entry();
-       print_func_exit();
-}
-
-static void nonpaging_free(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       hpa_t root;
-
-       ASSERT(vcpu);
-       root = vcpu->mmu.root_hpa;
-       if (VALID_PAGE(root))
-               release_pt_page_64(vcpu, root, vcpu->mmu.shadow_root_level);
-       vcpu->mmu.root_hpa = INVALID_PAGE;
-       print_func_exit();
-}
-
-static int nonpaging_init_context(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       struct litevm_mmu *context = &vcpu->mmu;
-
-       context->new_cr3 = nonpaging_new_cr3;
-       context->page_fault = nonpaging_page_fault;
-       context->inval_page = nonpaging_inval_page;
-       context->gva_to_gpa = nonpaging_gva_to_gpa;
-       context->free = nonpaging_free;
-       context->root_level = PT32E_ROOT_LEVEL;
-       context->shadow_root_level = PT32E_ROOT_LEVEL;
-       context->root_hpa = litevm_mmu_alloc_page(vcpu, 0);
-       ASSERT(VALID_PAGE(context->root_hpa));
-       vmcs_writel(GUEST_CR3, context->root_hpa);
-       print_func_exit();
-       return 0;
-}
-
-static void litevm_mmu_flush_tlb(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       struct litevm_mmu_page *page, *npage;
-
-       //list_for_each_entry_safe(page, npage, &vcpu->litevm->active_mmu_pages,
-       LIST_FOREACH_SAFE(page, &vcpu->litevm->link, link, npage) {
-               if (page->global)
-                       continue;
-
-               if (!page->parent_pte)
-                       continue;
-
-               *page->parent_pte = 0;
-               release_pt_page_64(vcpu, page->page_hpa, 1);
-       }
-       ++litevm_stat.tlb_flush;
-       print_func_exit();
-}
-
-static void paging_new_cr3(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       litevm_mmu_flush_tlb(vcpu);
-       print_func_exit();
-}
-
-static void mark_pagetable_nonglobal(void *shadow_pte)
-{
-       print_func_entry();
-       page_header(PADDR(shadow_pte))->global = 0;
-       print_func_exit();
-}
-
-static inline void set_pte_common(struct litevm_vcpu *vcpu,
-                                                                 uint64_t * shadow_pte,
-                                                                 gpa_t gaddr, int dirty, uint64_t access_bits)
-{
-       print_func_entry();
-       hpa_t paddr;
-
-       *shadow_pte |= access_bits << PT_SHADOW_BITS_OFFSET;
-       if (!dirty)
-               access_bits &= ~PT_WRITABLE_MASK;
-
-       if (access_bits & PT_WRITABLE_MASK)
-               mark_page_dirty(vcpu->litevm, gaddr >> PAGE_SHIFT);
-
-       *shadow_pte |= access_bits;
-
-       paddr = gpa_to_hpa(vcpu, gaddr & PT64_BASE_ADDR_MASK);
-
-       if (!(*shadow_pte & PT_GLOBAL_MASK))
-               mark_pagetable_nonglobal(shadow_pte);
-
-       if (is_error_hpa(paddr)) {
-               *shadow_pte |= gaddr;
-               *shadow_pte |= PT_SHADOW_IO_MARK;
-               *shadow_pte &= ~PT_PRESENT_MASK;
-       } else {
-               *shadow_pte |= paddr;
-               page_header_update_slot(vcpu->litevm, shadow_pte, gaddr);
-       }
-       print_func_exit();
-}
-
-static void inject_page_fault(struct litevm_vcpu *vcpu,
-                                                         uint64_t addr, uint32_t err_code)
-{
-       print_func_entry();
-       uint32_t vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
-
-       pgprintk("inject_page_fault: 0x%llx err 0x%x\n", addr, err_code);
-
-       ++litevm_stat.pf_guest;
-
-       if (is_page_fault(vect_info)) {
-               printd("inject_page_fault: "
-                          "double fault 0x%llx @ 0x%lx\n", addr, vmcs_readl(GUEST_RIP));
-               vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, 0);
-               vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
-                                        DF_VECTOR |
-                                        INTR_TYPE_EXCEPTION |
-                                        INTR_INFO_DELIVER_CODE_MASK | INTR_INFO_VALID_MASK);
-               print_func_exit();
-               return;
-       }
-       vcpu->cr2 = addr;
-       vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, err_code);
-       vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
-                                PF_VECTOR |
-                                INTR_TYPE_EXCEPTION |
-                                INTR_INFO_DELIVER_CODE_MASK | INTR_INFO_VALID_MASK);
-
-       print_func_exit();
-}
-
-static inline int fix_read_pf(uint64_t * shadow_ent)
-{
-       print_func_entry();
-       if ((*shadow_ent & PT_SHADOW_USER_MASK) && !(*shadow_ent & PT_USER_MASK)) {
-               /*
-                * If supervisor write protect is disabled, we shadow kernel
-                * pages as user pages so we can trap the write access.
-                */
-               *shadow_ent |= PT_USER_MASK;
-               *shadow_ent &= ~PT_WRITABLE_MASK;
-
-               print_func_exit();
-               return 1;
-
-       }
-       print_func_exit();
-       return 0;
-}
-
-static int may_access(uint64_t pte, int write, int user)
-{
-       print_func_entry();
-
-       if (user && !(pte & PT_USER_MASK)) {
-               print_func_exit();
-               return 0;
-       }
-       if (write && !(pte & PT_WRITABLE_MASK)) {
-               print_func_exit();
-               return 0;
-       }
-       print_func_exit();
-       return 1;
-}
-
-/*
- * Remove a shadow pte.
- */
-static void paging_inval_page(struct litevm_vcpu *vcpu, gva_t addr)
-{
-       print_func_entry();
-       hpa_t page_addr = vcpu->mmu.root_hpa;
-       int level = vcpu->mmu.shadow_root_level;
-
-printk("paging_inval_page: addr %016lx\n", addr);
-       ++litevm_stat.invlpg;
-
-       for (;; level--) {
-               uint32_t index = PT64_INDEX(addr, level);
-               uint64_t *table = KADDR(page_addr);
-
-               if (level == PT_PAGE_TABLE_LEVEL) {
-                       table[index] = 0;
-                       print_func_exit();
-                       return;
-               }
-
-               if (!is_present_pte(table[index])) {
-                       print_func_exit();
-                       return;
-               }
-
-               page_addr = table[index] & PT64_BASE_ADDR_MASK;
-
-               if (level == PT_DIRECTORY_LEVEL && (table[index] & PT_SHADOW_PS_MARK)) {
-                       table[index] = 0;
-                       release_pt_page_64(vcpu, page_addr, PT_PAGE_TABLE_LEVEL);
-
-                       //flush tlb
-                       vmcs_writel(GUEST_CR3, vcpu->mmu.root_hpa |
-                                               (vcpu->cr3 & (CR3_PCD_MASK | CR3_WPT_MASK)));
-                       print_func_exit();
-                       return;
-               }
-       }
-       print_func_exit();
-}
-
-static void paging_free(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       nonpaging_free(vcpu);
-       print_func_exit();
-}
-
-#define PTTYPE 64
-#include "paging_tmpl.h"
-#undef PTTYPE
-
-#define PTTYPE 32
-#include "paging_tmpl.h"
-#undef PTTYPE
-
-static int paging64_init_context(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       struct litevm_mmu *context = &vcpu->mmu;
-
-       ASSERT(is_pae());
-       context->new_cr3 = paging_new_cr3;
-       context->page_fault = paging64_page_fault;
-       context->inval_page = paging_inval_page;
-       context->gva_to_gpa = paging64_gva_to_gpa;
-       context->free = paging_free;
-       context->root_level = PT64_ROOT_LEVEL;
-       context->shadow_root_level = PT64_ROOT_LEVEL;
-       context->root_hpa = litevm_mmu_alloc_page(vcpu, 0);
-       ASSERT(VALID_PAGE(context->root_hpa));
-       vmcs_writel(GUEST_CR3, context->root_hpa |
-                               (vcpu->cr3 & (CR3_PCD_MASK | CR3_WPT_MASK)));
-       print_func_exit();
-       return 0;
-}
-
-static int paging32_init_context(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       struct litevm_mmu *context = &vcpu->mmu;
-
-       context->new_cr3 = paging_new_cr3;
-       context->page_fault = paging32_page_fault;
-       context->inval_page = paging_inval_page;
-       context->gva_to_gpa = paging32_gva_to_gpa;
-       context->free = paging_free;
-       context->root_level = PT32_ROOT_LEVEL;
-       context->shadow_root_level = PT32E_ROOT_LEVEL;
-       context->root_hpa = litevm_mmu_alloc_page(vcpu, 0);
-       ASSERT(VALID_PAGE(context->root_hpa));
-       vmcs_writel(GUEST_CR3, context->root_hpa |
-                               (vcpu->cr3 & (CR3_PCD_MASK | CR3_WPT_MASK)));
-       print_func_exit();
-       return 0;
-}
-
-static int paging32E_init_context(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       int ret;
-
-       if ((ret = paging64_init_context(vcpu))) {
-               print_func_exit();
-               return ret;
-       }
-
-       vcpu->mmu.root_level = PT32E_ROOT_LEVEL;
-       vcpu->mmu.shadow_root_level = PT32E_ROOT_LEVEL;
-       print_func_exit();
-       return 0;
-}
-
-static int init_litevm_mmu(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       ASSERT(vcpu);
-       ASSERT(!VALID_PAGE(vcpu->mmu.root_hpa));
-
-       if (!is_paging()) {
-               print_func_exit();
-               return nonpaging_init_context(vcpu);
-       } else if (is_long_mode()) {
-               print_func_exit();
-               return paging64_init_context(vcpu);
-       } else if (is_pae()) {
-               print_func_exit();
-               return paging32E_init_context(vcpu);
-       } else {
-               print_func_exit();
-               return paging32_init_context(vcpu);
-       }
-}
-
-static void destroy_litevm_mmu(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       ASSERT(vcpu);
-       if (VALID_PAGE(vcpu->mmu.root_hpa)) {
-               vcpu->mmu.free(vcpu);
-               vcpu->mmu.root_hpa = INVALID_PAGE;
-       }
-       print_func_exit();
-}
-
-int litevm_mmu_reset_context(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       destroy_litevm_mmu(vcpu);
-       print_func_exit();
-       return init_litevm_mmu(vcpu);
-}
-
-static void free_mmu_pages(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       /* todo: use the right macros */
-       while (!LIST_EMPTY(&vcpu->link)) {
-               struct litevm_mmu_page *vmpage;
-               vmpage = LIST_FIRST(&vcpu->link);
-               LIST_REMOVE(vmpage, link);
-               uintptr_t ppn = vmpage->page_hpa >> PAGE_SHIFT;
-               page_decref(ppn2page(ppn));
-               assert(page_is_free(ppn));
-               vmpage->page_hpa = INVALID_PAGE;
-       }
-       print_func_exit();
-}
-
-static int alloc_mmu_pages(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       int i;
-
-       ASSERT(vcpu);
-
-       /* we could try to do the contiguous alloc but it's not
-        * necessary for them to be contiguous.
-        */
-       for (i = 0; i < LITEVM_NUM_MMU_PAGES; i++) {
-               struct page *page;
-               struct litevm_mmu_page *page_header = &vcpu->page_header_buf[i];
-
-               if (kpage_alloc(&page) != ESUCCESS)
-                       goto error_1;
-               page->pg_private = page_header;
-               page_header->page_hpa = (hpa_t) page2pa(page);
-               memset(KADDR(page_header->page_hpa), 0, PAGE_SIZE);
-               LIST_INSERT_HEAD(&vcpu->link, page_header, link);
-       }
-       print_func_exit();
-       return 0;
-
-error_1:
-       free_mmu_pages(vcpu);
-       print_func_exit();
-       return -ENOMEM;
-}
-
-int litevm_mmu_init(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       int r;
-
-       ASSERT(vcpu);
-       ASSERT(!VALID_PAGE(vcpu->mmu.root_hpa));
-       ASSERT(LIST_EMPTY(&vcpu->link));
-
-       if ((r = alloc_mmu_pages(vcpu))) {
-               print_func_exit();
-               return r;
-       }
-
-       if ((r = init_litevm_mmu(vcpu))) {
-               free_mmu_pages(vcpu);
-               print_func_exit();
-               return r;
-       }
-       print_func_exit();
-       return 0;
-}
-
-void litevm_mmu_destroy(struct litevm_vcpu *vcpu)
-{
-       print_func_entry();
-       ASSERT(vcpu);
-
-       destroy_litevm_mmu(vcpu);
-       free_mmu_pages(vcpu);
-       print_func_exit();
-}
-
-void litevm_mmu_slot_remove_write_access(struct litevm *litevm, int slot)
-{
-       print_func_entry();
-       struct litevm_mmu_page *page, *link;
-
-       LIST_FOREACH(page, &litevm->link, link) {
-               int i;
-               uint64_t *pt;
-
-               if (!GET_BITMASK_BIT((uint8_t *) & page->slot_bitmap, slot))
-                       continue;
-
-               pt = KADDR(page->page_hpa);
-               for (i = 0; i < PT64_ENT_PER_PAGE; ++i)
-                       /* avoid RMW */
-                       if (pt[i] & PT_WRITABLE_MASK)
-                               pt[i] &= ~PT_WRITABLE_MASK;
-
-       }
-       print_func_exit();
-}
index 0b9dd7a..6a40e30 100644 (file)
@@ -12,6 +12,4 @@ obj-$(CONFIG_REGRESS)                         += regress.o
 obj-y                                          += root.o
 obj-y                                          += srv.o
 
-# VM support. Optional.
-obj-$(CONFIG_VM)                               += vm.o
 obj-$(CONFIG_NIX)                              += nix.o
index 47cc0fa..e2651df 100644 (file)
@@ -73,7 +73,6 @@
 #include <devalarm.h>
 #include <arch/types.h>
 #include <arch/emulate.h>
-#include <arch/vmdebug.h>
 #include <kdebug.h>
 #include <bitmap.h>
 
diff --git a/kern/drivers/dev/vm.c b/kern/drivers/dev/vm.c
deleted file mode 100644 (file)
index 67b3924..0000000
+++ /dev/null
@@ -1,564 +0,0 @@
-//#define DEBUG
-/* Copyright 2014 Google Inc.
- * Copyright (c) 2013 The Regents of the University of California
- * Barret Rhoden <brho@cs.berkeley.edu>
- * See LICENSE for details.
- *
- * devvm/#V: a device for VMs
- *
- */
-
-#include <kmalloc.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <error.h>
-#include <pmap.h>
-#include <sys/queue.h>
-#include <smp.h>
-#include <kref.h>
-#include <atomic.h>
-#include <alarm.h>
-#include <event.h>
-#include <umem.h>
-#include <devalarm.h>
-#include <arch/types.h>
-#include <arch/vm.h>
-#include <arch/emulate.h>
-#include <arch/vmdebug.h>
-
-/* qid path types */
-enum {
-       Qtopdir = 1,
-       Qclone,
-       Qstat,
-       Qvmdir,
-       Qctl,
-       Qimage,
-};
-
-/* The QID is the TYPE and the index into the vms array.
- * We reserve the right to make it an id later.
- */
-#define ID_SHIFT 5
-/* vm's have an image.
- * Note that the image can be read even as it is running. */
-struct vm {
-       struct kref kref;
-       /* should this be an array of pages? Hmm. */
-       void *image;
-       unsigned long imagesize;
-       int id; // not used yet. 
-       struct litevm *archvm;
-};
-
-static spinlock_t vmlock;
-/* array, not linked list. We expect few, might as well be cache friendly. */
-static struct vm *vms = NULL;
-static int nvm = 0;
-static int vmok = 0;
-
-static spinlock_t vmidlock[1];
-static struct kref vmid[1] = { {(void *)1, fake_release} };
-
-/* not clear what .h to put these in. Put them here. */
-
-struct litevm *vmx_open(void);
-int vmx_create_vcpu(struct litevm *litevm, int n);
-int vmx_init(void);
-int vm_set_memory_region(struct litevm *litevm,
-                                                struct litevm_memory_region *mem);
-int vm_run(struct litevm *litevm, struct litevm_run *litevm_run);
-
-static inline struct vm *
-QID2VM(struct qid q)
-{
-       return &vms[((q).path >> ID_SHIFT)];
-}
-
-static inline int 
-TYPE(struct qid q)
-{
-       return ((q).path & ((1 << ID_SHIFT) - 1));
-}
-
-static inline int QID(int index, int type)
-{
-       return ((index << ID_SHIFT) | type);
-}
-
-/* we'll need this somewhere more generic. */
-static void readn(struct chan *c, void *vp, long n)
-{
-       //print_func_entry();
-       char *p;
-       long nn;
-       int total = 0, want = n;
-
-       p = vp;
-       while (n > 0) {
-               nn = devtab[c->type].read(c, p, n, c->offset);
-               printk("readn: Got %d@%lld\n", nn, c->offset);
-               if (nn == 0)
-                       error("%s: wanted %d, got %d", Eshort, want, total);
-               c->offset += nn;
-               p += nn;
-               n -= nn;
-               total += nn;
-       }
-       //print_func_exit();
-}
-
-/* not called yet.  -- we have to unlink the vm */
-static void vm_release(struct kref *kref)
-{
-       //print_func_entry();
-       struct vm *v = container_of(kref, struct vm, kref);
-       spin_lock_irqsave(&vmlock);
-       /* cute trick. Save the last element of the array in place of the
-        * one we're deleting. Reduce nvm. Don't realloc; that way, next
-        * time we add a vm the allocator will just return.
-        * Well, this is stupid, because when we do this, we break
-        * the QIDs, which have pointers embedded in them.
-        * darn it, may have to use a linked list. Nope, will probably
-        * just walk the array until we find a matching id. Still ... yuck.
-        */
-       if (v != &vms[nvm - 1]) {
-               /* free the image ... oops */
-               /* get rid of the kref. */
-               *v = vms[nvm - 1];
-       }
-       nvm--;
-       spin_unlock(&vmlock);
-       //print_func_exit();
-}
-
-/* VM ids run in the range 1..infinity. But vmx.c wants them
- * 0-based.
- */
-static int newvmid(void)
-{
-       //print_func_entry();
-       int id;
-       spin_lock_irqsave(vmidlock);
-       id = kref_refcnt(vmid);
-       kref_get(vmid, 1);
-       spin_unlock(vmidlock);
-       //print_func_exit();
-       return id - 1;
-}
-
-static int vmgen(struct chan *c, char *entry_name,
-                                struct dirtab *unused, int unused_nr_dirtab,
-                                int s, struct dir *dp)
-{
-       //print_func_entry();
-       struct qid q;
-       struct vm *vm_i;
-       printd("GEN s %d\n", s);
-       /* Whether we're in one dir or at the top, .. still takes us to the top. */
-       if (s == DEVDOTDOT) {
-               mkqid(&q, Qtopdir, 0, QTDIR);
-               devdir(c, c->qid, "#V", 0, eve, 0555, dp);
-               //print_func_exit();
-               return 1;
-       }
-       printd("TYPE %d\n", TYPE(c->qid));
-       switch (TYPE(c->qid)) {
-               case Qtopdir:
-                       printd("Qtopdir s %d nvm %d\n", s, nvm);
-                       /* Generate elements for the top level dir.  We support clone, stat,
-                        * vm dirs at the top level */
-                       if (s == 0) {
-                               mkqid(&q, Qclone, 0, QTFILE);
-                               devdir(c, q, "clone", 0, eve, 0666, dp);
-                               //print_func_exit();
-                               return 1;
-                       }
-                       s--;
-                       if (s == 0) {
-                               mkqid(&q, Qstat, 0, QTFILE);
-                               devdir(c, q, "stat", 0, eve, 0666, dp);
-                               //print_func_exit();
-                               return 1;
-                       }
-                       s--;    /* 1 -> 0th element, 2 -> 1st element, etc */
-                       spin_lock_irqsave(&vmlock);
-                       if (s >= nvm) {
-                               printd("DONE qtopdir\n");
-                               spin_unlock(&vmlock);
-                               //print_func_exit();
-                               return -1;
-                       }
-                       vm_i = &vms[s];
-                       snprintf(get_cur_genbuf(), GENBUF_SZ, "vm%d", vm_i->id);
-                       spin_unlock(&vmlock);
-                       mkqid(&q, QID(s, Qvmdir), 0, QTDIR);
-                       devdir(c, q, get_cur_genbuf(), 0, eve, 0555, dp);
-                       //print_func_exit();
-                       return 1;
-               case Qvmdir:
-                       /* Gen the contents of the vm dirs */
-                       s += Qctl;      /* first time through, start on Qctl */
-                       switch (s) {
-                               case Qctl:
-                                       mkqid(&q, QID(s-Qctl, Qctl), 0, QTFILE);
-                                       devdir(c, q, "ctl", 0, eve, 0666, dp);
-                                       //print_func_exit();
-                                       return 1;
-                               case Qimage:
-                                       mkqid(&q, QID(s-Qctl, Qimage), 0, QTFILE);
-                                       devdir(c, q, "image", 0, eve, 0666, dp);
-                                       //print_func_exit();
-                                       return 1;
-                       }
-                       //print_func_exit();
-                       return -1;
-                       /* Need to also provide a direct hit for Qclone and all other files
-                        * (at all levels of the hierarchy).  Every file is both generated
-                        * (via the s increments in their respective directories) and
-                        * directly gen-able.  devstat() will call gen with a specific path
-                        * in the qid.  In these cases, we make a dir for whatever they are
-                        * asking for.  Note the qid stays the same.  I think this is what
-                        * the old plan9 comments above devgen were talking about for (ii).
-                        *
-                        * We don't need to do this for the directories - devstat will look
-                        * for the a directory by path and fail.  Then it will manually
-                        * build the stat output (check the -1 case in devstat). */
-               case Qclone:
-                       devdir(c, c->qid, "clone", 0, eve, 0666, dp);
-                       //print_func_exit();
-                       return 1;
-               case Qstat:
-                       devdir(c, c->qid, "stat", 0, eve, 0444, dp);
-                       //print_func_exit();
-                       return 1;
-               case Qctl:
-                       devdir(c, c->qid, "ctl", 0, eve, 0666, dp);
-                       //print_func_exit();
-                       return 1;
-               case Qimage:
-                       devdir(c, c->qid, "image", 0, eve, 0666, dp);
-                       //print_func_exit();
-                       return 1;
-       }
-       //print_func_exit();
-       return -1;
-}
-
-static void vminit(void)
-{
-       //print_func_entry();
-       int i;
-       spinlock_init_irqsave(&vmlock);
-       spinlock_init_irqsave(vmidlock);
-       i = vmx_init();
-       if (i == 0)
-               vmok = 1;
-       printk("vminit: litevm_init returns %d\n", i);
-
-       //print_func_exit();
-}
-
-static struct chan *vmattach(char *spec)
-{
-       //print_func_entry();
-       if (!vmok)
-               error("No VMs available");
-       struct chan *c = devattach('V', spec);
-       mkqid(&c->qid, Qtopdir, 0, QTDIR);
-       //print_func_exit();
-       return c;
-}
-
-static struct walkqid *vmwalk(struct chan *c, struct chan *nc, char **name,
-                                                         int nname)
-{
-       //print_func_entry();
-       //print_func_exit();
-       return devwalk(c, nc, name, nname, 0, 0, vmgen);
-}
-
-static int vmstat(struct chan *c, uint8_t * db, int n)
-{
-       //print_func_entry();
-       //print_func_exit();
-       return devstat(c, db, n, 0, 0, vmgen);
-}
-
-/* It shouldn't matter if p = current is DYING.  We'll eventually fail to insert
- * the open chan into p's fd table, then decref the chan. */
-static struct chan *vmopen(struct chan *c, int omode)
-{
-       //print_func_entry();
-       ERRSTACK(1);
-       struct vm *v = QID2VM(c->qid);
-       printk("vmopen: v is %p\n", v);
-       if (waserror()) {
-               nexterror();
-       }
-       switch (TYPE(c->qid)) {
-               case Qtopdir:
-               case Qvmdir:
-                       if (omode & ORCLOSE)
-                               error(Eperm);
-                       if (!IS_RDONLY(omode))
-                               error(Eisdir);
-                       break;
-               case Qclone:
-                       spin_lock_irqsave(&vmlock);
-                       vms = krealloc(vms, sizeof(vms[0]) * (nvm + 1), 0);
-                       v = &vms[nvm];
-                       nvm++;
-                       spin_unlock(&vmlock);
-                       kref_init(&v->kref, vm_release, 1);
-                       v->id = newvmid();
-                       mkqid(&c->qid, QID(nvm, Qctl), 0, QTFILE);
-                       c->aux = v;
-                       printd("New VM id %d\n", v->id);
-                       v->archvm = vmx_open();
-                       if (!v->archvm) {
-                               printk("vm_open failed\n");
-                               error("vm_open failed");
-                       }
-                       if (vmx_create_vcpu(v->archvm, v->id) < 0) {
-                               printk("vm_create failed");
-                               error("vm_create failed");
-                       }
-                       printk("Qclone open: id %d, v is %p, v->archvm is %p\n", 
-                                       nvm-1,
-                                       v, v->archvm);
-                       break;
-               case Qstat:
-                       break;
-               case Qctl:
-               case Qimage:
-                       c->aux = QID2VM(c->qid);
-                       printk("open qctl: aux (vm) is %p\n", c->aux);
-                       break;
-       }
-       c->mode = openmode(omode);
-       /* Assumes c is unique (can't be closed concurrently */
-       c->flag |= COPEN;
-       c->offset = 0;
-       poperror();
-       //print_func_exit();
-       return c;
-}
-
-static void vmcreate(struct chan *c, char *name, int omode, uint32_t perm)
-{
-       //print_func_entry();
-       error(Eperm);
-       //print_func_exit();
-}
-
-static void vmremove(struct chan *c)
-{
-       //print_func_entry();
-       error(Eperm);
-       //print_func_exit();
-}
-
-static int vmwstat(struct chan *c, uint8_t * dp, int n)
-{
-       //print_func_entry();
-       error("No vmwstat");
-       //print_func_exit();
-       return 0;
-}
-
-static void vmclose(struct chan *c)
-{
-       //print_func_entry();
-       struct vm *v = c->aux;
-       if (!v) {
-               //print_func_exit();
-               return;
-       }
-       /* There are more closes than opens.  For instance, sysstat doesn't open,
-        * but it will close the chan it got from namec.  We only want to clean
-        * up/decref chans that were actually open. */
-       if (!(c->flag & COPEN)) {
-               //print_func_exit();
-               return;
-       }
-       switch (TYPE(c->qid)) {
-                       /* for now, leave the VM active even when we close ctl */
-               case Qctl:
-                       break;
-               case Qimage:
-                       kref_put(&v->kref);
-                       break;
-       }
-       //print_func_exit();
-}
-
-static long vmread(struct chan *c, void *ubuf, long n, int64_t offset)
-{
-       //print_func_entry();
-       struct vm *v = c->aux;
-       printd("VMREAD\n");
-       switch (TYPE(c->qid)) {
-               case Qtopdir:
-               case Qvmdir:
-                       //print_func_exit();
-                       return devdirread(c, ubuf, n, 0, 0, vmgen);
-               case Qstat:
-                       //print_func_exit();
-                       return readnum(offset, ubuf, n, nvm, NUMSIZE32);
-               case Qctl:
-                       assert(v);
-                       //print_func_exit();
-                       return readnum(offset, ubuf, n, v->id, NUMSIZE32);
-               case Qimage:
-                       assert(v);
-                       //print_func_exit();
-                       return readmem(offset, ubuf, n, v->image, v->imagesize);
-               default:
-                       panic("Bad QID %p in devvm", c->qid.path);
-       }
-       //print_func_exit();
-       return 0;
-}
-
-static long vmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
-{
-       //print_func_entry();
-       ERRSTACK(3);
-       char buf[32];
-       struct cmdbuf *cb;
-       struct vm *vm;
-       struct litevm *litevm;
-       uint64_t hexval;
-       printd("vmwrite(%p, %p, %d)\n", c, ubuf, n);
-       switch (TYPE(c->qid)) {
-               case Qtopdir:
-               case Qvmdir:
-               case Qstat:
-                       error(Eperm);
-               case Qctl:
-                       vm = c->aux;
-                       litevm = vm->archvm;
-                       printk("qctl: vm is %p, litevm is %p\n", vm, litevm);
-                       cb = parsecmd(ubuf, n);
-                       if (waserror()) {
-                               kfree(cb);
-                               nexterror();
-                       }
-                       if (cb->nf < 1)
-                               error("short control request");
-                       if (!strcmp(cb->f[0], "run")) {
-                               int ret;
-                               if (cb->nf != 4)
-                                       error("usage: run vcpu emulated mmio_completed");
-                               struct litevm_run vmr;
-                               vmr.vcpu = strtoul(cb->f[1], NULL, 0);
-                               vmr.emulated = strtoul(cb->f[2], NULL, 0);
-                               vmr.mmio_completed = strtoul(cb->f[3], NULL, 0);
-                               disable_irq();
-                               ret = vm_run(litevm, &vmr);
-                               enable_irq();
-                               printk("vm_run returns %d\n", ret);
-                               //print_func_exit();
-                               return ret;
-                       } else if (!strcmp(cb->f[0], "stop")) {
-                               error("can't stop a vm yet");
-                       } else if (!strcmp(cb->f[0], "mapmem")) {
-                               struct chan *file;
-                               void *v;
-                               vm = c->aux;
-                               uint64_t filesize;
-                               struct litevm_memory_region vmr;
-                               int got;
-
-                               if (cb->nf != 6)
-                                       error("usage: mapmem file slot flags addr size");
-                               vmr.slot = strtoul(cb->f[2], NULL, 0);
-                               vmr.flags = strtoul(cb->f[3], NULL, 0);
-                               vmr.guest_phys_addr = strtoul(cb->f[4], NULL, 0);
-                               filesize = strtoul(cb->f[5], NULL, 0);
-                               vmr.memory_size = (filesize + 4095) & ~4095ULL;
-
-                               file = namec(cb->f[1], Aopen, OREAD, 0);
-                               printk("after namec file is %p\n", file);
-                               if (waserror()) {
-                                       printk("File open, alloc bad\n");
-                                       cclose(file);
-                                       nexterror();
-                               }
-                               /* at some point we want to mmap from the kernel
-                                * but we don't have that yet. This all needs
-                                * rethinking but the abstractions of kvm do too.
-                                */
-                               v = kmalloc(vmr.memory_size, KMALLOC_WAIT);
-                               if (waserror()) {
-                                       printk("memory allocated, read bad %s\n", 
-                                               current_errstr());
-                                       kfree(v);
-                                       nexterror();
-                               }
-
-                               readn(file, v, filesize);
-                               vmr.init_data = v;
-
-                               if (vm_set_memory_region(litevm, &vmr))
-                                       error("vm_set_memory_region failed");
-                               void monitor(void *);
-                               monitor(NULL);
-                               poperror();
-                               poperror();
-                               kfree(v);
-                               cclose(file);
-
-                       } else if (!strcmp(cb->f[0], "region")) {
-                               void *v;
-                               struct litevm_memory_region vmr;
-                               if (cb->nf != 5)
-                                       error("usage: mapmem slot flags addr size");
-                               vmr.slot = strtoul(cb->f[1], NULL, 0);
-                               vmr.flags = strtoul(cb->f[2], NULL, 0);
-                               vmr.guest_phys_addr = strtoul(cb->f[3], NULL, 0);
-                               vmr.memory_size = strtoul(cb->f[4], NULL, 0);
-                               vmr.init_data = NULL;
-                               if (vm_set_memory_region(litevm, &vmr))
-                                       error("vm_set_memory_region failed");
-                       } else {
-                               error("%s: not implemented", cb->f[0]);
-                       }
-                       kfree(cb);
-                       poperror();
-                       break;
-               case Qimage:
-                       error("can't write an image yet");
-                       break;
-               default:
-                       panic("Bad QID %p in devvm", c->qid.path);
-       }
-       //print_func_exit();
-       return n;
-}
-
-struct dev vmdevtab __devtab = {
-       'V',
-       "vm",
-
-       devreset,
-       vminit,
-       devshutdown,
-       vmattach,
-       vmwalk,
-       vmstat,
-       vmopen,
-       vmcreate,
-       vmclose,
-       vmread,
-       devbread,
-       vmwrite,
-       devbwrite,
-       vmremove,
-       vmwstat,
-       devpower,
-//  devconfig,
-       devchaninfo,
-};
index c31ad34..f57f038 100644 (file)
@@ -18,9 +18,6 @@
 #include <syscall.h>
 #include <alarm.h>
 #include <trace.h>
-#ifdef CONFIG_X86
-#include <arch/vm.h>
-#endif
 
 #ifdef __SHARC__
 typedef sharC_env_t;
@@ -45,11 +42,7 @@ struct per_cpu_info {
        uintptr_t stacktop;                     /* must be first */
        int coreid;                                     /* must be second */
        /* virtual machines */
-       /* this is all kind of gross, but so it goes. Kmalloc
-        * the vmxarea. It varies in size depending on the architecture.
-        */
-       struct vmcs *vmxarea;
-       struct vmcs *vmcs;
+       //struct vmcs *vmxarea;
        pseudodesc_t host_gdt;
        int vmx_enabled;
        void *local_vcpu;