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.


updated IO and MSRs to allow hooking/unhooking dynamic at runtime
Jack Lange [Sun, 26 Apr 2009 18:58:50 +0000 (13:58 -0500)]
palacios/include/palacios/svm_io.h
palacios/include/palacios/svm_msr.h
palacios/include/palacios/vm_guest.h
palacios/include/palacios/vmm_io.h
palacios/include/palacios/vmm_msr.h
palacios/src/palacios/svm.c
palacios/src/palacios/svm_io.c
palacios/src/palacios/svm_msr.c
palacios/src/palacios/vmm_intr.c
palacios/src/palacios/vmm_io.c
palacios/src/palacios/vmm_msr.c

index 4d691b4..81dec75 100644 (file)
@@ -39,10 +39,12 @@ struct svm_io_info {
     uint_t addr32      : 1       PACKED;  // 32 bit addr
     uint_t addr64      : 1       PACKED;  // 64 bit addr
     uint_t rsvd2       : 6       PACKED;  // Should be Zero
-    ushort_t port                PACKED;  // port number
+    uint16_t port                PACKED;  // port number
 };
 
 
+int v3_init_svm_io_map(struct guest_info * info);
+
 int v3_handle_svm_io_in(struct guest_info * info);
 int v3_handle_svm_io_ins(struct guest_info * info);
 int v3_handle_svm_io_out(struct guest_info * info);
index 30975f1..6972afd 100644 (file)
@@ -25,7 +25,7 @@
 
 #include <palacios/vmm.h>
 
-addr_t v3_init_svm_msr_map(struct guest_info * info);
+int v3_init_svm_msr_map(struct guest_info * info);
 
 int v3_handle_msr_write(struct guest_info * info);
 
index 63decc2..1f0293f 100644 (file)
@@ -138,7 +138,7 @@ struct guest_info {
     // This structure is how we get exceptions for the guest
     struct v3_excp_state excp_state;
 
-    v3_io_map_t io_map;
+    struct v3_io_map io_map;
 
     struct v3_msr_map msr_map;
 
index 20dd301..e2f4be5 100644 (file)
@@ -27,7 +27,7 @@
 #include <palacios/vmm_util.h>
 #include <palacios/vmm_rbtree.h>
 
-typedef struct rb_root v3_io_map_t;
+
 
 
 struct guest_info;
@@ -39,8 +39,8 @@ void v3_init_io_map(struct guest_info * info);
 
 /* External API */
 int v3_hook_io_port(struct guest_info * info, uint_t port, 
-                   int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data),
-                   int (*write)(ushort_t port, void * src, uint_t length, void * priv_data), 
+                   int (*read)(uint16_t port, void * dst, uint_t length, void * priv_data),
+                   int (*write)(uint16_t port, void * src, uint_t length, void * priv_data), 
                    void * priv_data);
 
 int v3_unhook_io_port(struct guest_info * info, uint_t port);
@@ -48,14 +48,17 @@ int v3_unhook_io_port(struct guest_info * info, uint_t port);
 
 
 
+
 struct v3_io_hook {
-    ushort_t port;
+    uint16_t port;
 
     // Reads data into the IO port (IN, INS)
-    int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data);
+    int (*read)(uint16_t port, void * dst, uint_t length, void * priv_data);
 
     // Writes data from the IO port (OUT, OUTS)
-    int (*write)(ushort_t port, void * src, uint_t length, void * priv_data);
+    int (*write)(uint16_t port, void * src, uint_t length, void * priv_data);
+
+
 
     void * priv_data;
   
@@ -63,6 +66,13 @@ struct v3_io_hook {
 
 };
 
+struct v3_io_map {
+    struct rb_root map;
+
+    int (*update_map)(struct guest_info * info, uint16_t port, int hook_read, int hook_write);
+
+    void * arch_data;
+};
 
 struct v3_io_hook * v3_get_io_hook(struct guest_info * info, uint_t port);
 
@@ -72,14 +82,14 @@ void v3_print_io_map(struct guest_info * info);
 
 
 
-void v3_outb(ushort_t port, uchar_t value);
-uchar_t v3_inb(ushort_t port);
+void v3_outb(uint16_t port, uint8_t value);
+uint8_t v3_inb(uint16_t port);
 
-void v3_outw(ushort_t port, ushort_t value);
-ushort_t v3_inw(ushort_t port);
+void v3_outw(uint16_t port, uint16_t value);
+uint16_t v3_inw(uint16_t port);
 
-void v3_outdw(ushort_t port, uint_t value);
-uint_t v3_indw(ushort_t port);
+void v3_outdw(uint16_t port, uint_t value);
+uint_t v3_indw(uint16_t port);
 
 
 
index 00e1425..ef66a60 100644 (file)
@@ -28,6 +28,7 @@
 
 struct guest_info;
 
+
 struct v3_msr {
 
     union {
@@ -41,7 +42,6 @@ struct v3_msr {
 } __attribute__((packed));
 
 
-
 typedef struct v3_msr v3_msr_t;
 
 struct v3_msr_hook {
@@ -62,6 +62,10 @@ struct v3_msr_hook;
 struct v3_msr_map {
     uint_t num_hooks;
     struct list_head hook_list;
+
+    int (*update_map)(struct guest_info * info, uint_t msr, int hook_read, int hook_write);
+    void * arch_data;
+
 };
 
 
index d617b61..c577a7d 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <palacios/vmm_ctrl_regs.h>
 #include <palacios/vmm_config.h>
+#include <palacios/svm_io.h>
 
 
 extern void v3_stgi();
@@ -164,37 +165,16 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info *vm_info) {
     guest_state->dr7 = 0x0000000000000400LL;
 
 
-    if ( !RB_EMPTY_ROOT(&(vm_info->io_map)) ) {
-       struct v3_io_hook * iter;
-       struct rb_node * io_node = v3_rb_first(&(vm_info->io_map));
-       addr_t io_port_bitmap;
-       int i = 0;
-       
-       io_port_bitmap = (addr_t)V3_VAddr(V3_AllocPages(3));
-       memset((uchar_t*)io_port_bitmap, 0, PAGE_SIZE * 3);
-
-       ctrl_area->IOPM_BASE_PA = (addr_t)V3_PAddr((void *)io_port_bitmap);
-
-       //PrintDebug("Setting up IO Map at 0x%x\n", io_port_bitmap);
-
-       do {
-           iter = rb_entry(io_node, struct v3_io_hook, tree_node);
-
-           ushort_t port = iter->port;
-           uchar_t * bitmap = (uchar_t *)io_port_bitmap;
-           //PrintDebug("%d: Hooking Port %d\n", i, port);
+    v3_init_svm_io_map(vm_info);
+    ctrl_area->IOPM_BASE_PA = (addr_t)V3_PAddr(vm_info->io_map.arch_data);
+    ctrl_area->instrs.IOIO_PROT = 1;
 
-           bitmap += (port / 8);
-           //      PrintDebug("Setting Bit for port 0x%x\n", port);
-           *bitmap |= 1 << (port % 8);
 
-           i++;
-       } while ((io_node = v3_rb_next(io_node)));
 
-       //PrintDebugMemDump((uchar_t*)io_port_bitmap, PAGE_SIZE *2);
+    v3_init_svm_msr_map(vm_info);
+    ctrl_area->MSRPM_BASE_PA = (addr_t)V3_PAddr(vm_info->msr_map.arch_data);
+    ctrl_area->instrs.MSR_PROT = 1;
 
-       ctrl_area->instrs.IOIO_PROT = 1;
-    }
 
 
     PrintDebug("Exiting on interrupts\n");
@@ -267,11 +247,7 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info *vm_info) {
        guest_state->g_pat = 0x7040600070406ULL;
     }
 
-    if (vm_info->msr_map.num_hooks > 0) {
-       PrintDebug("Hooking %d msrs\n", vm_info->msr_map.num_hooks);
-       ctrl_area->MSRPM_BASE_PA = v3_init_svm_msr_map(vm_info);
-       ctrl_area->instrs.MSR_PROT = 1;
-    }
+
 
     /* Safety locations for fs/gs */
     //    vm_info->fs = 0;
@@ -285,17 +261,17 @@ static int init_svm_guest(struct guest_info *info, struct v3_vm_config * config_
     PrintDebug("Allocating VMCB\n");
     info->vmm_data = (void*)Allocate_VMCB();
 
+    Init_VMCB_BIOS((vmcb_t*)(info->vmm_data), info);
+
     v3_config_devices(info, config_ptr);
 
     PrintDebug("Initializing VMCB (addr=%p)\n", (void *)info->vmm_data);
-    Init_VMCB_BIOS((vmcb_t*)(info->vmm_data), info);
-  
 
-    
+
     info->run_state = VM_STOPPED;
 
     //  info->rip = 0;
-    
+
     info->vm_regs.rdi = 0;
     info->vm_regs.rsi = 0;
     info->vm_regs.rbp = 0;
@@ -304,7 +280,7 @@ static int init_svm_guest(struct guest_info *info, struct v3_vm_config * config_
     info->vm_regs.rdx = 0;
     info->vm_regs.rcx = 0;
     info->vm_regs.rax = 0;
-    
+
     return 0;
 }
 
index 12610a1..4c85ec7 100644 (file)
 #endif
 
 
+static int update_map(struct guest_info * info, uint16_t port, int hook_read, int hook_write) {
+    uchar_t * bitmap = (uint8_t *)(info->io_map.arch_data);;
+    int major = port / 8;
+    int minor = port % 8;
+
+    if ((hook_read == 0) && (hook_write == 0)) {
+       *(bitmap + major) &= ~(0x1 << minor);
+    } else {
+       *(bitmap + major) |= (0x1 << minor);
+    }
+
+    return 0;
+}
+
+
+int v3_init_svm_io_map(struct guest_info * info) {
+    info->io_map.update_map = update_map;
+
+    info->io_map.arch_data = V3_VAddr(V3_AllocPages(3));
+    memset(info->io_map.arch_data, 0, PAGE_SIZE_4KB * 3);
+
+    return 0;
+}
 
 
 
index ee14a14..dcc653e 100644 (file)
@@ -53,38 +53,38 @@ static int get_bitmap_index(uint_t msr) {
 }
 
 
+static int update_map(struct guest_info * info, uint_t msr, int hook_reads, int hook_writes) {
+    int index = get_bitmap_index(msr);
+    uint_t major = index / 4;
+    uint_t minor = (index % 4) * 2;
+    uchar_t val = 0;
+    uchar_t mask = 0x3;
+    uint8_t * bitmap = (uint8_t *)(info->msr_map.arch_data);
+
+    if (hook_reads) {
+       val |= 0x1;
+    } 
+    
+    if (hook_writes) {
+       val |= 0x2;
+    }
 
-addr_t v3_init_svm_msr_map(struct guest_info * info) {
-    uchar_t * msr_bitmap = (uchar_t*)V3_VAddr(V3_AllocPages(2));
-    struct v3_msr_map * msr_map = &(info->msr_map);
-    struct v3_msr_hook * hook = NULL;
-  
-  
-    memset(msr_bitmap, 0, PAGE_SIZE * 2);
-
-    list_for_each_entry(hook, &(msr_map->hook_list), link) {
-       int index = get_bitmap_index(hook->msr);
-       uint_t byte_offset = index / 4;
-       uint_t bit_offset = (index % 4) * 2;
-       uchar_t val = 0;
-       uchar_t mask = ~0x3;
-
-       if (hook->read) {
-           val |= 0x1;
-       } 
+    *(bitmap + major) &= ~(mask << minor);
+    *(bitmap + major) |= (val << minor);
+    
+    return 0;
+}
 
-       if (hook->write) {
-           val |= 0x2;
-       }
 
-       val = val << bit_offset;
-       mask = mask << bit_offset;
+int v3_init_svm_msr_map(struct guest_info * info) {
+    struct v3_msr_map * msr_map = &(info->msr_map);
+  
+    msr_map->update_map = update_map;
 
-       *(msr_bitmap + byte_offset) &= mask;
-       *(msr_bitmap + byte_offset) |= val;
-    }
+    msr_map->arch_data = V3_VAddr(V3_AllocPages(2));  
+    memset(msr_map->arch_data, 0, PAGE_SIZE_4KB * 2);
 
-    return (addr_t)V3_PAddr(msr_bitmap);
+    return 0;
 }
 
 
index 865a9fd..875534a 100644 (file)
@@ -177,21 +177,14 @@ 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;
-    struct rflags * flags = (struct rflags *)&(info->ctrl_regs.rflags);
     //  PrintDebug("[intr_pending]\n");
     
-    // Check if the guest has interrupts enabled
-    if (flags->intr == 0) {
-       //return 0;
-    }
-
     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;
 }
 
index 9756eb4..9f44fbd 100644 (file)
 #endif
 
 
-static int default_write(ushort_t port, void *src, uint_t length, void * priv_data);
-static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data);
+static int default_write(uint16_t port, void *src, uint_t length, void * priv_data);
+static int default_read(uint16_t port, void * dst, uint_t length, void * priv_data);
 
 
 void v3_init_io_map(struct guest_info * info) {
-  info->io_map.rb_node = NULL;
+
+  info->io_map.map.rb_node = NULL;
+  info->io_map.arch_data = NULL;
+  info->io_map.update_map = NULL;
+
 }
 
 
 
 
 static inline struct v3_io_hook * __insert_io_hook(struct guest_info * info, struct v3_io_hook * hook) {
-  struct rb_node ** p = &(info->io_map.rb_node);
+  struct rb_node ** p = &(info->io_map.map.rb_node);
   struct rb_node * parent = NULL;
   struct v3_io_hook * tmp_hook = NULL;
 
@@ -71,14 +75,14 @@ static inline struct v3_io_hook * insert_io_hook(struct guest_info * info, struc
     return ret;
   }
 
-  v3_rb_insert_color(&(hook->tree_node), &(info->io_map));
+  v3_rb_insert_color(&(hook->tree_node), &(info->io_map.map));
 
   return NULL;
 }
 
 
 struct v3_io_hook * v3_get_io_hook(struct guest_info * info, uint_t port) {
-  struct rb_node * n = info->io_map.rb_node;
+  struct rb_node * n = info->io_map.map.rb_node;
   struct v3_io_hook * hook = NULL;
 
   while (n) {
@@ -102,8 +106,8 @@ struct v3_io_hook * v3_get_io_hook(struct guest_info * info, uint_t port) {
 
 
 int v3_hook_io_port(struct guest_info * info, uint_t port, 
-                   int (*read)(ushort_t port, void * dst, uint_t length, void * priv_data),
-                   int (*write)(ushort_t port, void * src, uint_t length, void * priv_data), 
+                   int (*read)(uint16_t port, void * dst, uint_t length, void * priv_data),
+                   int (*write)(uint16_t port, void * src, uint_t length, void * priv_data), 
                    void * priv_data) {
   struct v3_io_hook * io_hook = (struct v3_io_hook *)V3_Malloc(sizeof(struct v3_io_hook));
 
@@ -129,6 +133,15 @@ int v3_hook_io_port(struct guest_info * info, uint_t port,
     return -1;
   }
 
+
+  if (info->io_map.update_map(info, port, 
+                             ((read == NULL) ? 0 : 1), 
+                             ((write == NULL) ? 0 : 1)) == -1) {
+    V3_Free(io_hook);
+    return -1;
+  }
+
+
   return 0;
 }
 
@@ -139,7 +152,10 @@ int v3_unhook_io_port(struct guest_info * info, uint_t port) {
     return -1;
   }
 
-  v3_rb_erase(&(hook->tree_node), &(info->io_map));
+  v3_rb_erase(&(hook->tree_node), &(info->io_map.map));
+
+  // set the arch map to default (this should be 1, 1)
+  info->io_map.update_map(info, port, 0, 0);
 
   V3_Free(hook);
 
@@ -153,7 +169,7 @@ int v3_unhook_io_port(struct guest_info * info, uint_t port) {
 
 void v3_print_io_map(struct guest_info * info) {
   struct v3_io_hook * tmp_hook = NULL;
-  struct rb_node * node = v3_rb_first(&(info->io_map));
+  struct rb_node * node = v3_rb_first(&(info->io_map.map));
 
   PrintDebug("VMM IO Map\n");
 
@@ -171,7 +187,7 @@ void v3_print_io_map(struct guest_info * info) {
 /*
  * Write a byte to an I/O port.
  */
-void v3_outb(ushort_t port, uchar_t value) {
+void v3_outb(uint16_t port, uint8_t value) {
     __asm__ __volatile__ (
        "outb %b0, %w1"
        :
@@ -182,8 +198,8 @@ void v3_outb(ushort_t port, uchar_t value) {
 /*
  * Read a byte from an I/O port.
  */
-uchar_t v3_inb(ushort_t port) {
-    uchar_t value;
+uint8_t v3_inb(uint16_t port) {
+    uint8_t value;
 
     __asm__ __volatile__ (
        "inb %w1, %b0"
@@ -197,7 +213,7 @@ uchar_t v3_inb(ushort_t port) {
 /*
  * Write a word to an I/O port.
  */
-void v3_outw(ushort_t port, ushort_t value) {
+void v3_outw(uint16_t port, uint16_t value) {
     __asm__ __volatile__ (
        "outw %w0, %w1"
        :
@@ -208,8 +224,8 @@ void v3_outw(ushort_t port, ushort_t value) {
 /*
  * Read a word from an I/O port.
  */
-ushort_t v3_inw(ushort_t port) {
-    ushort_t value;
+uint16_t v3_inw(uint16_t port) {
+    uint16_t value;
 
     __asm__ __volatile__ (
        "inw %w1, %w0"
@@ -223,7 +239,7 @@ ushort_t v3_inw(ushort_t port) {
 /*
  * Write a double word to an I/O port.
  */
-void v3_outdw(ushort_t port, uint_t value) {
+void v3_outdw(uint16_t port, uint_t value) {
     __asm__ __volatile__ (
        "outl %0, %1"
        :
@@ -234,7 +250,7 @@ void v3_outdw(ushort_t port, uint_t value) {
 /*
  * Read a double word from an I/O port.
  */
-uint_t v3_indw(ushort_t port) {
+uint_t v3_indw(uint16_t port) {
     uint_t value;
 
     __asm__ __volatile__ (
@@ -250,7 +266,7 @@ uint_t v3_indw(ushort_t port) {
 
 
 /* FIX ME */
-static int default_write(ushort_t port, void *src, uint_t length, void * priv_data) {
+static int default_write(uint16_t port, void *src, uint_t length, void * priv_data) {
   /*
     
   if (length == 1) {
@@ -276,10 +292,10 @@ static int default_write(ushort_t port, void *src, uint_t length, void * priv_da
   return 0;
 }
 
-static int default_read(ushort_t port, void * dst, uint_t length, void * priv_data) {
+static int default_read(uint16_t port, void * dst, uint_t length, void * priv_data) {
 
   /*    
-       uchar_t value;
+       uint8_t value;
 
     __asm__ __volatile__ (
        "inb %w1, %b0"
index 105bfe6..5fe5ffd 100644 (file)
@@ -28,6 +28,9 @@ void v3_init_msr_map(struct guest_info * info) {
 
     INIT_LIST_HEAD(&(msr_map->hook_list));
     msr_map->num_hooks = 0;
+
+    msr_map->arch_data = NULL;
+    msr_map->update_map = NULL;
 }
 
 
@@ -40,6 +43,7 @@ int v3_hook_msr(struct guest_info * info, uint_t msr,
     struct v3_msr_hook * hook = NULL;
 
     hook = (struct v3_msr_hook *)V3_Malloc(sizeof(struct v3_msr_hook));
+
     if (hook == NULL) {
        PrintError("Could not allocate msr hook for MSR %d\n", msr);
        return -1;
@@ -54,6 +58,9 @@ int v3_hook_msr(struct guest_info * info, uint_t msr,
 
     list_add(&(hook->link), &(msr_map->hook_list));
 
+    msr_map->update_map(info, msr, 
+                       (read == NULL) ? 0 : 1,
+                       (write == NULL) ? 0 : 1);
     return 0;
 }