From: Jack Lange Date: Wed, 9 Apr 2008 23:58:07 +0000 (+0000) Subject: added the framework for interupt delivery X-Git-Tag: working-cdboot-physical-but-not-qemu~25 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=fc90c3287f85c66e1f6616685b66a8339145c3ee added the framework for interupt delivery --- diff --git a/palacios/build/Makefile b/palacios/build/Makefile index c79201e..59e47a8 100644 --- a/palacios/build/Makefile +++ b/palacios/build/Makefile @@ -1,6 +1,6 @@ # Makefile for GeekOS kernel, userspace, and tools # Copyright (c) 2004,2005 David H. Hovemeyer -# $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". @@ -124,6 +124,7 @@ VMM_ASM_OBJS := $(VMM_ASM_SRCS:%.asm=palacios/%.o) 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 diff --git a/palacios/include/palacios/vm_guest.h b/palacios/include/palacios/vm_guest.h index 4e62449..977356d 100644 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@ -5,7 +5,7 @@ #include #include #include - +#include typedef ullong_t gpr_t; @@ -51,6 +51,9 @@ struct guest_info { // 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 diff --git a/palacios/include/palacios/vmcb.h b/palacios/include/palacios/vmcb.h index 7424880..a61cf89 100644 --- a/palacios/include/palacios/vmcb.h +++ b/palacios/include/palacios/vmcb.h @@ -22,9 +22,7 @@ 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; @@ -41,13 +39,10 @@ union Ctrl_Registers { 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; @@ -64,47 +59,10 @@ union Debug_Registers { 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 @@ -137,13 +95,10 @@ union Exception_Vectors { 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; @@ -176,57 +131,64 @@ union Instr_Intercepts { 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 @@ -240,7 +202,7 @@ typedef struct VMCB_Control_Area { 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 @@ -266,7 +228,7 @@ typedef struct VMCB_Control_Area { 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.... @@ -307,7 +269,8 @@ struct vmcb_selector { 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; diff --git a/palacios/include/palacios/vmm_intr.h b/palacios/include/palacios/vmm_intr.h index 9751807..0b178b0 100644 --- a/palacios/include/palacios/vmm_intr.h +++ b/palacios/include/palacios/vmm_intr.h @@ -1,7 +1,47 @@ #ifndef __VMM_INTR_H #define __VMM_INTR_H +#include +#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 diff --git a/palacios/src/geekos/vm.c b/palacios/src/geekos/vm.c index b1149fb..b8e497b 100644 --- a/palacios/src/geekos/vm.c +++ b/palacios/src/geekos/vm.c @@ -83,7 +83,7 @@ int IO_BOCHS_debug(ushort_t port, void * src, uint_t length) { 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; diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index dec6554..2003ba7 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -180,28 +180,28 @@ void Init_VMCB(vmcb_t * vmcb, struct guest_info vm_info) { //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; @@ -242,10 +242,10 @@ void Init_VMCB(vmcb_t * vmcb, struct guest_info vm_info) { //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; @@ -256,12 +256,12 @@ void Init_VMCB(vmcb_t * vmcb, struct guest_info vm_info) { 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; @@ -302,27 +302,27 @@ void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info vm_info) { 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; @@ -384,7 +384,7 @@ void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info vm_info) { //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; @@ -398,14 +398,14 @@ void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info vm_info) { 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; @@ -489,7 +489,7 @@ void Init_VMCB_pe(vmcb_t *vmcb, struct guest_info vm_info) { 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; @@ -500,24 +500,24 @@ void Init_VMCB_pe(vmcb_t *vmcb, struct guest_info vm_info) { // 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); { @@ -526,7 +526,7 @@ void Init_VMCB_pe(vmcb_t *vmcb, struct guest_info vm_info) { memset((void*)(tmp_reg.e_reg.low), 0xffffffff, PAGE_SIZE * 2); } - ctrl_area->instrs.instrs.INTR = 1; + ctrl_area->instrs.INTR = 1; { @@ -632,18 +632,18 @@ void Init_VMCB_Real(vmcb_t * vmcb, struct guest_info vm_info) { 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; diff --git a/palacios/src/palacios/svm_handler.c b/palacios/src/palacios/svm_handler.c index 15e320f..46b4fa2 100644 --- a/palacios/src/palacios/svm_handler.c +++ b/palacios/src/palacios/svm_handler.c @@ -4,6 +4,7 @@ #include #include #include +#include extern struct vmm_os_hooks * os_hooks; @@ -105,6 +106,40 @@ int handle_svm_exit(struct guest_info * info) { // 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; diff --git a/palacios/src/palacios/vmcb.c b/palacios/src/palacios/vmcb.c index 3933fc1..4c31432 100644 --- a/palacios/src/palacios/vmcb.c +++ b/palacios/src/palacios/vmcb.c @@ -12,80 +12,80 @@ void PrintDebugVMCB(vmcb_t * vmcb) { 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); @@ -100,13 +100,13 @@ void PrintDebugVMCB(vmcb_t * vmcb) { 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); @@ -125,8 +125,11 @@ void PrintDebugVMCB(vmcb_t * vmcb) { 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; diff --git a/palacios/src/palacios/vmm_intr.c b/palacios/src/palacios/vmm_intr.c index c15d68c..464bc79 100644 --- a/palacios/src/palacios/vmm_intr.c +++ b/palacios/src/palacios/vmm_intr.c @@ -1,4 +1,48 @@ #include +#include +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; +}