From: Peter Dinda Date: Mon, 10 Sep 2012 20:16:21 +0000 (-0500) Subject: Added functionality for MONITOR and MWAIT instructions on SVM and VMX: X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=adfcd4fddcf65f9ec0e74acff09cf8f88d8ebd0d Added functionality for MONITOR and MWAIT instructions on SVM and VMX: - CPUID now reports that MONITOR/MWAIT is not available - MONITOR and MWAIT are hooked on both VMX and SVM (previously only SVM) - If monitor or mwait are executed, they cause a #UD --- diff --git a/Kconfig b/Kconfig index bcf3ef7..1d21516 100644 --- a/Kconfig +++ b/Kconfig @@ -387,6 +387,13 @@ config DEBUG_HALT help This turns on debugging for the halt instruction handler +config DEBUG_MWAIT + bool "MWAIT/MONITOR" + default n + depends on DEBUG_ON + help + This turns on debugging for the mwait and monitor instruction handlers + config DEBUG_DEV_MGR bool "Device Manager" default n diff --git a/palacios/include/palacios/vmm_mwait.h b/palacios/include/palacios/vmm_mwait.h new file mode 100644 index 0000000..2d7939b --- /dev/null +++ b/palacios/include/palacios/vmm_mwait.h @@ -0,0 +1,34 @@ +/* + * 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) 2012, Peter Dinda + * Copyright (c) 2012, The V3VEE Project + * All rights reserved. + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#ifndef __VMM_MWAIT_H +#define __VMM_MWAIT_H + +#ifdef __V3VEE__ + +#include +#include + + +int v3_handle_monitor(struct guest_info * info); +int v3_handle_mwait(struct guest_info * info); + +#endif // ! __V3VEE__ + +#endif diff --git a/palacios/src/palacios/Makefile b/palacios/src/palacios/Makefile index 4a4b04e..a26f8df 100644 --- a/palacios/src/palacios/Makefile +++ b/palacios/src/palacios/Makefile @@ -11,6 +11,7 @@ obj-y := \ vmm_emulator.o \ vmm_excp.o \ vmm_halt.o \ + vmm_mwait.o \ vmm_hashtable.o \ vmm_host_events.o \ vmm_hypercall.o \ diff --git a/palacios/src/palacios/svm_handler.c b/palacios/src/palacios/svm_handler.c index 4ea49c9..d0adffc 100644 --- a/palacios/src/palacios/svm_handler.c +++ b/palacios/src/palacios/svm_handler.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -257,6 +258,26 @@ int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_i return -1; } break; + + case SVM_EXIT_MONITOR: +#ifdef V3_CONFIG_DEBUG_MWAIT + PrintDebug("Guest issuing MONITOR\n"); +#endif + if (v3_handle_monitor(info) == -1) { + return -1; + } + break; + + case SVM_EXIT_MWAIT: + case SVM_EXIT_MWAIT_CONDITIONAL: +#ifdef V3_CONFIG_DEBUG_MWAIT + PrintDebug("Guest issuing MWAIT\n"); +#endif + if (v3_handle_mwait(info) == -1) { + return -1; + } + break; + case SVM_EXIT_PAUSE: // PrintDebug("Guest paused\n"); if (v3_handle_svm_pause(info) == -1) { diff --git a/palacios/src/palacios/vmm_cpuid.c b/palacios/src/palacios/vmm_cpuid.c index 06aac52..bd0862b 100644 --- a/palacios/src/palacios/vmm_cpuid.c +++ b/palacios/src/palacios/vmm_cpuid.c @@ -43,6 +43,9 @@ void v3_init_cpuid_map(struct v3_vm_info * vm) { // Disable XSAVE (cpuid 0x01, ECX bit 26) v3_cpuid_add_fields(vm, 0x01, 0, 0, 0, 0, (1 << 26), 0, 0, 0); + // Disable MONITOR/MWAIT (cpuid 0x01, ECX bit 3) + v3_cpuid_add_fields(vm, 0x01, 0, 0, 0, 0, (1 << 3), 0, 0, 0); + } diff --git a/palacios/src/palacios/vmm_mwait.c b/palacios/src/palacios/vmm_mwait.c new file mode 100644 index 0000000..3196ae2 --- /dev/null +++ b/palacios/src/palacios/vmm_mwait.c @@ -0,0 +1,50 @@ +/* + * 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) 2012, Peter Dinda + * Copyright (c) 2012, The V3VEE Project + * All rights reserved. + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#include + +#ifndef V3_CONFIG_DEBUG_MWAIT +#undef PrintDebug +#define PrintDebug(fmt, args...) +#endif + + +// +// Currently we disallow mwait in the CPUID field, so we need to raise an exception +// +int v3_handle_mwait(struct guest_info * info) +{ + PrintDebug("Raising undefined opcode due to mwait instruction\n"); + + v3_raise_exception(info, UD_EXCEPTION ); + + return 0; +} + +// +// Currently we disallow mwait in the CPUID field, so we need to raise an exception +// +int v3_handle_monitor(struct guest_info * info) +{ + PrintDebug("Raising undefined opcode due to monitor instruction\n"); + + v3_raise_exception(info, UD_EXCEPTION ); + + return 0; +} diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index 3fede2b..945ec50 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -195,10 +195,17 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) vmx_state->exit_ctrls.save_preempt_timer = 1; } + // we want it to use this when halting vmx_state->pri_proc_ctrls.hlt_exit = 1; + // cpuid tells it that it does not have these instructions + vmx_state->pri_proc_ctrls.monitor_exit = 1; + vmx_state->pri_proc_ctrls.mwait_exit = 1; + // we don't need to handle a pause, although this is where + // we could pull out of a spin lock acquire or schedule to find its partner vmx_state->pri_proc_ctrls.pause_exit = 0; + vmx_state->pri_proc_ctrls.tsc_offset = 1; #ifdef V3_CONFIG_TIME_VIRTUALIZE_TSC vmx_state->pri_proc_ctrls.rdtsc_exit = 1; diff --git a/palacios/src/palacios/vmx_handler.c b/palacios/src/palacios/vmx_handler.c index 8f7665d..24e2c8e 100644 --- a/palacios/src/palacios/vmx_handler.c +++ b/palacios/src/palacios/vmx_handler.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -265,6 +266,25 @@ int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_inf break; + case VMX_EXIT_MONITOR: + PrintDebug("Guest Executing monitor\n"); + + if (v3_handle_monitor(info) == -1) { + PrintError("Error handling monitor instruction\n"); + return -1; + } + + break; + + case VMX_EXIT_MWAIT: + PrintDebug("Guest Executing mwait\n"); + + if (v3_handle_mwait(info) == -1) { + PrintError("Error handling mwait instruction\n"); + return -1; + } + + break; case VMX_EXIT_PAUSE: