# Makefile for GeekOS kernel, userspace, and tools
# Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.22 $
+# $Revision: 1.23 $
# This is free software. You are permitted to use,
# redistribute, and modify it as specified in the file "COPYING".
VMM_C_SRCS := vm_guest.c \
svm.c svm_handler.c vmm.c vmm_util.c svm_ctrl_regs.c \
vmcb.c vmm_mem.c vmm_paging.c vmm_io.c vmm_debug.c svm_io.c \
+ vmm_intr.c \
vmm_shadow_paging.c vm_guest_mem.c #\
# vmx.c vmcs_gen.c vmcs.c
#include <palacios/vmm_types.h>
#include <palacios/vmm_io.h>
#include <palacios/vmm_shadow_paging.h>
-
+#include <palacios/vmm_intr.h>
typedef ullong_t gpr_t;
// nested_paging_t nested_page_state;
+ // This structure is how we get interrupts for the guest
+ struct vm_intr intr_state;
+
vmm_io_map_t io_map;
// device_map
typedef void vmcb_t;
-union Ctrl_Registers {
- ushort_t bitmap PACKED;
- struct {
+struct Ctrl_Registers {
uint_t cr0 : 1 PACKED;
uint_t cr1 : 1 PACKED;
uint_t cr2 : 1 PACKED;
uint_t cr13 : 1 PACKED;
uint_t cr14 : 1 PACKED;
uint_t cr15 : 1 PACKED;
- } crs;
};
-union Debug_Registers {
- ushort_t bitmap PACKED;
- struct {
+struct Debug_Registers {
uint_t dr0 : 1 PACKED;
uint_t dr1 : 1 PACKED;
uint_t dr2 : 1 PACKED;
uint_t dr13 : 1 PACKED;
uint_t dr14 : 1 PACKED;
uint_t dr15 : 1 PACKED;
- } drs;
};
-union Exception_Vectors {
- uint_t bitmap PACKED;
- struct {
- uint_t ex0 : 1 PACKED;
- uint_t ex1 : 1 PACKED;
- uint_t ex2 : 1 PACKED;
- uint_t ex3 : 1 PACKED;
- uint_t ex4 : 1 PACKED;
- uint_t ex5 : 1 PACKED;
- uint_t ex6 : 1 PACKED;
- uint_t ex7 : 1 PACKED;
- uint_t ex8 : 1 PACKED;
- uint_t ex9 : 1 PACKED;
- uint_t ex10 : 1 PACKED;
- uint_t ex11 : 1 PACKED;
- uint_t ex12 : 1 PACKED;
- uint_t ex13 : 1 PACKED;
- uint_t ex14 : 1 PACKED;
- uint_t ex15 : 1 PACKED;
- uint_t ex16 : 1 PACKED;
- uint_t ex17 : 1 PACKED;
- uint_t ex18 : 1 PACKED;
- uint_t ex19 : 1 PACKED;
- uint_t ex20 : 1 PACKED;
- uint_t ex21 : 1 PACKED;
- uint_t ex22 : 1 PACKED;
- uint_t ex23 : 1 PACKED;
- uint_t ex24 : 1 PACKED;
- uint_t ex25 : 1 PACKED;
- uint_t ex26 : 1 PACKED;
- uint_t ex27 : 1 PACKED;
- uint_t ex28 : 1 PACKED;
- uint_t ex29 : 1 PACKED;
- uint_t ex30 : 1 PACKED;
- uint_t ex31 : 1 PACKED;
- } ex_numbers;
- struct {
+struct Exception_Vectors {
uint_t de : 1 PACKED; // divide by zero
uint_t db : 1 PACKED; // Debug
uint_t nmi : 1 PACKED; // Non-maskable interrupt
uint_t ex29 : 1 PACKED;
uint_t sx : 1 PACKED; // Security Exception
uint_t ex31 : 1 PACKED;
- } ex_names;
};
-union Instr_Intercepts {
- uint_t bitmap PACKED;
- struct {
+struct Instr_Intercepts {
uint_t INTR : 1 PACKED;
uint_t NMI : 1 PACKED;
uint_t SMI : 1 PACKED;
uint_t task_switch : 1 PACKED;
uint_t FERR_FREEZE : 1 PACKED;
uint_t shutdown_evts: 1 PACKED;
- } instrs;
};
-union SVM_Instr_Intercepts {
- uint_t bitmap PACKED;
- struct {
- uint_t VMRUN : 1 PACKED;
- uint_t VMMCALL : 1 PACKED;
- uint_t VMLOAD : 1 PACKED;
- uint_t VMSAVE : 1 PACKED;
- uint_t STGI : 1 PACKED;
- uint_t CLGI : 1 PACKED;
- uint_t SKINIT : 1 PACKED;
- uint_t RDTSCP : 1 PACKED;
- uint_t ICEBP : 1 PACKED;
- uint_t WBINVD : 1 PACKED;
- uint_t MONITOR : 1 PACKED;
- uint_t MWAIT_always : 1 PACKED;
- uint_t MWAIT_if_armed : 1 PACKED;
- uint_t reserved : 19 PACKED; // Should be 0
- } instrs;
+struct SVM_Instr_Intercepts {
+ uint_t VMRUN : 1 PACKED;
+ uint_t VMMCALL : 1 PACKED;
+ uint_t VMLOAD : 1 PACKED;
+ uint_t VMSAVE : 1 PACKED;
+ uint_t STGI : 1 PACKED;
+ uint_t CLGI : 1 PACKED;
+ uint_t SKINIT : 1 PACKED;
+ uint_t RDTSCP : 1 PACKED;
+ uint_t ICEBP : 1 PACKED;
+ uint_t WBINVD : 1 PACKED;
+ uint_t MONITOR : 1 PACKED;
+ uint_t MWAIT_always : 1 PACKED;
+ uint_t MWAIT_if_armed : 1 PACKED;
+ uint_t reserved : 19 PACKED; // Should be 0
};
-union Guest_Control {
- uint_t bitmap PACKED;
- struct {
- uchar_t V_TPR PACKED;
- uint_t V_IRQ : 1 PACKED;
- uint_t rsvd1 : 7 PACKED; // Should be 0
- uint_t V_INTR_PRIO : 4 PACKED;
- uint_t V_IGN_TPR : 1 PACKED;
- uint_t rsvd2 : 3 PACKED; // Should be 0
- uint_t V_INTR_MASKING : 1 PACKED;
- uint_t rsvd3 : 7 PACKED; // Should be 0
- uchar_t V_INTR_VECTOR PACKED;
- uint_t rsvd4 : 24 PACKED; // Should be 0
- } ctrls;
+struct Guest_Control {
+ uchar_t V_TPR PACKED;
+ uint_t V_IRQ : 1 PACKED;
+ uint_t rsvd1 : 7 PACKED; // Should be 0
+ uint_t V_INTR_PRIO : 4 PACKED;
+ uint_t V_IGN_TPR : 1 PACKED;
+ uint_t rsvd2 : 3 PACKED; // Should be 0
+ uint_t V_INTR_MASKING : 1 PACKED;
+ uint_t rsvd3 : 7 PACKED; // Should be 0
+ uchar_t V_INTR_VECTOR PACKED;
+ uint_t rsvd4 : 24 PACKED; // Should be 0
};
+#define SVM_INJECTION_EXTERNAL_INTR 0
+#define SVM_INJECTION_VIRTUAL_INTR 0
+#define SVM_INJECTION_NMI 2
+#define SVM_INJECTION_EXCEPTION 3
+#define SVM_INJECTION_SOFT_INTR 4
+
+struct Interrupt_Info {
+ uint_t vector : 8 PACKED;
+ uint_t type : 3 PACKED;
+ uint_t ev : 1 PACKED;
+ uint_t rsvd : 19 PACKED;
+ uint_t valid : 1 PACKED;
+ uint_t error_code : 32 PACKED;
+};
typedef struct VMCB_Control_Area {
// offset 0x0
- union Ctrl_Registers cr_reads PACKED;
- union Ctrl_Registers cr_writes PACKED;
- union Debug_Registers dr_reads PACKED;
- union Debug_Registers dr_writes PACKED;
- union Exception_Vectors exceptions PACKED;
- union Instr_Intercepts instrs PACKED;
- union SVM_Instr_Intercepts svm_instrs PACKED;
+ struct Ctrl_Registers cr_reads PACKED;
+ struct Ctrl_Registers cr_writes PACKED;
+ struct Debug_Registers dr_reads PACKED;
+ struct Debug_Registers dr_writes PACKED;
+ struct Exception_Vectors exceptions PACKED;
+ struct Instr_Intercepts instrs PACKED;
+ struct SVM_Instr_Intercepts svm_instrs PACKED;
uchar_t rsvd1[44] PACKED; // Should be 0
uchar_t rsvd2[3] PACKED; // Should be 0
- union Guest_Control guest_ctrl PACKED;
+ struct Guest_Control guest_ctrl PACKED;
uint_t interrupt_shadow : 1 PACKED;
uint_t rsvd3 : 31 PACKED; // Should be 0
uchar_t rsvd7[16] PACKED; // Should be 0
// Offset 0xA8
- ullong_t EVENTINJ PACKED;
+ struct Interrupt_Info EVENTINJ PACKED;
/* This could be a typo in the manual....
uint_t avl : 1 PACKED; // available for use by system software
uint_t L : 1 PACKED; // long mode (64 bit?)
uint_t db : 1 PACKED; // default op size (0=16 bit seg, 1=32 bit seg)
- uint_t G : 1 PACKED; // Granularity, (0=bytes, 1=4k)
+ uint_t G : 1 PACKED; // Granularity, (0=bytes, 1=4k)
+ uint_t rsvd : 4 PACKED;
} fields;
} attrib;
uint_t limit PACKED;
#ifndef __VMM_INTR_H
#define __VMM_INTR_H
+#include <palacios/vmm_types.h>
+#define DE_EXCEPTION 0x00
+#define DB_EXCEPTION 0x01
+#define NMI_EXCEPTION 0x02
+#define BP_EXCEPTION 0x03
+#define OF_EXCEPTION 0x04
+#define BR_EXCEPTION 0x05
+#define UD_EXCEPTION 0x06
+#define NM_EXCEPTION 0x07
+#define DF_EXCEPTION 0x08
+#define TS_EXCEPTION 0x0a
+#define NP_EXCEPTION 0x0b
+#define SS_EXCEPTION 0x0c
+#define GPF_EXCEPTION 0x0d
+#define PF_EXCEPTION 0x0e
+#define MF_EXCEPTION 0x10
+#define AC_EXCEPTION 0x11
+#define MC_EXCEPTION 0x12
+#define XF_EXCEPTION 0x13
+#define SX_EXCEPTION 0x1e
+
+
+typedef enum {INVALID_INTR, EXTERNAL_IRQ, NMI, EXCEPTION, SOFTWARE, VIRTUAL} intr_types_t;
+
+struct guest_info;
+
+struct vm_intr {
+ uint_t excp_pending;
+ uint_t excp_num;
+
+ /* some way to get the [A]PIC intr */
+
+};
+
+
+int raise_exception(struct guest_info * info, uint_t excp);
+
+int intr_pending(struct vm_intr * intr);
+uint_t get_intr_number(struct vm_intr * intr);
+intr_types_t get_intr_type(struct vm_intr * intr);
#endif
bochs_debug_buf[bochs_debug_offset++] = *(char*)src;
- if ((*(char*)src == '\n') || (bochs_debug_offset == 1023)) {
+ if ((*(char*)src == 0xa) || (bochs_debug_offset == 1023)) {
SerialPrint("BOCHS>%s", bochs_debug_buf);
memset(bochs_debug_buf, 0, 1024);
bochs_debug_offset = 0;
//ctrl_area->instrs.instrs.CR0 = 1;
- ctrl_area->cr_reads.crs.cr0 = 1;
- ctrl_area->cr_writes.crs.cr0 = 1;
+ ctrl_area->cr_reads.cr0 = 1;
+ ctrl_area->cr_writes.cr0 = 1;
guest_state->efer |= EFER_MSR_svm_enable;
guest_state->rflags = 0x00000002; // The reserved bit is always 1
- ctrl_area->svm_instrs.instrs.VMRUN = 1;
+ ctrl_area->svm_instrs.VMRUN = 1;
// guest_state->cr0 = 0x00000001; // PE
ctrl_area->guest_ASID = 1;
- ctrl_area->exceptions.ex_names.de = 1;
- ctrl_area->exceptions.ex_names.df = 1;
- ctrl_area->exceptions.ex_names.pf = 1;
- ctrl_area->exceptions.ex_names.ts = 1;
- ctrl_area->exceptions.ex_names.ss = 1;
- ctrl_area->exceptions.ex_names.ac = 1;
- ctrl_area->exceptions.ex_names.mc = 1;
- ctrl_area->exceptions.ex_names.gp = 1;
- ctrl_area->exceptions.ex_names.ud = 1;
- ctrl_area->exceptions.ex_names.np = 1;
- ctrl_area->exceptions.ex_names.of = 1;
- ctrl_area->exceptions.ex_names.nmi = 1;
+ ctrl_area->exceptions.de = 1;
+ ctrl_area->exceptions.df = 1;
+ ctrl_area->exceptions.pf = 1;
+ ctrl_area->exceptions.ts = 1;
+ ctrl_area->exceptions.ss = 1;
+ ctrl_area->exceptions.ac = 1;
+ ctrl_area->exceptions.mc = 1;
+ ctrl_area->exceptions.gp = 1;
+ ctrl_area->exceptions.ud = 1;
+ ctrl_area->exceptions.np = 1;
+ ctrl_area->exceptions.of = 1;
+ ctrl_area->exceptions.nmi = 1;
guest_state->cs.selector = 0x0000;
guest_state->cs.limit=~0u;
//PrintDebugMemDump((uchar_t*)io_port_bitmap, PAGE_SIZE *2);
- ctrl_area->instrs.instrs.IOIO_PROT = 1;
+ ctrl_area->instrs.IOIO_PROT = 1;
}
- ctrl_area->instrs.instrs.INTR = 1;
+ ctrl_area->instrs.INTR = 1;
guest_state->cr3 = vm_info.shdw_pg_state.shadow_cr3.r_reg;
- ctrl_area->cr_reads.crs.cr3 = 1;
- ctrl_area->cr_writes.crs.cr3 = 1;
+ ctrl_area->cr_reads.cr3 = 1;
+ ctrl_area->cr_writes.cr3 = 1;
- ctrl_area->instrs.instrs.INVLPG = 1;
- ctrl_area->instrs.instrs.INVLPGA = 1;
+ ctrl_area->instrs.INVLPG = 1;
+ ctrl_area->instrs.INVLPGA = 1;
guest_state->g_pat = 0x7040600070406ULL;
guest_state->rip = 0xfff0;
//ctrl_area->instrs.instrs.CR0 = 1;
- ctrl_area->cr_reads.crs.cr0 = 1;
- ctrl_area->cr_writes.crs.cr0 = 1;
+ ctrl_area->cr_reads.cr0 = 1;
+ ctrl_area->cr_writes.cr0 = 1;
guest_state->efer |= EFER_MSR_svm_enable;
guest_state->rflags = 0x00000002; // The reserved bit is always 1
- ctrl_area->svm_instrs.instrs.VMRUN = 1;
+ ctrl_area->svm_instrs.VMRUN = 1;
// guest_state->cr0 = 0x00000001; // PE
ctrl_area->guest_ASID = 1;
- ctrl_area->exceptions.ex_names.de = 1;
- ctrl_area->exceptions.ex_names.df = 1;
- ctrl_area->exceptions.ex_names.pf = 1;
- ctrl_area->exceptions.ex_names.ts = 1;
- ctrl_area->exceptions.ex_names.ss = 1;
- ctrl_area->exceptions.ex_names.ac = 1;
- ctrl_area->exceptions.ex_names.mc = 1;
- ctrl_area->exceptions.ex_names.gp = 1;
- ctrl_area->exceptions.ex_names.ud = 1;
- ctrl_area->exceptions.ex_names.np = 1;
- ctrl_area->exceptions.ex_names.of = 1;
- ctrl_area->exceptions.ex_names.nmi = 1;
+ ctrl_area->exceptions.de = 1;
+ ctrl_area->exceptions.df = 1;
+ ctrl_area->exceptions.pf = 1;
+ ctrl_area->exceptions.ts = 1;
+ ctrl_area->exceptions.ss = 1;
+ ctrl_area->exceptions.ac = 1;
+ ctrl_area->exceptions.mc = 1;
+ ctrl_area->exceptions.gp = 1;
+ ctrl_area->exceptions.ud = 1;
+ ctrl_area->exceptions.np = 1;
+ ctrl_area->exceptions.of = 1;
+ ctrl_area->exceptions.nmi = 1;
vm_info.vm_regs.rdx = 0x00000f00;
//PrintDebugMemDump((uchar_t*)io_port_bitmap, PAGE_SIZE *2);
- ctrl_area->instrs.instrs.IOIO_PROT = 1;
+ ctrl_area->instrs.IOIO_PROT = 1;
}
//ctrl_area->instrs.instrs.INTR = 1;
guest_state->cr3 = vm_info.shdw_pg_state.shadow_cr3.r_reg;
- PrintDebugPageTables((pde32_t*)(vm_info.shdw_pg_state.shadow_cr3.e_reg.low));
+ //PrintDebugPageTables((pde32_t*)(vm_info.shdw_pg_state.shadow_cr3.e_reg.low));
- ctrl_area->cr_reads.crs.cr3 = 1;
- ctrl_area->cr_writes.crs.cr3 = 1;
+ ctrl_area->cr_reads.cr3 = 1;
+ ctrl_area->cr_writes.cr3 = 1;
- ctrl_area->instrs.instrs.INVLPG = 1;
- ctrl_area->instrs.instrs.INVLPGA = 1;
+ ctrl_area->instrs.INVLPG = 1;
+ ctrl_area->instrs.INVLPGA = 1;
guest_state->g_pat = 0x7040600070406ULL;
guest_state->efer |= EFER_MSR_svm_enable;
guest_state->rflags = 0x00000002; // The reserved bit is always 1
- ctrl_area->svm_instrs.instrs.VMRUN = 1;
+ ctrl_area->svm_instrs.VMRUN = 1;
guest_state->cr0 = 0x00000001; // PE
ctrl_area->guest_ASID = 1;
// Setup exits
- ctrl_area->cr_writes.crs.cr4 = 1;
+ ctrl_area->cr_writes.cr4 = 1;
- ctrl_area->exceptions.ex_names.de = 1;
- ctrl_area->exceptions.ex_names.df = 1;
- ctrl_area->exceptions.ex_names.pf = 1;
- ctrl_area->exceptions.ex_names.ts = 1;
- ctrl_area->exceptions.ex_names.ss = 1;
- ctrl_area->exceptions.ex_names.ac = 1;
- ctrl_area->exceptions.ex_names.mc = 1;
- ctrl_area->exceptions.ex_names.gp = 1;
- ctrl_area->exceptions.ex_names.ud = 1;
- ctrl_area->exceptions.ex_names.np = 1;
- ctrl_area->exceptions.ex_names.of = 1;
- ctrl_area->exceptions.ex_names.nmi = 1;
+ ctrl_area->exceptions.de = 1;
+ ctrl_area->exceptions.df = 1;
+ ctrl_area->exceptions.pf = 1;
+ ctrl_area->exceptions.ts = 1;
+ ctrl_area->exceptions.ss = 1;
+ ctrl_area->exceptions.ac = 1;
+ ctrl_area->exceptions.mc = 1;
+ ctrl_area->exceptions.gp = 1;
+ ctrl_area->exceptions.ud = 1;
+ ctrl_area->exceptions.np = 1;
+ ctrl_area->exceptions.of = 1;
+ ctrl_area->exceptions.nmi = 1;
- ctrl_area->instrs.instrs.IOIO_PROT = 1;
+ ctrl_area->instrs.IOIO_PROT = 1;
ctrl_area->IOPM_BASE_PA = (uint_t)os_hooks->allocate_pages(3);
{
memset((void*)(tmp_reg.e_reg.low), 0xffffffff, PAGE_SIZE * 2);
}
- ctrl_area->instrs.instrs.INTR = 1;
+ ctrl_area->instrs.INTR = 1;
{
guest_state->cr0 = 0x60000010;
- ctrl_area->exceptions.ex_names.de = 1;
- ctrl_area->exceptions.ex_names.df = 1;
- ctrl_area->exceptions.ex_names.pf = 1;
- ctrl_area->exceptions.ex_names.ts = 1;
- ctrl_area->exceptions.ex_names.ss = 1;
- ctrl_area->exceptions.ex_names.ac = 1;
- ctrl_area->exceptions.ex_names.mc = 1;
- ctrl_area->exceptions.ex_names.gp = 1;
- ctrl_area->exceptions.ex_names.ud = 1;
- ctrl_area->exceptions.ex_names.np = 1;
- ctrl_area->exceptions.ex_names.of = 1;
- ctrl_area->exceptions.ex_names.nmi = 1;
+ ctrl_area->exceptions.de = 1;
+ ctrl_area->exceptions.df = 1;
+ ctrl_area->exceptions.pf = 1;
+ ctrl_area->exceptions.ts = 1;
+ ctrl_area->exceptions.ss = 1;
+ ctrl_area->exceptions.ac = 1;
+ ctrl_area->exceptions.mc = 1;
+ ctrl_area->exceptions.gp = 1;
+ ctrl_area->exceptions.ud = 1;
+ ctrl_area->exceptions.np = 1;
+ ctrl_area->exceptions.of = 1;
+ ctrl_area->exceptions.nmi = 1;
guest_state->cs.selector = 0xf000;
guest_state->cs.limit=0xffff;
#include <palacios/vmm_emulate.h>
#include <palacios/svm_ctrl_regs.h>
#include <palacios/svm_io.h>
+#include <palacios/vmm_intr.h>
extern struct vmm_os_hooks * os_hooks;
// Update the low level state
+
+ if (intr_pending(&(info->intr_state))) {
+ guest_ctrl->EVENTINJ.vector = get_intr_number(&(info->intr_state));
+ guest_ctrl->EVENTINJ.valid = 1;
+
+ switch (get_intr_type(&(info->intr_state))) {
+ case EXTERNAL_IRQ:
+ guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
+ break;
+ case NMI:
+ guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
+ break;
+ case EXCEPTION:
+ guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
+ break;
+ case SOFTWARE:
+ guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
+ break;
+ case VIRTUAL:
+ guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
+ break;
+
+ case INVALID_INTR:
+ default:
+ PrintDebug("Attempted to issue and invalid interrupt\n");
+ return -1;
+ }
+
+ // IMPORTANT TODO
+ // We need to figure out stack parameters....
+ // EVENTINJ.error_code
+
+ }
+
guest_state->rax = info->vm_regs.rax;
guest_state->rip = info->rip;
guest_state->rsp = info->vm_regs.rsp;
PrintDebug("VMCB (0x%.8x)\n", vmcb);
PrintDebug("--Control Area--\n");
- PrintDebug("CR Reads: %x\n", ctrl_area->cr_reads.bitmap);
- PrintDebug("CR Writes: %x\n", ctrl_area->cr_writes.bitmap);
- PrintDebug("DR Reads: %x\n", ctrl_area->dr_reads.bitmap);
- PrintDebug("DR Writes: %x\n", ctrl_area->dr_writes.bitmap);
-
- PrintDebug("Exception Bitmap: %x (at 0x%.8x)\n", ctrl_area->exceptions.bitmap, &(ctrl_area->exceptions));
- PrintDebug("\tDivide-by-Zero: %d\n", ctrl_area->exceptions.ex_names.de);
- PrintDebug("\tDebug: %d\n", ctrl_area->exceptions.ex_names.db);
- PrintDebug("\tNon-maskable interrupts: %d\n", ctrl_area->exceptions.ex_names.nmi);
- PrintDebug("\tBreakpoint: %d\n", ctrl_area->exceptions.ex_names.bp);
- PrintDebug("\tOverflow: %d\n", ctrl_area->exceptions.ex_names.of);
- PrintDebug("\tBound-Range: %d\n", ctrl_area->exceptions.ex_names.br);
- PrintDebug("\tInvalid Opcode: %d\n", ctrl_area->exceptions.ex_names.ud);
- PrintDebug("\tDevice not available: %d\n", ctrl_area->exceptions.ex_names.nm);
- PrintDebug("\tDouble Fault: %d\n", ctrl_area->exceptions.ex_names.df);
- PrintDebug("\tInvalid TSS: %d\n", ctrl_area->exceptions.ex_names.ts);
- PrintDebug("\tSegment not present: %d\n", ctrl_area->exceptions.ex_names.np);
- PrintDebug("\tStack: %d\n", ctrl_area->exceptions.ex_names.ss);
- PrintDebug("\tGPF: %d\n", ctrl_area->exceptions.ex_names.gp);
- PrintDebug("\tPage Fault: %d\n", ctrl_area->exceptions.ex_names.pf);
- PrintDebug("\tFloating Point: %d\n", ctrl_area->exceptions.ex_names.mf);
- PrintDebug("\tAlignment Check: %d\n", ctrl_area->exceptions.ex_names.ac);
- PrintDebug("\tMachine Check: %d\n", ctrl_area->exceptions.ex_names.mc);
- PrintDebug("\tSIMD floating point: %d\n", ctrl_area->exceptions.ex_names.xf);
- PrintDebug("\tSecurity: %d\n", ctrl_area->exceptions.ex_names.sx);
-
- PrintDebug("Instructions bitmap: %.8x (at 0x%.8x)\n", ctrl_area->instrs.bitmap, &(ctrl_area->instrs));
- PrintDebug("\tINTR: %d\n", ctrl_area->instrs.instrs.INTR);
- PrintDebug("\tNMI: %d\n", ctrl_area->instrs.instrs.NMI);
- PrintDebug("\tSMI: %d\n", ctrl_area->instrs.instrs.SMI);
- PrintDebug("\tINIT: %d\n", ctrl_area->instrs.instrs.INIT);
- PrintDebug("\tVINTR: %d\n", ctrl_area->instrs.instrs.VINTR);
- PrintDebug("\tCR0: %d\n", ctrl_area->instrs.instrs.CR0);
- PrintDebug("\tRD_IDTR: %d\n", ctrl_area->instrs.instrs.RD_IDTR);
- PrintDebug("\tRD_GDTR: %d\n", ctrl_area->instrs.instrs.RD_GDTR);
- PrintDebug("\tRD_LDTR: %d\n", ctrl_area->instrs.instrs.RD_LDTR);
- PrintDebug("\tRD_TR: %d\n", ctrl_area->instrs.instrs.RD_TR);
- PrintDebug("\tWR_IDTR: %d\n", ctrl_area->instrs.instrs.WR_IDTR);
- PrintDebug("\tWR_GDTR: %d\n", ctrl_area->instrs.instrs.WR_GDTR);
- PrintDebug("\tWR_LDTR: %d\n", ctrl_area->instrs.instrs.WR_LDTR);
- PrintDebug("\tWR_TR: %d\n", ctrl_area->instrs.instrs.WR_TR);
- PrintDebug("\tRDTSC: %d\n", ctrl_area->instrs.instrs.RDTSC);
- PrintDebug("\tRDPMC: %d\n", ctrl_area->instrs.instrs.RDPMC);
- PrintDebug("\tPUSHF: %d\n", ctrl_area->instrs.instrs.PUSHF);
- PrintDebug("\tPOPF: %d\n", ctrl_area->instrs.instrs.POPF);
- PrintDebug("\tCPUID: %d\n", ctrl_area->instrs.instrs.CPUID);
- PrintDebug("\tRSM: %d\n", ctrl_area->instrs.instrs.RSM);
- PrintDebug("\tIRET: %d\n", ctrl_area->instrs.instrs.IRET);
- PrintDebug("\tINTn: %d\n", ctrl_area->instrs.instrs.INTn);
- PrintDebug("\tINVD: %d\n", ctrl_area->instrs.instrs.INVD);
- PrintDebug("\tPAUSE: %d\n", ctrl_area->instrs.instrs.PAUSE);
- PrintDebug("\tHLT: %d\n", ctrl_area->instrs.instrs.HLT);
- PrintDebug("\tINVLPG: %d\n", ctrl_area->instrs.instrs.INVLPG);
- PrintDebug("\tINVLPGA: %d\n", ctrl_area->instrs.instrs.INVLPGA);
- PrintDebug("\tIOIO_PROT: %d\n", ctrl_area->instrs.instrs.IOIO_PROT);
- PrintDebug("\tMSR_PROT: %d\n", ctrl_area->instrs.instrs.MSR_PROT);
- PrintDebug("\ttask_switch: %d\n", ctrl_area->instrs.instrs.task_switch);
- PrintDebug("\tFERR_FREEZE: %d\n", ctrl_area->instrs.instrs.FERR_FREEZE);
- PrintDebug("\tshutdown_evts: %d\n", ctrl_area->instrs.instrs.shutdown_evts);
-
- PrintDebug("SVM Instruction Bitmap: %.8x (at 0x%.8x)\n", ctrl_area->svm_instrs.bitmap, &(ctrl_area->svm_instrs));
- PrintDebug("\tVMRUN: %d\n", ctrl_area->svm_instrs.instrs.VMRUN);
- PrintDebug("\tVMMCALL: %d\n", ctrl_area->svm_instrs.instrs.VMMCALL);
- PrintDebug("\tVMLOAD: %d\n", ctrl_area->svm_instrs.instrs.VMLOAD);
- PrintDebug("\tVMSAVE: %d\n", ctrl_area->svm_instrs.instrs.VMSAVE);
- PrintDebug("\tSTGI: %d\n", ctrl_area->svm_instrs.instrs.STGI);
- PrintDebug("\tCLGI: %d\n", ctrl_area->svm_instrs.instrs.CLGI);
- PrintDebug("\tSKINIT: %d\n", ctrl_area->svm_instrs.instrs.SKINIT);
- PrintDebug("\tRDTSCP: %d\n", ctrl_area->svm_instrs.instrs.RDTSCP);
- PrintDebug("\tICEBP: %d\n", ctrl_area->svm_instrs.instrs.ICEBP);
- PrintDebug("\tWBINVD: %d\n", ctrl_area->svm_instrs.instrs.WBINVD);
- PrintDebug("\tMONITOR: %d\n", ctrl_area->svm_instrs.instrs.MONITOR);
- PrintDebug("\tMWAIT_always: %d\n", ctrl_area->svm_instrs.instrs.MWAIT_always);
- PrintDebug("\tMWAIT_if_armed: %d\n", ctrl_area->svm_instrs.instrs.MWAIT_if_armed);
+ PrintDebug("CR Reads: %x\n", *(ushort_t*)&(ctrl_area->cr_reads));
+ PrintDebug("CR Writes: %x\n", *(ushort_t*)&(ctrl_area->cr_writes));
+ PrintDebug("DR Reads: %x\n", *(ushort_t*)&(ctrl_area->dr_reads));
+ PrintDebug("DR Writes: %x\n", *(ushort_t*)&(ctrl_area->dr_writes));
+
+ PrintDebug("Exception Bitmap: %x (at 0x%.8x)\n", *(uint_t*)&(ctrl_area->exceptions), &(ctrl_area->exceptions));
+ PrintDebug("\tDivide-by-Zero: %d\n", ctrl_area->exceptions.de);
+ PrintDebug("\tDebug: %d\n", ctrl_area->exceptions.db);
+ PrintDebug("\tNon-maskable interrupts: %d\n", ctrl_area->exceptions.nmi);
+ PrintDebug("\tBreakpoint: %d\n", ctrl_area->exceptions.bp);
+ PrintDebug("\tOverflow: %d\n", ctrl_area->exceptions.of);
+ PrintDebug("\tBound-Range: %d\n", ctrl_area->exceptions.br);
+ PrintDebug("\tInvalid Opcode: %d\n", ctrl_area->exceptions.ud);
+ PrintDebug("\tDevice not available: %d\n", ctrl_area->exceptions.nm);
+ PrintDebug("\tDouble Fault: %d\n", ctrl_area->exceptions.df);
+ PrintDebug("\tInvalid TSS: %d\n", ctrl_area->exceptions.ts);
+ PrintDebug("\tSegment not present: %d\n", ctrl_area->exceptions.np);
+ PrintDebug("\tStack: %d\n", ctrl_area->exceptions.ss);
+ PrintDebug("\tGPF: %d\n", ctrl_area->exceptions.gp);
+ PrintDebug("\tPage Fault: %d\n", ctrl_area->exceptions.pf);
+ PrintDebug("\tFloating Point: %d\n", ctrl_area->exceptions.mf);
+ PrintDebug("\tAlignment Check: %d\n", ctrl_area->exceptions.ac);
+ PrintDebug("\tMachine Check: %d\n", ctrl_area->exceptions.mc);
+ PrintDebug("\tSIMD floating point: %d\n", ctrl_area->exceptions.xf);
+ PrintDebug("\tSecurity: %d\n", ctrl_area->exceptions.sx);
+
+ PrintDebug("Instructions bitmap: %.8x (at 0x%.8x)\n", *(uint_t*)&(ctrl_area->instrs), &(ctrl_area->instrs));
+ PrintDebug("\tINTR: %d\n", ctrl_area->instrs.INTR);
+ PrintDebug("\tNMI: %d\n", ctrl_area->instrs.NMI);
+ PrintDebug("\tSMI: %d\n", ctrl_area->instrs.SMI);
+ PrintDebug("\tINIT: %d\n", ctrl_area->instrs.INIT);
+ PrintDebug("\tVINTR: %d\n", ctrl_area->instrs.VINTR);
+ PrintDebug("\tCR0: %d\n", ctrl_area->instrs.CR0);
+ PrintDebug("\tRD_IDTR: %d\n", ctrl_area->instrs.RD_IDTR);
+ PrintDebug("\tRD_GDTR: %d\n", ctrl_area->instrs.RD_GDTR);
+ PrintDebug("\tRD_LDTR: %d\n", ctrl_area->instrs.RD_LDTR);
+ PrintDebug("\tRD_TR: %d\n", ctrl_area->instrs.RD_TR);
+ PrintDebug("\tWR_IDTR: %d\n", ctrl_area->instrs.WR_IDTR);
+ PrintDebug("\tWR_GDTR: %d\n", ctrl_area->instrs.WR_GDTR);
+ PrintDebug("\tWR_LDTR: %d\n", ctrl_area->instrs.WR_LDTR);
+ PrintDebug("\tWR_TR: %d\n", ctrl_area->instrs.WR_TR);
+ PrintDebug("\tRDTSC: %d\n", ctrl_area->instrs.RDTSC);
+ PrintDebug("\tRDPMC: %d\n", ctrl_area->instrs.RDPMC);
+ PrintDebug("\tPUSHF: %d\n", ctrl_area->instrs.PUSHF);
+ PrintDebug("\tPOPF: %d\n", ctrl_area->instrs.POPF);
+ PrintDebug("\tCPUID: %d\n", ctrl_area->instrs.CPUID);
+ PrintDebug("\tRSM: %d\n", ctrl_area->instrs.RSM);
+ PrintDebug("\tIRET: %d\n", ctrl_area->instrs.IRET);
+ PrintDebug("\tINTn: %d\n", ctrl_area->instrs.INTn);
+ PrintDebug("\tINVD: %d\n", ctrl_area->instrs.INVD);
+ PrintDebug("\tPAUSE: %d\n", ctrl_area->instrs.PAUSE);
+ PrintDebug("\tHLT: %d\n", ctrl_area->instrs.HLT);
+ PrintDebug("\tINVLPG: %d\n", ctrl_area->instrs.INVLPG);
+ PrintDebug("\tINVLPGA: %d\n", ctrl_area->instrs.INVLPGA);
+ PrintDebug("\tIOIO_PROT: %d\n", ctrl_area->instrs.IOIO_PROT);
+ PrintDebug("\tMSR_PROT: %d\n", ctrl_area->instrs.MSR_PROT);
+ PrintDebug("\ttask_switch: %d\n", ctrl_area->instrs.task_switch);
+ PrintDebug("\tFERR_FREEZE: %d\n", ctrl_area->instrs.FERR_FREEZE);
+ PrintDebug("\tshutdown_evts: %d\n", ctrl_area->instrs.shutdown_evts);
+
+ PrintDebug("SVM Instruction Bitmap: %.8x (at 0x%.8x)\n", *(uint_t*)&(ctrl_area->svm_instrs), &(ctrl_area->svm_instrs));
+ PrintDebug("\tVMRUN: %d\n", ctrl_area->svm_instrs.VMRUN);
+ PrintDebug("\tVMMCALL: %d\n", ctrl_area->svm_instrs.VMMCALL);
+ PrintDebug("\tVMLOAD: %d\n", ctrl_area->svm_instrs.VMLOAD);
+ PrintDebug("\tVMSAVE: %d\n", ctrl_area->svm_instrs.VMSAVE);
+ PrintDebug("\tSTGI: %d\n", ctrl_area->svm_instrs.STGI);
+ PrintDebug("\tCLGI: %d\n", ctrl_area->svm_instrs.CLGI);
+ PrintDebug("\tSKINIT: %d\n", ctrl_area->svm_instrs.SKINIT);
+ PrintDebug("\tRDTSCP: %d\n", ctrl_area->svm_instrs.RDTSCP);
+ PrintDebug("\tICEBP: %d\n", ctrl_area->svm_instrs.ICEBP);
+ PrintDebug("\tWBINVD: %d\n", ctrl_area->svm_instrs.WBINVD);
+ PrintDebug("\tMONITOR: %d\n", ctrl_area->svm_instrs.MONITOR);
+ PrintDebug("\tMWAIT_always: %d\n", ctrl_area->svm_instrs.MWAIT_always);
+ PrintDebug("\tMWAIT_if_armed: %d\n", ctrl_area->svm_instrs.MWAIT_if_armed);
PrintDebug("TLB_CONTROL: %d\n", ctrl_area->TLB_CONTROL);
- PrintDebug("Guest Control Bitmap: %x (at 0x%.8x)\n", ctrl_area->guest_ctrl.bitmap, &(ctrl_area->guest_ctrl));
- PrintDebug("\tV_TPR: %d\n", ctrl_area->guest_ctrl.ctrls.V_TPR);
- PrintDebug("\tV_IRQ: %d\n", ctrl_area->guest_ctrl.ctrls.V_IRQ);
- PrintDebug("\tV_INTR_PRIO: %d\n", ctrl_area->guest_ctrl.ctrls.V_INTR_PRIO);
- PrintDebug("\tV_IGN_TPR: %d\n", ctrl_area->guest_ctrl.ctrls.V_IGN_TPR);
- PrintDebug("\tV_INTR_MASKING: %d\n", ctrl_area->guest_ctrl.ctrls.V_INTR_MASKING);
- PrintDebug("\tV_INTR_VECTOR: %d\n", ctrl_area->guest_ctrl.ctrls.V_INTR_VECTOR);
+ PrintDebug("Guest Control Bitmap: %x (at 0x%.8x)\n", *(uint_t*)&(ctrl_area->guest_ctrl), &(ctrl_area->guest_ctrl));
+ PrintDebug("\tV_TPR: %d\n", ctrl_area->guest_ctrl.V_TPR);
+ PrintDebug("\tV_IRQ: %d\n", ctrl_area->guest_ctrl.V_IRQ);
+ PrintDebug("\tV_INTR_PRIO: %d\n", ctrl_area->guest_ctrl.V_INTR_PRIO);
+ PrintDebug("\tV_IGN_TPR: %d\n", ctrl_area->guest_ctrl.V_IGN_TPR);
+ PrintDebug("\tV_INTR_MASKING: %d\n", ctrl_area->guest_ctrl.V_INTR_MASKING);
+ PrintDebug("\tV_INTR_VECTOR: %d\n", ctrl_area->guest_ctrl.V_INTR_VECTOR);
PrintDebug("Interrupt_shadow: %d\n", ctrl_area->interrupt_shadow);
tmp_reg.r_reg = ctrl_area->NP_ENABLE;
PrintDebug("NP_ENABLE: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
- tmp_reg.r_reg = ctrl_area->EVENTINJ;
- PrintDebug("EVENTINJ: hi: 0x%.8x, lo: 0x%.8x\n", tmp_reg.e_reg.high, tmp_reg.e_reg.low);
+ PrintDebug("Event Injection: (at 0x%.8x)\n", &(ctrl_area->EVENTINJ));
+ PrintDebug("Vector: %d\n", ctrl_area->EVENTINJ.vector);
+ PrintDebug("(type=%d) (ev=%d) (valid=%d)\n", ctrl_area->EVENTINJ.type,
+ ctrl_area->EVENTINJ.ev, ctrl_area->EVENTINJ.valid);
+ PrintDebug("Error Code: %d\n", ctrl_area->EVENTINJ.error_code);
tmp_reg.r_reg = ctrl_area->N_CR3;
#include <palacios/vmm_intr.h>
+#include <palacios/vm_guest.h>
+int raise_exception(struct guest_info * info, uint_t excp) {
+ /* We can't stack exceptions,
+ but do we need to have some sort of priority?
+ */
+ if (info->intr_state.excp_pending) {
+ info->intr_state.excp_pending = 1;
+ info->intr_state.excp_num = excp;
+ } else {
+ return -1;
+ }
+ return 0;
+}
+
+
+int intr_pending(struct vm_intr * intr) {
+ if (intr->excp_pending) {
+ return 1;
+ }
+
+ /* Check [A]PIC */
+
+ return 0;
+}
+
+
+uint_t get_intr_number(struct vm_intr * intr) {
+ if (intr->excp_pending) {
+ return intr->excp_num;
+ }
+
+ /* someway to get the [A]PIC intr */
+
+ return 0;
+}
+
+
+uint_t get_intr_type(struct vm_intr * intr) {
+ if (intr->excp_pending) {
+ return EXCEPTION;
+ }
+
+ return INVALID_INTR;
+}