Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Added functionality for MONITOR and MWAIT instructions on SVM and VMX:
Peter Dinda [Mon, 10 Sep 2012 20:16:21 +0000 (15:16 -0500)]
  - 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

Kconfig
palacios/include/palacios/vmm_mwait.h [new file with mode: 0644]
palacios/src/palacios/Makefile
palacios/src/palacios/svm_handler.c
palacios/src/palacios/vmm_cpuid.c
palacios/src/palacios/vmm_mwait.c [new file with mode: 0644]
palacios/src/palacios/vmx.c
palacios/src/palacios/vmx_handler.c

diff --git a/Kconfig b/Kconfig
index bcf3ef7..1d21516 100644 (file)
--- 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 (file)
index 0000000..2d7939b
--- /dev/null
@@ -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 <pdinda@northwestern.edu> 
+ * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * 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 <palacios/vm_guest.h>
+#include <palacios/vmm.h>
+
+
+int v3_handle_monitor(struct guest_info * info);
+int v3_handle_mwait(struct guest_info * info);
+
+#endif // ! __V3VEE__
+
+#endif
index 4a4b04e..a26f8df 100644 (file)
@@ -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 \
index 4ea49c9..d0adffc 100644 (file)
@@ -25,6 +25,7 @@
 #include <palacios/vmm_ctrl_regs.h>
 #include <palacios/svm_io.h>
 #include <palacios/vmm_halt.h>
+#include <palacios/vmm_mwait.h>
 #include <palacios/svm_pause.h>
 #include <palacios/svm_wbinvd.h>
 #include <palacios/vmm_intr.h>
@@ -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) { 
index 06aac52..bd0862b 100644 (file)
@@ -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 (file)
index 0000000..3196ae2
--- /dev/null
@@ -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 <pdinda@northwestern.edu>
+ * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm_mwait.h>
+
+#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;
+}
index 3fede2b..945ec50 100644 (file)
@@ -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;
index 8f7665d..24e2c8e 100644 (file)
@@ -32,6 +32,7 @@
 #include <palacios/vmx_ctrl_regs.h>
 #include <palacios/vmx_assist.h>
 #include <palacios/vmm_halt.h>
+#include <palacios/vmm_mwait.h>
 #include <palacios/vmx_ept.h>
 
 
@@ -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: