From: Jack Lange Date: Fri, 20 Mar 2009 22:05:02 +0000 (-0500) Subject: moved exception tracking out of the interrupt state and into a seperate data structure X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=4db5b116275d135e67c67b0781fc8c184e884001 moved exception tracking out of the interrupt state and into a seperate data structure --- diff --git a/palacios/build/Makefile b/palacios/build/Makefile index de62095..0fcc358 100644 --- a/palacios/build/Makefile +++ b/palacios/build/Makefile @@ -62,8 +62,7 @@ endif ifeq ($(DEBUG_ALL),1) - DEBUG_SECTIONS:= $(DEBUG_SECTIONS) -DDEBUG_SHADOW_PAGING -DDEBUG_CTRL_REGS -DDEBUG_INTERRUPTS -DDEBUG_KEYBOARD -DDEBUG_PIC -DDEBUG_PIT -DDEBUG_NVRAM -DDEBUG_EMULATOR -DDEBUG_XED -DDEBUG_HALT -DDEBUG_DEV_MGR -# -DDEBUG_IO -DDEBUG_GENERIC -DDEBUG_RAMDISK + DEBUG_SECTIONS:= $(DEBUG_SECTIONS) -DDEBUG_SHADOW_PAGING -DDEBUG_CTRL_REGS -DDEBUG_INTERRUPTS -DDEBUG_KEYBOARD -DDEBUG_PIC -DDEBUG_PIT -DDEBUG_NVRAM -DDEBUG_EMULATOR -DDEBUG_XED -DDEBUG_HALT -DDEBUG_DEV_MGR -DDEBUG_IO -DDEBUG_GENERIC -DDEBUG_RAMDISK endif @@ -271,6 +270,7 @@ VMM_OBJS := \ palacios/vmm_debug.o \ palacios/svm_io.o \ palacios/vmm_intr.o \ + palacios/vmm_excp.o \ palacios/vmm_time.o \ palacios/vmm_shadow_paging.o \ palacios/vm_guest_mem.o \ diff --git a/palacios/include/palacios/vm_guest.h b/palacios/include/palacios/vm_guest.h index 23329eb..005d32b 100644 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -135,6 +136,9 @@ struct guest_info { // This structure is how we get interrupts for the guest struct v3_intr_state intr_state; + // This structure is how we get exceptions for the guest + struct v3_excp_state excp_state; + v3_io_map_t io_map; struct v3_msr_map msr_map; diff --git a/palacios/include/palacios/vmm_excp.h b/palacios/include/palacios/vmm_excp.h new file mode 100644 index 0000000..9e15e32 --- /dev/null +++ b/palacios/include/palacios/vmm_excp.h @@ -0,0 +1,74 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2008, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#ifndef __VMM_EXCP_H__ +#define __VMM_EXCP_H__ + +#ifdef __V3VEE__ + + +#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 + + +struct guest_info; + +struct v3_excp_state { + + /* We need to rework the exception state, to handle stacking */ + uint_t excp_pending; + uint_t excp_num; + uint_t excp_error_code_valid : 1; + uint_t excp_error_code; + +}; + + +void v3_init_exception_state(struct guest_info * info); + + +int v3_raise_exception(struct guest_info * info, uint_t excp); +int v3_raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code); + +int v3_excp_pending(struct guest_info * info); +int v3_get_excp_number(struct guest_info * info); +int v3_injecting_excp(struct guest_info * info, uint_t excp); + +#endif + +#endif diff --git a/palacios/include/palacios/vmm_intr.h b/palacios/include/palacios/vmm_intr.h index be407c1..82de275 100644 --- a/palacios/include/palacios/vmm_intr.h +++ b/palacios/include/palacios/vmm_intr.h @@ -26,28 +26,9 @@ #include #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_INTR, VIRTUAL_INTR} intr_type_t; + + +typedef enum {INVALID_INTR, EXTERNAL_IRQ, NMI, SOFTWARE_INTR, VIRTUAL_INTR} intr_type_t; struct guest_info; struct v3_interrupt; @@ -65,15 +46,8 @@ struct v3_irq_hook { struct v3_intr_state { - /* We need to rework the exception state, to handle stacking */ - uint_t excp_pending; - uint_t excp_num; - uint_t excp_error_code_valid : 1; - uint_t excp_error_code; - struct list_head controller_list; - uint_t irq_pending; uint_t irq_vector; @@ -102,12 +76,8 @@ struct intr_ctrl_ops { - void v3_register_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state); -int v3_raise_exception(struct guest_info * info, uint_t excp); -int v3_raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code); - int v3_intr_pending(struct guest_info * info); uint_t v3_get_intr_number(struct guest_info * info); intr_type_t v3_get_intr_type(struct guest_info * info); diff --git a/palacios/src/palacios/svm_handler.c b/palacios/src/palacios/svm_handler.c index 5afadae..7c278d3 100644 --- a/palacios/src/palacios/svm_handler.c +++ b/palacios/src/palacios/svm_handler.c @@ -74,10 +74,7 @@ int v3_handle_svm_exit(struct guest_info * info) { if ((info->intr_state.irq_pending == 1) && (guest_ctrl->guest_ctrl.V_IRQ == 0)) { // Interrupt was taken in the guest #ifdef DEBUG_INTERRUPTS - if ((info->intr_state.irq_vector == 238) || - (info->intr_state.irq_vector == 239)) { PrintDebug("Interrupt %d taken by guest\n", info->intr_state.irq_vector); - } #endif v3_injecting_intr(info, info->intr_state.irq_vector, EXTERNAL_IRQ); } @@ -350,7 +347,29 @@ int v3_handle_svm_exit(struct guest_info * info) { // Update the low level state - if (v3_intr_pending(info)) { + if (v3_excp_pending(info)) { + uint_t excp = v3_get_excp_number(info); + + guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION; + + if (info->excp_state.excp_error_code_valid) { + guest_ctrl->EVENTINJ.error_code = info->excp_state.excp_error_code; + guest_ctrl->EVENTINJ.ev = 1; +#ifdef DEBUG_INTERRUPTS + PrintDebug("Injecting exception %d with error code %x\n", excp, guest_ctrl->EVENTINJ.error_code); +#endif + } + + guest_ctrl->EVENTINJ.vector = excp; + + guest_ctrl->EVENTINJ.valid = 1; +#ifdef DEBUG_INTERRUPTS + PrintDebug("Injecting Exception %d (EIP=%p)\n", + guest_ctrl->EVENTINJ.vector, + (void *)(addr_t)info->rip); +#endif + v3_injecting_excp(info, excp); + } else if (v3_intr_pending(info)) { switch (v3_get_intr_type(info)) { case EXTERNAL_IRQ: { @@ -358,11 +377,6 @@ int v3_handle_svm_exit(struct guest_info * info) { // check to see if ==-1 (non exists) - /* - guest_ctrl->EVENTINJ.vector = irq; - guest_ctrl->EVENTINJ.valid = 1; - guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR; - */ guest_ctrl->guest_ctrl.V_IRQ = 1; guest_ctrl->guest_ctrl.V_INTR_VECTOR = irq; @@ -370,11 +384,9 @@ int v3_handle_svm_exit(struct guest_info * info) { guest_ctrl->guest_ctrl.V_INTR_PRIO = 0xf; #ifdef DEBUG_INTERRUPTS - if ((irq == 238) || (irq == 239)) { - PrintDebug("Injecting Interrupt %d (EIP=%p)\n", - guest_ctrl->guest_ctrl.V_INTR_VECTOR, - (void *)(addr_t)info->rip); - } + PrintDebug("Injecting Interrupt %d (EIP=%p)\n", + guest_ctrl->guest_ctrl.V_INTR_VECTOR, + (void *)(addr_t)info->rip); #endif info->intr_state.irq_pending = 1; @@ -385,32 +397,6 @@ int v3_handle_svm_exit(struct guest_info * info) { case NMI: guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI; break; - case EXCEPTION: { - uint_t excp = v3_get_intr_number(info); - - guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION; - - if (info->intr_state.excp_error_code_valid) { //PAD - guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code; - guest_ctrl->EVENTINJ.ev = 1; -#ifdef DEBUG_INTERRUPTS - // PrintDebug("Injecting exception %d with error code %x\n", excp, guest_ctrl->EVENTINJ.error_code); -#endif - } - - guest_ctrl->EVENTINJ.vector = excp; - - guest_ctrl->EVENTINJ.valid = 1; -#ifdef DEBUG_INTERRUPTS - /* - PrintDebug("Injecting Exception %d (EIP=%p)\n", - guest_ctrl->EVENTINJ.vector, - (void *)(addr_t)info->rip); - */ -#endif - v3_injecting_intr(info, excp, EXCEPTION); - break; - } case SOFTWARE_INTR: guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR; break; diff --git a/palacios/src/palacios/vmm_excp.c b/palacios/src/palacios/vmm_excp.c new file mode 100644 index 0000000..ea6cdc5 --- /dev/null +++ b/palacios/src/palacios/vmm_excp.c @@ -0,0 +1,98 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2008, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#include +#include +#include + +void v3_init_exception_state(struct guest_info * info) { + info->excp_state.excp_pending = 0; + info->excp_state.excp_num = 0; + info->excp_state.excp_error_code = 0; + +} + + + +int v3_raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code) { + struct v3_excp_state * excp_state = &(info->excp_state); + + if (excp_state->excp_pending == 0) { + excp_state->excp_pending = 1; + excp_state->excp_num = excp; + excp_state->excp_error_code = error_code; + excp_state->excp_error_code_valid = 1; + // PrintDebug("[v3_raise_exception_with_error] error code: %x\n", error_code); + } else { + PrintError("exception already pending, currently not implemented\n"); + return -1; + } + + return 0; +} + +int v3_raise_exception(struct guest_info * info, uint_t excp) { + struct v3_excp_state * excp_state = &(info->excp_state); + //PrintDebug("[v3_raise_exception]\n"); + if (excp_state->excp_pending == 0) { + excp_state->excp_pending = 1; + excp_state->excp_num = excp; + excp_state->excp_error_code = 0; + excp_state->excp_error_code_valid = 0; + } else { + PrintError("exception already pending, currently not implemented\n"); + return -1; + } + + return 0; +} + + +int v3_excp_pending(struct guest_info * info) { + struct v3_excp_state * excp_state = &(info->excp_state); + + if (excp_state->excp_pending == 1) { + return 1; + } + + return 0; +} + + +int v3_get_excp_number(struct guest_info * info) { + struct v3_excp_state * excp_state = &(info->excp_state); + + if (excp_state->excp_pending == 1) { + return excp_state->excp_num; + } + + return 0; +} + + +int v3_injecting_excp(struct guest_info * info, uint_t excp) { + struct v3_excp_state * excp_state = &(info->excp_state); + + excp_state->excp_pending = 0; + excp_state->excp_num = 0; + excp_state->excp_error_code = 0; + excp_state->excp_error_code_valid = 0; + + return 0; +} diff --git a/palacios/src/palacios/vmm_intr.c b/palacios/src/palacios/vmm_intr.c index ce21ff3..953df0e 100644 --- a/palacios/src/palacios/vmm_intr.c +++ b/palacios/src/palacios/vmm_intr.c @@ -40,14 +40,10 @@ struct intr_controller { void v3_init_interrupt_state(struct guest_info * info) { - info->intr_state.excp_pending = 0; - info->intr_state.excp_num = 0; - info->intr_state.excp_error_code = 0; info->intr_state.irq_pending = 0; info->intr_state.irq_vector = 0; - INIT_LIST_HEAD(&(info->intr_state.controller_list)); memset((uchar_t *)(info->intr_state.hooks), 0, sizeof(struct v3_irq_hook *) * 256); @@ -147,39 +143,6 @@ int v3_deliver_irq(struct guest_info * info, struct v3_interrupt * intr) { -int v3_raise_exception_with_error(struct guest_info * info, uint_t excp, uint_t error_code) { - struct v3_intr_state * intr_state = &(info->intr_state); - - if (intr_state->excp_pending == 0) { - intr_state->excp_pending = 1; - intr_state->excp_num = excp; - intr_state->excp_error_code = error_code; - intr_state->excp_error_code_valid = 1; - // PrintDebug("[v3_raise_exception_with_error] error code: %x\n", error_code); - } else { - PrintError("exception already pending, currently not implemented\n"); - return -1; - } - - return 0; -} - -int v3_raise_exception(struct guest_info * info, uint_t excp) { - struct v3_intr_state * intr_state = &(info->intr_state); - //PrintDebug("[v3_raise_exception]\n"); - if (intr_state->excp_pending == 0) { - intr_state->excp_pending = 1; - intr_state->excp_num = excp; - intr_state->excp_error_code = 0; - intr_state->excp_error_code_valid = 0; - } else { - PrintError("exception already pending, currently not implemented\n"); - return -1; - } - - return 0; -} - int v3_lower_irq(struct guest_info * info, int irq) { struct intr_controller * ctrl = NULL; @@ -211,61 +174,45 @@ int v3_raise_irq(struct guest_info * info, int irq) { int v3_intr_pending(struct guest_info * info) { struct v3_intr_state * intr_state = &(info->intr_state); - + struct intr_controller * ctrl = NULL; // PrintDebug("[intr_pending]\n"); - if (intr_state->excp_pending == 1) { - return 1; - } else { - struct intr_controller * ctrl = NULL; - list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) { - if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) { - return 1; - } + list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) { + if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) { + return 1; } } + return 0; } uint_t v3_get_intr_number(struct guest_info * info) { struct v3_intr_state * intr_state = &(info->intr_state); + struct intr_controller * ctrl = NULL; - if (intr_state->excp_pending == 1) { - return intr_state->excp_num; - } else { - struct intr_controller * ctrl = NULL; - - list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) { - if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data)) { - uint_t intr_num = ctrl->ctrl_ops->get_intr_number(ctrl->priv_data); - - // PrintDebug("[get_intr_number] intr_number = %d\n", intr_num); - - return intr_num; - } + list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) { + if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data)) { + uint_t intr_num = ctrl->ctrl_ops->get_intr_number(ctrl->priv_data); + + // PrintDebug("[get_intr_number] intr_number = %d\n", intr_num); + + return intr_num; } } - return 0; } intr_type_t v3_get_intr_type(struct guest_info * info) { struct v3_intr_state * intr_state = &(info->intr_state); + struct intr_controller * ctrl = NULL; - if (intr_state->excp_pending) { - // PrintDebug("[get_intr_type] Exception\n"); - return EXCEPTION; - } else { - struct intr_controller * ctrl = NULL; - - list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) { - if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) { - //PrintDebug("[get_intr_type] External_irq\n"); - return EXTERNAL_IRQ; - } + list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) { + if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) { + //PrintDebug("[get_intr_type] External_irq\n"); + return EXTERNAL_IRQ; } } @@ -281,14 +228,7 @@ intr_type_t v3_get_intr_type(struct guest_info * info) { int v3_injecting_intr(struct guest_info * info, uint_t intr_num, intr_type_t type) { struct v3_intr_state * intr_state = &(info->intr_state); - if (type == EXCEPTION) { - // PrintDebug("[injecting_intr] Exception\n"); - intr_state->excp_pending = 0; - intr_state->excp_num = 0; - intr_state->excp_error_code = 0; - intr_state->excp_error_code_valid = 0; - - } else if (type == EXTERNAL_IRQ) { + if (type == EXTERNAL_IRQ) { struct intr_controller * ctrl = NULL; // PrintDebug("[injecting_intr] External_Irq with intr_num = %x\n", intr_num);