From: Kyle Hale Date: Fri, 17 Jun 2011 19:51:21 +0000 (-0500) Subject: minor changes to organization X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=840d15c3a300636e758fcfcf403ae415ffa67816 minor changes to organization --- 840d15c3a300636e758fcfcf403ae415ffa67816 diff --cc Kconfig index 3c98783,71f5f9b..acf7ebf --- a/Kconfig +++ b/Kconfig @@@ -163,66 -163,6 +163,15 @@@ config EXPERIMENTA The purpose of this option is to allow features under development to be committed to the mainline to more easily track changes and provide access to multiple developers - config VNET - depends on EXPERIMENTAL - bool "Enable Vnet in Palacios" - default n - help - Enable the Vnet in Palacios - + +config INSPECTOR + bool "Enable VM inspection" + depends on EXPERIMENTAL + default n + help + Enable inspection framework for vm internal state + - config SW_INTERRUPTS - bool "Enable interception and hooking of software interrupts" - depends on EXPERIMENTAL - default n - help - This feature will cause the VMM to intercept the execution - of software interrupts (i.e. the INTn instruction) and enable - any INT vector to be hooked - - config SWINTR_PASSTHROUGH - bool "Hook all unhandled sofware interrupts for passthrough" - depends on SW_INTERRUPTS - default n - help - If enabled, this will cause all software interrupts - (INT instruction vectors) to be hooked for passthrough. - May reduce performance but useful for debugging. - - config SYSCALL_HIJACK - bool "Enable System Call Hijacking" - depends on SW_INTERRUPTS - default n - help - Enable the VMM to hijack system calls executed by the guest. - If enabled, the VMM will hook execution of INT 80 - (support for Fast-System Calls coming soon) - - config SYSCALL_PASSTHROUGH - bool "Hook all unhandled system calls for passthrough" - depends on SYSCALL_HIJACK - default n - help - If enabled, this option will cause all system calls - that are not explicitly hooked to be hooked for - passthrough. This is useful for debugging. - - config HIJACK_SYSCALL_MSR - bool "Intercept Syscall-related MSR reads & writes" - depends on SYSCALL_HIJACK - default n - help - Allow the VMM to intercept reads and writes to MSRs - related to SYSCALL and SYSENTER instructions. Specifically, - it will intercept R/W to STAR, CSTAR, and LSTAR. + endmenu @@@ -446,22 -402,6 +411,16 @@@ config DEBUG_DEV_MG help This turns on debugging for the device manager - config DEBUG_VNET - depends on EXPERIMENTAL && VNET - bool "Enable Vnet Debug in Palacios" - default n - help - Enable the Vnet debug in Palacios + +config DEBUG_SYSCALL_HIJACK + bool "Enable Syscall Hijack Debug in Palacios" + default n + depends on DEBUG_ON && SYSCALL_HIJACK + help + Enable Debugging printouts for syscall hijacking + code in Palacios + + endmenu diff --cc palacios/include/palacios/vm_guest.h index 1eba744,4360a64..5792543 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@@ -50,11 -50,6 +50,11 @@@ struct v3_sym_core_state; #endif - #ifdef CONFIG_SYSCALL_HIJACK ++#ifdef V3_CONFIG_SYSCALL_HIJACK +#include +#include +#endif + #include @@@ -95,12 -90,6 +95,12 @@@ struct guest_info /* This structure is how we get exceptions for the guest */ struct v3_excp_state excp_state; - #ifdef CONFIG_SYSCALL_HIJACK ++#ifdef V3_CONFIG_SYSCALL_HIJACK + struct v3_syscall_hook_map sc_hook_map; + struct v3_execve_varchunk var_dump; + struct v3_exec_hooks exec_hooks; +#endif + v3_cpu_mode_t cpu_mode; v3_mem_mode_t mem_mode; diff --cc palacios/include/palacios/vmm_ctrl_regs.h index 3cc1932,e072a04..0b3336a --- a/palacios/include/palacios/vmm_ctrl_regs.h +++ b/palacios/include/palacios/vmm_ctrl_regs.h @@@ -27,15 -27,6 +27,20 @@@ #define EFER_MSR 0xc0000080 +// KCH: for system-call interposition - #define STAR_MSR 0xc0000081 - #define LSTAR_MSR 0xc0000082 - #define CSTAR_MSR 0xc0000083 - #define SF_MASK_MSR 0xc0000084 - #define FS_BASE_MSR 0xc0000100 - #define GS_BASE_MSR 0xc0000101 - #define KERN_GS_BASE_MSR 0xc0000102 ++#define STAR_MSR 0xc0000081 /* Legacy mode SYSCALL target */ ++#define LSTAR_MSR 0xc0000082 /* Long mode SYSCALL target */ ++#define CSTAR_MSR 0xc0000083 /* compat mode SYSCALL target */ ++#define SF_MASK_MSR 0xc0000084 /* EFLAGS mask for syscall */ ++#define FS_BASE_MSR 0xc0000100 /* 64-bit FS base */ ++#define GS_BASE_MSR 0xc0000101 /* 64-bit GS base */ ++#define KERN_GS_BASE_MSR 0xc0000102 /* swapGS GS shadow */ ++ ++/* Intel specific */ ++#define IA32_SYSENTER_CS_MSR 0x00000174 ++#define IA32_SYSENTER_ESP_MSR 0x00000175 ++#define IA32_SYSENTER_EIP_MSR 0x00000176 + struct cr0_real { uint_t pe : 1; uint_t mp : 1; @@@ -224,13 -215,6 +229,16 @@@ int v3_handle_cr4_read(struct guest_inf int v3_handle_efer_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data); int v3_handle_efer_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data); +int v3_handle_star_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data); +int v3_handle_star_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data); +int v3_handle_lstar_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data); +int v3_handle_lstar_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data); +int v3_handle_cstar_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data); +int v3_handle_cstar_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data); + ++int v3_handle_seeip_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data); ++int v3_handle_seeip_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data); ++ int v3_handle_vm_cr_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data); int v3_handle_vm_cr_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data); diff --cc palacios/src/extensions/Kconfig index c7b7d69,c7b7d69..22d1dcc --- a/palacios/src/extensions/Kconfig +++ b/palacios/src/extensions/Kconfig @@@ -38,4 -38,4 +38,48 @@@ config EXT_INSPECTO help Provides the inspection extension ++config SW_INTERRUPTS ++ bool "Enable interception and hooking of software interrupts" ++ default n ++ help ++ This feature will cause the VMM to intercept the execution ++ of software interrupts (i.e. the INTn instruction) and enable ++ any INT vector to be hooked ++ ++config SWINTR_PASSTHROUGH ++ bool "Hook all unhandled sofware interrupts for passthrough" ++ depends on SW_INTERRUPTS ++ default n ++ help ++ If enabled, this will cause all software interrupts ++ (INT instruction vectors) to be hooked for passthrough. ++ May reduce performance but useful for debugging. ++ ++config SYSCALL_HIJACK ++ bool "Enable System Call Hijacking" ++ depends on SW_INTERRUPTS ++ default n ++ help ++ Enable the VMM to hijack system calls executed by the guest. ++ If enabled, the VMM will hook execution of INT 80 ++ (support for Fast-System Calls coming soon) ++ ++config SYSCALL_PASSTHROUGH ++ bool "Hook all unhandled system calls for passthrough" ++ depends on SYSCALL_HIJACK ++ default n ++ help ++ If enabled, this option will cause all system calls ++ that are not explicitly hooked to be hooked for ++ passthrough. This is useful for debugging. ++ ++config HIJACK_SYSCALL_MSR ++ bool "Intercept Syscall-related MSR reads & writes" ++ depends on SYSCALL_HIJACK ++ default n ++ help ++ Allow the VMM to intercept reads and writes to MSRs ++ related to SYSCALL and SYSENTER instructions. Specifically, ++ it will intercept R/W to STAR, CSTAR, and LSTAR. ++ endmenu diff --cc palacios/src/extensions/Makefile index ac19202,ab31a13..ca51193 --- a/palacios/src/extensions/Makefile +++ b/palacios/src/extensions/Makefile @@@ -1,5 -1,5 +1,11 @@@ obj-y += null.o - obj-$(CONFIG_EXT_MTRRS) += ext_mtrr.o - obj-$(CONFIG_EXT_VTSC) += ext_vtsc.o - obj-$(CONFIG_EXT_VTIME) += ext_vtime.o - obj-$(CONFIG_EXT_INSPECTOR) += ext_inspector.o + obj-$(V3_CONFIG_EXT_MTRRS) += ext_mtrr.o + obj-$(V3_CONFIG_EXT_VTSC) += ext_vtsc.o + obj-$(V3_CONFIG_EXT_VTIME) += ext_vtime.o + obj-$(V3_CONFIG_EXT_INSPECTOR) += ext_inspector.o ++ ++obj-$(V3_CONFIG_SYSCALL_HIJACK) += vmm_syscall_hijack.o ++obj-$(V3_CONFIG_SYSCALL_HIJACK) += vmm_linux_syscall_map.o ++obj-$(V3_CONFIG_SYSCALL_HIJACK) += vmm_mpi_accel.o ++obj-$(V3_CONFIG_SYSCALL_HIJACK) += vmm_process_environment.o ++obj-$(V3_CONFIG_SYSCALL_HIJACK) += vmm_execve_hook.o diff --cc palacios/src/palacios/Makefile index 672f7aa,4c55738..4985623 --- a/palacios/src/palacios/Makefile +++ b/palacios/src/palacios/Makefile @@@ -65,20 -65,11 +65,10 @@@ obj-$(V3_CONFIG_VMX) += vmx.o - obj-$(CONFIG_INSTRUMENT_VMM) += vmm_instrument.o - obj-$(CONFIG_TELEMETRY) += vmm_telemetry.o + obj-$(V3_CONFIG_TELEMETRY) += vmm_telemetry.o - obj-$(CONFIG_VNET) += vmm_vnet_core.o - - - obj-$(CONFIG_SYMBIOTIC) += vmm_symbiotic.o vmm_symspy.o - obj-$(CONFIG_SYMCALL) += vmm_symcall.o - obj-$(CONFIG_SYMMOD) += vmm_symmod.o - - obj-$(CONFIG_SYSCALL_HIJACK) += vmm_syscall_hijack.o - obj-$(CONFIG_SYSCALL_HIJACK) += vmm_linux_syscall_map.o - obj-$(CONFIG_SYSCALL_HIJACK) += vmm_mpi_accel.o - obj-$(CONFIG_SYSCALL_HIJACK) += vmm_process_environment.o - obj-$(CONFIG_SYSCALL_HIJACK) += vmm_execve_hook.o + obj-$(V3_CONFIG_SYMBIOTIC) += vmm_symbiotic.o vmm_symspy.o + obj-$(V3_CONFIG_SYMCALL) += vmm_symcall.o + obj-$(V3_CONFIG_SYMMOD) += vmm_symmod.o - obj-y += mmu/ diff --cc palacios/src/palacios/svm.c index 5aa0e30,dffbdb8..a2cbbc1 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@@ -135,11 -136,6 +136,11 @@@ static void Init_VMCB_BIOS(vmcb_t * vmc ctrl_area->instrs.PAUSE = 1; ctrl_area->instrs.shutdown_evts = 1; + /* KCH: intercept SW Interrupts (INT instr) */ - #ifdef CONFIG_SW_INTERRUPTS ++#ifdef V3_CONFIG_SW_INTERRUPTS + ctrl_area->instrs.INTn = 1; +#endif + /* DEBUG FOR RETURN CODE */ ctrl_area->exit_code = 1; @@@ -228,22 -224,6 +229,37 @@@ &v3_handle_efer_write, core); - #ifdef CONFIG_HIJACK_MSR - /* KCH: for SYSCALL and SYSENTER interception */ ++#ifdef V3_CONFIG_HIJACK_SYSCALL_MSR ++ /* KCH: we're not hooking these to TRAP them, ++ instead, we're going to catch the target EIP. ++ Hopefully this EIP is the entry point in the ELF located in the ++ vsyscall page. We can inject checks into the code segment such that ++ we don't have to exit on uninteresting system calls. This should ++ give us much better performance than INT 80, and should even obviate ++ the need to deal with software interrupts at all */ + v3_hook_msr(core->vm_info, STAR_MSR, + &v3_handle_star_read, + &v3_handle_star_write, + core); + v3_hook_msr(core->vm_info, LSTAR_MSR, + &v3_handle_lstar_read, + &v3_handle_lstar_write, + core); + v3_hook_msr(core->vm_info, CSTAR_MSR, + &v3_handle_cstar_read, + &v3_handle_cstar_write, + core); ++ ++ /* KCH: this probably isn't necessary, as ++ SYSENTER is only used in legacy mode. In fact, ++ in long mode it results in an illegal instruction ++ exception */ ++ v3_hook_msr(core->vm_info, IA32_SYSENTER_EIP_MSR, ++ &v3_handle_seeip_read, ++ &v3_handle_seeip_write, ++ core); +#endif + if (core->shdw_pg_mode == SHADOW_PAGING) { PrintDebug("Creating initial shadow page table\n"); diff --cc palacios/src/palacios/svm_handler.c index 8822116,a84d2e1..da85eb2 --- a/palacios/src/palacios/svm_handler.c +++ b/palacios/src/palacios/svm_handler.c @@@ -33,9 -33,8 +33,9 @@@ #include #include #include +#include - #ifndef CONFIG_DEBUG_SVM + #ifndef V3_CONFIG_DEBUG_SVM #undef PrintDebug #define PrintDebug(fmt, args...) #endif @@@ -194,18 -193,9 +194,18 @@@ int v3_handle_svm_exit(struct guest_inf } break; } + case VMEXIT_SWINT: +#ifdef CONFIG_DEBUG_INTERRUPTS + PrintDebug("Intercepted SW Interrupt\n"); +#endif + if (v3_handle_swintr(info) == -1) { + PrintError("Error handling software interrupt\n"); + return -1; + } + break; case VMEXIT_INVLPG: if (info->shdw_pg_mode == SHADOW_PAGING) { - #ifdef CONFIG_DEBUG_SHADOW_PAGING + #ifdef V3_CONFIG_DEBUG_SHADOW_PAGING PrintDebug("Invlpg\n"); #endif if (v3_handle_shadow_invlpg(info) == -1) { diff --cc palacios/src/palacios/vm_guest.c index e0d55a5,62d2a94..6f40a87 --- a/palacios/src/palacios/vm_guest.c +++ b/palacios/src/palacios/vm_guest.c @@@ -31,11 -31,6 +31,11 @@@ #include #include - #ifdef CONFIG_SYSCALL_HIJACK ++#ifdef V3_CONFIG_SYSCALL_HIJACK +#include +#include +#endif + v3_cpu_mode_t v3_get_vm_cpu_mode(struct guest_info * info) { @@@ -683,20 -680,6 +685,12 @@@ int v3_init_core(struct guest_info * co v3_init_symbiotic_core(core); #endif +// KCH - #ifdef CONFIG_SYSCALL_HIJACK ++#ifdef V3_CONFIG_SYSCALL_HIJACK + v3_init_exec_hooks(core); + v3_init_mpi_accel(core); - //v3_hook_swintr(core, 0x80, v3_syscall_handler, NULL); - /* hook a poll syscall */ - //v3_hook_syscall(core, 5, v3_sysopen_handler, NULL); - //v3_hook_syscall(core, 21, v3_sysmount_handler, NULL); - //char * args[2]; - //args[0] = "./envtest"; - //args[1] = "LD_PRELOAD=./libcwrap.so"; - //v3_hook_syscall(core, 11, v3_sysexecve_handler, (void*)args); +#endif + // init SVM/VMX diff --cc palacios/src/palacios/vmm_ctrl_regs.c index cc1fac6,d5a8650..4c84e2e --- a/palacios/src/palacios/vmm_ctrl_regs.c +++ b/palacios/src/palacios/vmm_ctrl_regs.c @@@ -582,63 -582,6 +582,78 @@@ int v3_handle_efer_write(struct guest_i return 0; } + +/* KCH: all of the star handlers are for syscall interposition */ +int v3_handle_star_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) { + +#ifdef CONFIG_DEBUG_SYSCALL_HIJACK + PrintDebug("STAR Read\n"); +#endif + + return 0; +} + + +int v3_handle_star_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) { + - #ifdef CONFIG_DEBUG_SYSCALL_HIJACK ++#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK + PrintDebug("STAR Write\n"); +#endif + return 0; +} + + +int v3_handle_lstar_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) { + - #ifdef CONFIG_DEBUG_SYSCALL_HIJACK ++#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK + PrintDebug("LSTAR Read\n"); +#endif + return 0; +} + + +int v3_handle_lstar_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) { + - #ifdef CONFIG_DEBUG_SYSCALL_HIJACK ++#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK ++ ulong_t entry = ((ulong_t)src.hi << 32) | (ulong_t)src.lo; + PrintDebug("LSTAR Write\n"); ++ PrintDebug("\tKernel syscall entry point: 0x%lx\n", entry); +#endif ++ + return 0; +} + + +int v3_handle_cstar_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) { + - #ifdef CONFIG_DEBUG_SYSCALL_HIJACK ++#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK + PrintDebug("CSTAR Read\n"); +#endif + return 0; +} + + +int v3_handle_cstar_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) { + - #ifdef CONFIG_DEBUG_SYSCALL_HIJACK ++#ifdef V3_CONFIG_DEBUG_SYSCALL_HIJACK + PrintDebug("CSTAR Write\n"); +#endif ++ return 0; ++} ++ ++int v3_handle_seeip_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) { ++ /* we don't care about reads */ ++ return 0; ++} ++ ++int v3_handle_seeip_write(struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) { ++#ifdef V3_CONFIG_DEBUG_SYSALL_HIJACK ++ PrintDebug("SYSENTER_EIP Write\n"); ++#endif + return 0; +} + + int v3_handle_vm_cr_read(struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) { /* tell the guest that the BIOS disabled SVM, that way it doesn't get * confused by the fact that CPUID reports SVM as available but it still diff --cc palacios/src/palacios/vmm_intr.c index 46e2c70,8c4e1c2..f8dbd68 --- a/palacios/src/palacios/vmm_intr.c +++ b/palacios/src/palacios/vmm_intr.c @@@ -25,10 -25,8 +25,10 @@@ #include #include +#include +#include - #ifndef CONFIG_DEBUG_INTERRUPTS + #ifndef V3_CONFIG_DEBUG_INTERRUPTS #undef PrintDebug #define PrintDebug(fmt, args...) #endif @@@ -295,127 -294,6 +295,127 @@@ int v3_raise_irq(struct v3_vm_info * vm } +int v3_signal_swintr(struct guest_info * core, int vector) { + struct v3_intr_core_state * intr_state = &(core->intr_core_state); + + PrintDebug("Signaling software interrupt in vmm_intr.c\n"); + PrintDebug("\tINT vector: %d\n", vector); + + intr_state->swintr_posted = 1; + intr_state->swintr_vector = vector; + return 0; +} + + +int v3_handle_swintr(struct guest_info * core) { + + int ret = 0; + void * instr_ptr = NULL; + struct x86_instr instr; + + if (core->mem_mode == PHYSICAL_MEM) { + ret = v3_gpa_to_hva(core, get_addr_linear(core, core->rip, &(core->segments.cs)), (addr_t *)&instr_ptr); + } else { + ret = v3_gva_to_hva(core, get_addr_linear(core, core->rip, &(core->segments.cs)), (addr_t *)&instr_ptr); + } + + if (ret == -1) { + PrintError("V3 SWintr Handler: Could not translate Instruction Address (%p)\n", (void *)core->rip); + return -1; + } + + if (v3_decode(core, (addr_t)instr_ptr, &instr) == -1) { + PrintError("V3 SWintr Handler: Decoding Error\n"); + return -1; + } + + uint8_t vector = instr.dst_operand.operand; + + struct v3_swintr_hook * hook = core->intr_core_state.swintr_hooks[vector]; + if (hook == NULL) { - #ifdef CONFIG_SWINTR_PASSTHROUGH ++#ifdef V3_CONFIG_SWINTR_PASSTHROUGH + if (v3_hook_passthrough_swintr(core, vector) == -1) { + PrintDebug("V3 SWintr Handler: Error hooking passthrough swintr\n"); + return -1; + } + hook = core->intr_core_state.swintr_hooks[vector]; +#else + core->rip += instr.instr_length; + return v3_signal_swintr(core, vector); +#endif + } + + ret = hook->handler(core, vector, NULL); + if (ret == -1) { + PrintDebug("V3 SWintr Handler: Error in swintr hook\n"); + return -1; + } + - /* at some point we may need to prioritize swints ++ /* KCH: at some point we may need to prioritize swints + so that they finish in time for the next - instruction */ ++ instruction... */ + core->rip += instr.instr_length; + return v3_signal_swintr(core, vector); +} + + +static inline struct v3_swintr_hook * get_swintr_hook(struct guest_info * core, uint8_t vector) { + return core->intr_core_state.swintr_hooks[vector]; +} + + +int v3_hook_swintr(struct guest_info * core, + uint8_t vector, + int (*handler)(struct guest_info * core, uint8_t vector, void * priv_data), + void * priv_data) +{ + + struct v3_swintr_hook * hook = (struct v3_swintr_hook *)V3_Malloc(sizeof(struct v3_swintr_hook)); + + if (hook == NULL) { + return -1; + } + + if (get_swintr_hook(core, vector) != NULL) { + PrintError("SWINT %d already hooked\n", vector); + return -1; + } + + hook->handler = handler; + hook->priv_data = priv_data; + + core->intr_core_state.swintr_hooks[vector] = hook; + + return 0; +} + + +static int passthrough_swintr_handler(struct guest_info * core, uint8_t vector, void * priv_data) { + + PrintDebug("[passthrough_swint_handler] INT vector=%d (guest=0x%p)\n", + vector, (void *)core); + + return 0; +} + + +int v3_hook_passthrough_swintr(struct guest_info * core, uint8_t vector) { + + int rc = v3_hook_swintr(core, vector, passthrough_swintr_handler, NULL); + + if (rc) { + PrintError("guest_swintr_injection: failed to hook swint 0x%x (guest=0x%p)\n", vector, (void *)core); + return -1; + } else { + PrintDebug("guest_swintr_injection: hooked swint 0x%x (guest=0x%p)\n", vector, (void *)core); + return 0; + } + + /* shouldn't get here */ + return 0; +} + + void v3_clear_pending_intr(struct guest_info * core) { struct v3_intr_core_state * intr_state = &(core->intr_core_state);