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 profiling support
Jack Lange [Thu, 29 Jan 2009 04:57:09 +0000 (22:57 -0600)]
and also added license to some files

16 files changed:
geekos/src/geekos/vm.c
palacios/build/Makefile
palacios/include/palacios/svm_handler.h
palacios/include/palacios/vm_guest.h
palacios/include/palacios/vmm.h
palacios/include/palacios/vmm_decoder.h
palacios/include/palacios/vmm_hashtable.h
palacios/include/palacios/vmm_instr_emulator.h
palacios/include/palacios/vmm_profiler.h [new file with mode: 0644]
palacios/src/palacios/svm.c
palacios/src/palacios/svm_handler.c
palacios/src/palacios/vmm_config.c
palacios/src/palacios/vmm_hashtable.c
palacios/src/palacios/vmm_paging_debug.h
palacios/src/palacios/vmm_profiler.c [new file with mode: 0644]
palacios/src/palacios/vmm_shadow_paging.c

index c391c63..17c3499 100644 (file)
@@ -106,6 +106,8 @@ int RunVMM(struct Boot_Info * bootInfo) {
     vm_config.rombios_size = rombios->length;
     
     region_start += rombios->length;
+
+    vm_config.enable_profiling = 1;
     
     vm_config.vgabios = region_start;
     vm_config.vgabios_size = vgabios->length;
index 3969547..c50323e 100644 (file)
@@ -267,6 +267,7 @@ VMM_OBJS := \
        palacios/vmm_socket.o \
        palacios/vmm_xed.o \
        palacios/vmm_rbtree.o \
+       palacios/vmm_profiler.o \
 
 #              vmx.c vmcs_gen.c vmcs.c
 
index e2425ac..4cab37c 100644 (file)
 
 
 int v3_handle_svm_exit(struct guest_info * info);
+const uchar_t * vmexit_code_to_str(uint_t exit_code);
+
 
 #endif // ! __V3VEE__
 
index 271bbb9..7871eb0 100644 (file)
@@ -32,6 +32,7 @@
 #include <palacios/vmm_emulator.h>
 #include <palacios/vmm_host_events.h>
 #include <palacios/vmm_msr.h>
+#include <palacios/vmm_profiler.h>
 
 
 
@@ -97,11 +98,9 @@ struct v3_segments {
 };
 
 struct shadow_page_state;
-struct shadow_map;
-struct vmm_io_map;
 struct emulation_state;
 struct v3_intr_state;
-
+struct v3_profiler;
 
 
 
@@ -149,6 +148,9 @@ struct guest_info {
   void * vmm_data;
 
 
+  uint_t enable_profiler;
+  struct v3_profiler profiler;
+
   void * decoder_state;
 
   struct v3_msr guest_efer;
index 549ccb1..9fae52e 100644 (file)
@@ -258,6 +258,9 @@ struct v3_vm_config {
                           // so we can specify maximum physical address size
                           // (We're screwed if we want to do 32 bit host/64 bit guest)
 
+
+  int enable_profiling;
+
   int use_ramdisk;
   void * ramdisk;
   int ramdisk_size;
index ff70106..0ae0109 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * This file is part of the Palacios Virtual Machine Monitor developed
  * by the V3VEE Project with funding from the United States National 
index a51c53a..5acb89e 100644 (file)
@@ -104,18 +104,18 @@ ulong_t hash_buffer(uchar_t * msg, uint_t length);
 
 
 #define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype)            \
-  int fnname (struct hashtable * htable, keytype key, valuetype value) { \
-    return hashtable_insert(htable, (addr_t)key, (addr_t)value);               \
+  static int fnname (struct hashtable * htable, keytype key, valuetype value) { \
+    return hashtable_insert(htable, (addr_t)key, (addr_t)value);       \
   }
 
 #define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype)            \
-  valuetype * fnname (struct hashtable * htable, keytype  key) {       \
-    return (valuetype *) (hashtable_search(htable, (addr_t)key));              \
+  static valuetype * fnname (struct hashtable * htable, keytype  key) {        \
+    return (valuetype *) (hashtable_search(htable, (addr_t)key));      \
   }
 
 #define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype, free_key)  \
-  valuetype * fnname (struct hashtable * htable, keytype key) {        \
-    return (valuetype *) (hashtable_remove(htable, (addr_t)key, free_key));    \
+  static valuetype * fnname (struct hashtable * htable, keytype key) { \
+    return (valuetype *) (hashtable_remove(htable, (addr_t)key, free_key)); \
   }
 
 
@@ -154,6 +154,11 @@ addr_t hashtable_remove(struct hashtable * htable, addr_t key, int free_key);
 
 uint_t hashtable_count(struct hashtable * htable);
 
+// Specialty functions for a counting hashtable 
+int hashtable_inc(struct hashtable * htable, addr_t key, addr_t value);
+int hashtable_dec(struct hashtable * htable, addr_t key, addr_t value);
+
+
   /* ************ */
  /* ITERATOR API */
 /* ************ */
index 74701a5..a971805 100644 (file)
@@ -1,3 +1,22 @@
+/*
+ * 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 <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.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_types.h>
 
 
diff --git a/palacios/include/palacios/vmm_profiler.h b/palacios/include/palacios/vmm_profiler.h
new file mode 100644 (file)
index 0000000..b083232
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * 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 <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef __VMM_PROFILER_H__
+#define __VMM_PROFILER_H__
+
+#ifdef __V3VEE__
+
+#include <palacios/vmm_rbtree.h>
+
+struct guest_info;
+
+
+struct v3_profiler {
+  uint_t total_exits;
+
+  ullong_t start_time;
+  ullong_t end_time;
+
+  struct rb_root root;
+};
+
+
+void v3_init_profiler(struct guest_info * info);
+
+void v3_profile_exit(struct guest_info * info, uint_t exit_code);
+
+void v3_print_profile(struct guest_info * info);
+
+
+#endif
+
+#endif
index f5489c3..986bec8 100644 (file)
@@ -39,6 +39,8 @@
 
 #include <palacios/vmm_rbtree.h>
 
+#include <palacios/vmm_profiler.h>
+
 
 extern void v3_stgi();
 extern void v3_clgi();
@@ -352,7 +354,6 @@ static int start_svm_guest(struct guest_info *info) {
     ullong_t tmp_tsc;
     uint_t vm_cr_low = 0, vm_cr_high = 0;
 
-
     v3_enable_ints();
     v3_clgi();
 
@@ -384,10 +385,12 @@ static int start_svm_guest(struct guest_info *info) {
     v3_stgi();
 
 
-    if (num_exits % 25 == 0) {
+    if ((num_exits % 1000) == 0) {
       PrintDebug("SVM Exit number %d\n", num_exits);
+      v3_print_profile(info);
     }
 
+
      
     if (v3_handle_svm_exit(info) != 0) {
       vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
@@ -416,10 +419,6 @@ static int start_svm_guest(struct guest_info *info) {
       }
       v3_print_GPRs(info);
 
-
-      
-
-
       PrintDebug("SVM Exit Code: %p\n", (void *)(addr_t)guest_ctrl->exit_code); 
       
       PrintDebug("exit_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
@@ -442,6 +441,7 @@ static int start_svm_guest(struct guest_info *info) {
 
       break;
     }
+
   }
   return 0;
 }
index 1f834a6..8424137 100644 (file)
 #include <palacios/vmm_intr.h>
 #include <palacios/vmm_emulator.h>
 #include <palacios/svm_msr.h>
+#include <palacios/vmm_profiler.h>
 
 
 
-static const uchar_t * vmexit_code_to_str(uint_t exit_code);
-
 
 int v3_handle_svm_exit(struct guest_info * info) {
   vmcb_ctrl_t * guest_ctrl = 0;
@@ -69,7 +68,10 @@ int v3_handle_svm_exit(struct guest_info * info) {
 
 
   exit_code = guest_ctrl->exit_code;
+
+
+
+  
 
   // Disable printing io exits due to bochs debug messages
   //if (!((exit_code == VMEXIT_IOIO) && ((ushort_t)(guest_ctrl->exit_info1 >> 16) == 0x402))) {
@@ -106,12 +108,10 @@ int v3_handle_svm_exit(struct guest_info * info) {
   }
 
 
-    //  }
-  // PrintDebugVMCB((vmcb_t*)(info->vmm_data));
-
 
-  // PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
-  //PrintDebug("RIP: %x\n", guest_state->rip);
+  if (info->enable_profiler) {
+    rdtscll(info->profiler.start_time);
+  }
 
   
   //PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
@@ -429,6 +429,13 @@ int v3_handle_svm_exit(struct guest_info * info) {
   // END OF SWITCH (EXIT_CODE)
 
 
+  if (info->enable_profiler) {
+    rdtscll(info->profiler.end_time);
+    v3_profile_exit(info, exit_code);
+  }
+      
+
+
   // Update the low level state
 
   if (v3_intr_pending(info)) {
index 82f34e2..180a618 100644 (file)
@@ -22,6 +22,8 @@
 #include <palacios/vmm_debug.h>
 #include <palacios/vmm_msr.h>
 #include <palacios/vmm_decoder.h>
+#include <palacios/vmm_profiler.h>
+#include <palacios/vmm_mem.h>
 
 #include <devices/serial.h>
 #include <devices/keyboard.h>
@@ -34,6 +36,7 @@
 #include <devices/bochs_debug.h>
 
 
+
 #include <palacios/vmm_host_events.h>
 
 #define USE_GENERIC 1
@@ -99,6 +102,14 @@ int v3_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr)
   setup_devices(info, config_ptr);
  
 
+
+  if (config_ptr->enable_profiling) {
+    info->enable_profiler = 1;
+    v3_init_profiler(info);
+  } else {
+    info->enable_profiler = 0;
+  }
+
   //v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
 
   // Setup initial cpu register state
index 612ae78..fa9aba3 100644 (file)
@@ -394,6 +394,55 @@ int hashtable_change(struct hashtable * htable, addr_t key, addr_t value, int fr
 
 
 
+int hashtable_inc(struct hashtable * htable, addr_t key, addr_t value) {
+    struct hash_entry * tmp_entry;
+    uint_t hash_value;
+    uint_t index;
+
+    hash_value = do_hash(htable, key);
+
+    index = indexFor(htable->table_length, hash_value);
+
+    tmp_entry = htable->table[index];
+
+    while (tmp_entry != NULL) {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hash_value == tmp_entry->hash) && (htable->eq_fn(key, tmp_entry->key))) {
+
+         tmp_entry->value += value;
+         return -1;
+        }
+        tmp_entry = tmp_entry->next;
+    }
+    return 0;
+}
+
+
+int hashtable_dec(struct hashtable * htable, addr_t key, addr_t value) {
+    struct hash_entry * tmp_entry;
+    uint_t hash_value;
+    uint_t index;
+
+    hash_value = do_hash(htable, key);
+
+    index = indexFor(htable->table_length, hash_value);
+
+    tmp_entry = htable->table[index];
+
+    while (tmp_entry != NULL) {
+        /* Check hash value to short circuit heavier comparison */
+        if ((hash_value == tmp_entry->hash) && (htable->eq_fn(key, tmp_entry->key))) {
+
+         tmp_entry->value -= value;
+         return -1;
+        }
+        tmp_entry = tmp_entry->next;
+    }
+    return 0;
+}
+
+
+
 
 /*****************************************************************************/
 /* returns value associated with key */
index cba22a8..21817a3 100644 (file)
@@ -1,3 +1,21 @@
+/*
+ * 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 <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
 
 #ifdef USE_VMM_PAGING_DEBUG
 
diff --git a/palacios/src/palacios/vmm_profiler.c b/palacios/src/palacios/vmm_profiler.c
new file mode 100644 (file)
index 0000000..362b8c9
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * 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 <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.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_types.h>
+#include <palacios/vmm_profiler.h>
+#include <palacios/svm_handler.h>
+#include <palacios/vmm_rbtree.h>
+
+
+struct exit_event {
+  uint_t exit_code;
+  uint_t exit_count;
+  uint_t handler_time;
+
+  struct rb_node tree_node;
+};
+
+
+void v3_init_profiler(struct guest_info * info) {
+  info->profiler.total_exits = 0;
+
+  info->profiler.start_time = 0;
+  info->profiler.end_time = 0;  
+
+  info->profiler.root.rb_node = NULL;
+}
+
+
+
+static inline struct exit_event * __insert_event(struct guest_info * info, 
+                                                struct exit_event * evt) {
+  struct rb_node ** p = &(info->profiler.root.rb_node);
+  struct rb_node * parent = NULL;
+  struct exit_event * tmp_evt = NULL;
+
+  while (*p) {
+    parent = *p;
+    tmp_evt = rb_entry(parent, struct exit_event, tree_node);
+
+    if (evt->exit_code < tmp_evt->exit_code) {
+      p = &(*p)->rb_left;
+    } else if (evt->exit_code > tmp_evt->exit_code) {
+      p = &(*p)->rb_right;
+    } else {
+      return tmp_evt;
+    }
+  }
+  rb_link_node(&(evt->tree_node), parent, p);
+
+  return NULL;
+}
+
+static inline struct exit_event * insert_event(struct guest_info * info, 
+                                              struct exit_event * evt) {
+  struct exit_event * ret;
+
+  if ((ret = __insert_event(info, evt))) {
+    return ret;
+  }
+
+  v3_rb_insert_color(&(evt->tree_node), &(info->profiler.root));
+
+  return NULL;
+}
+
+
+static struct exit_event * get_exit(struct guest_info * info, uint_t exit_code) {
+  struct rb_node * n = info->profiler.root.rb_node;
+  struct exit_event * evt = NULL;
+
+  while (n) {
+    evt = rb_entry(n, struct exit_event, tree_node);
+    
+    if (exit_code < evt->exit_code) {
+      n = n->rb_left;
+    } else if (exit_code > evt->exit_code) {
+      n = n->rb_right;
+    } else {
+      return evt;
+    }
+  }
+
+  return NULL;
+}
+
+
+static inline struct exit_event * create_exit(uint_t exit_code) {
+  struct exit_event * evt = V3_Malloc(sizeof(struct exit_event));
+
+  evt->exit_code = exit_code;
+  evt->exit_count = 0;
+  evt->handler_time = 0;
+
+  return evt;
+}
+
+void v3_profile_exit(struct guest_info * info, uint_t exit_code) {
+  uint_t time = (info->profiler.end_time - info->profiler.start_time);
+  struct exit_event * evt = get_exit(info, exit_code);
+
+  if (evt == NULL) {
+    evt = create_exit(exit_code);
+    insert_event(info, evt);
+  }
+
+  evt->handler_time += time;
+  evt->exit_count++;
+  
+  info->profiler.total_exits++;
+}
+
+
+void v3_print_profile(struct guest_info * info) {
+  struct exit_event * evt = NULL;
+  struct rb_node * node = v3_rb_first(&(info->profiler.root));
+  
+  do {
+    evt = rb_entry(node, struct exit_event, tree_node);
+
+    PrintDebug("%s: Cnt=%u, Time=%u\n", 
+              vmexit_code_to_str(evt->exit_code),
+              evt->exit_count,
+              evt->handler_time);
+              
+  } while ((node = v3_rb_next(node)));
+}
index 198d17e..9b89157 100644 (file)
@@ -62,14 +62,14 @@ struct shadow_page_data {
 
 
 
-DEFINE_HASHTABLE_INSERT(add_cr3_to_cache, addr_t, struct hashtable *);
-DEFINE_HASHTABLE_SEARCH(find_cr3_in_cache, addr_t, struct hashtable *);
-DEFINE_HASHTABLE_REMOVE(del_cr3_from_cache, addr_t, struct hashtable *, 0);
+//DEFINE_HASHTABLE_INSERT(add_cr3_to_cache, addr_t, struct hashtable *);
+//DEFINE_HASHTABLE_SEARCH(find_cr3_in_cache, addr_t, struct hashtable *);
+//DEFINE_HASHTABLE_REMOVE(del_cr3_from_cache, addr_t, struct hashtable *, 0);
 
 
 DEFINE_HASHTABLE_INSERT(add_pte_map, addr_t, addr_t);
 DEFINE_HASHTABLE_SEARCH(find_pte_map, addr_t, addr_t);
-DEFINE_HASHTABLE_REMOVE(del_pte_map, addr_t, addr_t, 0);
+//DEFINE_HASHTABLE_REMOVE(del_pte_map, addr_t, addr_t, 0);