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.


lots of fixes
Jack Lange [Thu, 7 Jan 2010 23:15:22 +0000 (17:15 -0600)]
14 files changed:
palacios/include/palacios/vmm.h
palacios/include/palacios/vmm_list.h
palacios/include/palacios/vmm_sym_swap.h
palacios/src/devices/Kconfig
palacios/src/devices/Makefile
palacios/src/devices/ata.h
palacios/src/devices/ide.c
palacios/src/devices/keyboard.c
palacios/src/devices/pci_passthrough.c
palacios/src/devices/tmpdisk.c
palacios/src/palacios/svm.c
palacios/src/palacios/vmm_shadow_paging_32.h
palacios/src/palacios/vmm_sym_swap.c
palacios/src/palacios/vmx.c

index fb89f28..b05871f 100644 (file)
@@ -114,6 +114,7 @@ struct guest_info;
            if ((os_hooks) && (os_hooks)->malloc) {     \
                var = (os_hooks)->malloc(size);         \
            }                                           \
+           if (!var) PrintError("MALLOC FAILURE. Memory LEAK!!\n");    \
            var;                                        \
        })
 
index 0d5b907..f44933a 100644 (file)
@@ -247,6 +247,24 @@ static inline void list_splice_init(struct list_head *list,
 })
 
 /**
+ * list_first_entry - get the struct for the first entry
+ * @ptr:       the list_head head pointer.
+ * @type:      the type of the struct this is embedded in.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_first_entry(head, type, member)                   \
+({                                                             \
+    type * first = NULL;                                       \
+    if ((head)->next != (head)) {                              \
+       first = list_entry((head)->next, type, member);         \
+    }                                                          \
+    first;                                                     \
+ })
+    
+
+
+
+/**
  * list_for_each       -       iterate over a list
  * @pos:       the &struct list_head to use as a loop counter.
  * @head:      the head for your list.
index a8646ef..e104acc 100644 (file)
@@ -50,6 +50,7 @@ struct v3_sym_swap_state {
     uint32_t write_faults;
     uint32_t flushes;
     uint32_t mapped_pages;
+    uint32_t list_size;
 #endif
 
     // shadow pointers
@@ -73,7 +74,8 @@ int v3_swap_in_notify(struct guest_info * info, int pg_index, int dev_index);
 
 
 int v3_get_vaddr_perms(struct guest_info * info, addr_t vaddr, pte32_t * guest_pte, pf_error_t * page_perms);
-addr_t v3_get_swapped_pg_addr(struct guest_info * info, pte32_t * shadow_pte, pte32_t * guest_pte);
+addr_t v3_get_swapped_pg_addr(struct guest_info * info, pte32_t * guest_pte);
+addr_t v3_map_swp_page(struct guest_info * info, pte32_t * shadow_pte, pte32_t * guest_pte, void * swp_page_ptr);
 
 int v3_swap_flush(struct guest_info * info);
 
index 1a449d6..dbce08b 100644 (file)
@@ -270,6 +270,20 @@ config SYM_SWAP
        help 
          Includes the symbiotic ram based swap disk
 
+config SYM_SWAP2
+       bool "Symbiotic Swap disk v2"
+       default y
+       depends on SYMBIOTIC_SWAP && (LINUX_VIRTIO_BLOCK || IDE)
+       help 
+         Includes the symbiotic ram based swap disk
+
+config DISK_MODEL
+       bool "Disk Performance Model"
+       default y
+       depends on LINUX_VIRTIO_BLOCK || IDE
+       help 
+         Includes Performance model filter for disk operations
+
 config CGA
        bool "CGA"
        default n
index 81ecbf2..a9b7f54 100644 (file)
@@ -16,6 +16,8 @@ obj-$(CONFIG_OS_DEBUG) += os_debug.o
 obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_PIIX3) += piix3.o
 obj-$(CONFIG_SYM_SWAP) += sym_swap.o
+obj-$(CONFIG_SYM_SWAP2) += sym_swap2.o
+obj-$(CONFIG_DISK_MODEL) += disk_model.o
 
 obj-$(CONFIG_NE2K) += ne2k.o
 
index 4cf6cd2..cb0193e 100644 (file)
@@ -64,10 +64,10 @@ static void ata_identify_device(struct ide_drive * drive) {
     drive_id->lba_enable = 1;
     
     // Drive Capacity (28 bit LBA)
-    drive_id->lba_capacity = drive->ops->get_capacity(drive->private_data);
+    drive_id->lba_capacity = drive->ops->get_capacity(drive->private_data) / HD_SECTOR_SIZE;
     
     // Drive Capacity (48 bit LBA)
-    drive_id->lba_capacity_2 = drive->ops->get_capacity(drive->private_data);
+    drive_id->lba_capacity_2 = drive->ops->get_capacity(drive->private_data) / HD_SECTOR_SIZE;
 
 
     // lower byte is the maximum multiple sector size...
@@ -124,6 +124,9 @@ static int ata_read(struct vm_device * dev, struct ide_channel * channel, uint8_
     }
 
     return 0;
+
+
+
 }
 
 
@@ -168,7 +171,7 @@ static int ata_get_lba(struct vm_device * dev, struct ide_channel * channel, uin
 
 
     if ((lba_addr.addr + sect_cnt) > 
-       drive->ops->get_capacity(drive->private_data)) {
+       drive->ops->get_capacity(drive->private_data) / HD_SECTOR_SIZE) {
        PrintError("IDE: request size exceeds disk capacity (lba=%d) (sect_cnt=%d) (ReadEnd=%d) (capacity=%p)\n", 
                   lba_addr.addr, sect_cnt, 
                   lba_addr.addr + (sect_cnt * HD_SECTOR_SIZE),
index 7b13e5b..246b1d4 100644 (file)
@@ -1494,7 +1494,7 @@ static int connect_fn(struct guest_info * info,
 
        drive->num_sectors = 63;
        drive->num_heads = 16;
-       drive->num_cylinders = ops->get_capacity(private_data)  / (drive->num_sectors * drive->num_heads);
+       drive->num_cylinders = (ops->get_capacity(private_data) / HD_SECTOR_SIZE) / (drive->num_sectors * drive->num_heads);
     } else {
        PrintError("invalid IDE drive type\n");
        return -1;
index a6ba864..eb76cc9 100644 (file)
@@ -317,6 +317,7 @@ static int pull_from_output_queue(struct vm_device * dev, uint8_t * value) {
 }
 
 
+#include <palacios/vmm_telemetry.h>
 
 
 static int key_event_handler(struct guest_info * info, 
@@ -347,11 +348,14 @@ static int key_event_handler(struct guest_info * info,
 
     } 
 #endif
-    else if (evt->scan_code == 0x42) { // F8 Sym test2
+    else if (evt->scan_code == 0x42) { // F8 debug toggle
        extern int v3_dbg_enable;
        
        PrintDebug("Toggling Debugging\n");     
        v3_dbg_enable ^= 1;
+    } else if (evt->scan_code == 0x41) { // F7 telemetry dump
+       v3_print_telemetry(info);
+       
     }
 
 
index fafd303..18e4ef4 100644 (file)
@@ -191,7 +191,6 @@ static int pci_bar_init(int bar_num, uint32_t * dst,void * private_data) {
 
        pbar->size = (uint16_t)~PCI_IO_BASE(max_val) + 1;
 
-
        
        V3_Print("IO Bar with %d (%x) ports %x->%x\n", pbar->size, pbar->size, pbar->addr, pbar->addr + pbar->size);
        // setup a set of null io hooks
@@ -262,8 +261,6 @@ static int pci_bar_init(int bar_num, uint32_t * dst,void * private_data) {
 
        }
     }
-    
-
 
 
     // Initially the virtual bars match the physical ones
@@ -279,8 +276,6 @@ static int pci_bar_init(int bar_num, uint32_t * dst,void * private_data) {
               state->virt_bars[bar_num].type, state->virt_bars[bar_num].addr, 
               state->virt_bars[bar_num].size);
 
-
-
     // Update the pci subsystem versions
     *dst = bar_val;
 
index fde3cf3..b573cf6 100644 (file)
@@ -32,7 +32,7 @@ struct blk_state {
 static uint64_t blk_get_capacity(void * private_data) {
     struct blk_state * blk = (struct blk_state *)private_data;
 
-    PrintDebug("SymBlk: Getting Capacity %d\n", (uint32_t)(blk->capacity));
+    //  PrintDebug("SymBlk: Getting Capacity %d\n", (uint32_t)(blk->capacity));
 
     return blk->capacity;
 }
@@ -42,6 +42,8 @@ static uint64_t blk_get_capacity(void * private_data) {
 static int blk_read(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data) {
     struct blk_state * blk = (struct blk_state *)private_data;
 
+    //    PrintDebug("TmpDisk Reading %d bytes to %p (lba=%p)\n", (uint32_t)num_bytes, buf, (void *)(addr_t)lba);
+
     if (lba + num_bytes > blk->capacity) {
        PrintError("TMPDISK Read past end of disk\n");
        return -1;
@@ -58,6 +60,8 @@ static int blk_read(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * priv
 static int blk_write(uint8_t * buf,  uint64_t lba, uint64_t num_bytes, void * private_data) {
     struct blk_state * blk = (struct blk_state *)private_data;
 
+    //    PrintDebug("TmpDisk Writing %d bytes to %p (lba=%p)\n", (uint32_t)num_bytes, buf, (void *)(addr_t)lba);
+
     if (lba + num_bytes > blk->capacity) {
        PrintError("TMPDISK Write past end of disk\n");
        return -1;
index fa1f3ec..acb5353 100644 (file)
@@ -465,7 +465,7 @@ int v3_svm_enter(struct guest_info * info) {
 
 
     rdtscll(info->time_state.cached_host_tsc);
-    //    guest_ctrl->TSC_OFFSET = info->time_state.guest_tsc - info->time_state.cached_host_tsc;
+    guest_ctrl->TSC_OFFSET = info->time_state.guest_tsc - info->time_state.cached_host_tsc;
        
     v3_svm_launch((vmcb_t *)V3_PAddr(info->vmm_data), &(info->vm_regs), (vmcb_t *)host_vmcbs[info->cpu_id]);
     
index c358c3c..fc2df95 100644 (file)
@@ -230,8 +230,18 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault
        
 #ifdef CONFIG_SYMBIOTIC_SWAP
        if (is_swapped_pte32(guest_pte)) {
+
            pf_error_t swap_perms;
 
+
+           /*
+           int sym_ret = v3_get_vaddr_perms(info, fault_addr, guest_pte, &swap_perms);
+           sym_ret = 0;
+           */
+           addr_t swp_pg_addr = 0;
+
+
+
 #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY
            if (error_code.write == 0) {
                info->swap_state.read_faults++;
@@ -240,54 +250,72 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault
            }
 #endif
 
-           if (v3_get_vaddr_perms(info, fault_addr, guest_pte, &swap_perms) == -1) {
-               PrintError("Error getting Swapped page permissions\n");
-               return -1;
-           }
 
+           swp_pg_addr = v3_get_swapped_pg_addr(info,  guest_pte);
 
-           // swap_perms.write == 1 || error_code.write == 0
-           // swap_perms.user == 0 || error_code.user == 1
+           if (swp_pg_addr != 0) {
+               PrintDebug("Swapped page address=%p\n", (void *)swp_pg_addr);
 
-           // This checks for permissions violations that require a guest PF injection
-           if ( (swap_perms.present == 1) && 
-                ( (swap_perms.write == 1) || 
-                  (error_code.write == 0) ) &&
-                ( (swap_perms.user == 1) || 
-                  (error_code.user == 0) ) ) {
-               addr_t swp_pg_addr = 0;
+               /*
+               if (info->cpl == 0) {
+                   PrintError("Swapped Page fault in kernel mode.... bad...\n");
+                   goto inject;
+               }
+               */
 
-               PrintDebug("Page fault on swapped out page (vaddr=%p) (pte=%x) (error_code=%x)\n", 
-                        (void *)fault_addr, *(uint32_t *)guest_pte, *(uint32_t *)&error_code);
+               int sym_ret = v3_get_vaddr_perms(info, fault_addr, guest_pte, &swap_perms);
 
-               swp_pg_addr = v3_get_swapped_pg_addr(info, shadow_pte, guest_pte);
+               if (sym_ret == -1) {
+                   PrintError("Symcall error...\n");
+                   return -1;
+               } else if (sym_ret == 0) {
 
-               PrintDebug("Swapped page address=%p\n", (void *)swp_pg_addr);
 
-               if (swp_pg_addr != 0) {
-                   shadow_pte->writable = swap_perms.write;
-                   shadow_pte->user_page = swap_perms.user;
-                   
-                   shadow_pte->write_through = 0;
-                   shadow_pte->cache_disable = 0;
-                   shadow_pte->global_page = 0;
-                   
-                   shadow_pte->present = 1;
+                   if (swap_perms.present == 0) {
+                       PrintError("Nonpresent swapped page\n");
+                   }
                    
-                   shadow_pte->page_base_addr = swp_pg_addr;
+                   // swap_perms.write ==1 || error_code.write == 0
+                   // swap_perms.user == 0 || error_code.user == 1
                    
+                   // This checks for permissions violations that require a guest PF injection
+                   if ( (swap_perms.present == 1) && 
+                        ( (swap_perms.write == 1) || 
+                          (error_code.write == 0) ) &&
+                        ( (swap_perms.user == 1) || 
+                          (error_code.user == 0) ) ) {
+                       addr_t swp_pg_pa = 0;
+                       
+                       swp_pg_pa = v3_map_swp_page(info, shadow_pte, guest_pte, (void *)swp_pg_addr);
+
+                       PrintDebug("Page fault on swapped out page (vaddr=%p) (pte=%x) (error_code=%x)\n", 
+                                  (void *)fault_addr, *(uint32_t *)guest_pte, *(uint32_t *)&error_code);
+                       
+                       shadow_pte->writable = swap_perms.write;
+                       shadow_pte->user_page = swap_perms.user;
+                       
+                       shadow_pte->write_through = 0;
+                       shadow_pte->cache_disable = 0;
+                       shadow_pte->global_page = 0;
+                       
+                       shadow_pte->present = 1;
+                       
+                       shadow_pte->page_base_addr = swp_pg_pa;
+                       
 #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY
-                   info->swap_state.mapped_pages++;
+                       info->swap_state.mapped_pages++;
 #endif
-
-                   return 0;
+                       //              PrintError("Swap fault handled\n");
+                       return 0;
+                   }
                }
            } else {
                PrintDebug("Not a sym swappable page\n");
            }
+
        }
 #endif
-       
+       //   inject:
 
        if (inject_guest_pf(info, fault_addr, error_code) == -1) {
            PrintError("Could not inject guest page fault for vaddr %p\n", (void *)fault_addr);
index 3b1620c..5e1aa80 100644 (file)
@@ -78,6 +78,7 @@ static void telemetry_cb(struct guest_info * info, void * private_data, char * h
     V3_Print("%s\tWrite faults=%d\n", hdr, swap_state->write_faults);
     V3_Print("%s\tMapped Pages=%d\n", hdr, swap_state->mapped_pages);
     V3_Print("%s\tFlushes=%d\n", hdr, swap_state->flushes);
+    V3_Print("%s\tlist size=%d\n", hdr, swap_state->list_size);
 }
 #endif
 
@@ -199,29 +200,38 @@ int v3_get_vaddr_perms(struct guest_info * info, addr_t vaddr, pte32_t * guest_p
 
     //    V3_Print("page perms = %x\n", *(uint32_t *)page_perms);
 
+    if (vaddr == 0) {
+       return 1;
+    }
+
     return 0;
 }
 
 
 
-addr_t v3_get_swapped_pg_addr(struct guest_info * info, pte32_t * shadow_pte, pte32_t * guest_pte) {
-    struct list_head * shdw_ptr_list = NULL;
+addr_t v3_get_swapped_pg_addr(struct guest_info * info, pte32_t * guest_pte) {
     struct v3_sym_swap_state * swap_state = &(info->swap_state);
-    struct shadow_pointer * shdw_ptr = NULL;
-    void * swp_page_ptr = NULL;
     int dev_index = get_dev_index(guest_pte);
     struct v3_swap_dev * swp_dev = &(swap_state->devs[dev_index]);
 
+
     if (! swp_dev->present ) {
        return 0;
     }
 
+    return (addr_t)swp_dev->ops->get_swap_entry(get_pg_index(guest_pte), swp_dev->private_data);
+}
+
+
+addr_t v3_map_swp_page(struct guest_info * info, pte32_t * shadow_pte, pte32_t * guest_pte, void * swp_page_ptr) {
+    struct list_head * shdw_ptr_list = NULL;
+    struct v3_sym_swap_state * swap_state = &(info->swap_state);
+    struct shadow_pointer * shdw_ptr = NULL;
 
 
-    swp_page_ptr = swp_dev->ops->get_swap_entry(get_pg_index(guest_pte), swp_dev->private_data);
 
     if (swp_page_ptr == NULL) {
-       PrintError("Swapped out page not found on swap device\n");
+       //      PrintError("Swapped out page not found on swap device\n");
        return 0;
     }
 
@@ -229,12 +239,19 @@ addr_t v3_get_swapped_pg_addr(struct guest_info * info, pte32_t * shadow_pte, pt
 
     if (shdw_ptr_list == NULL) {
        shdw_ptr_list = (struct list_head *)V3_Malloc(sizeof(struct list_head *));
+       swap_state->list_size++;
        INIT_LIST_HEAD(shdw_ptr_list);
        v3_htable_insert(swap_state->shdw_ptr_ht, (addr_t)*(uint32_t *)guest_pte, (addr_t)shdw_ptr_list);
     }
 
     shdw_ptr = (struct shadow_pointer *)V3_Malloc(sizeof(struct shadow_pointer));
 
+    if (shdw_ptr == NULL) {
+       PrintError("MEMORY LEAK\n");
+       telemetry_cb(info, NULL, "");
+       return 0;
+    }
+
     shdw_ptr->shadow_pte = shadow_pte;
     shdw_ptr->guest_pte = *(uint32_t *)guest_pte;
     shdw_ptr->pg_index = get_pg_index(guest_pte);
@@ -245,3 +262,23 @@ addr_t v3_get_swapped_pg_addr(struct guest_info * info, pte32_t * shadow_pte, pt
 
     return PAGE_BASE_ADDR((addr_t)V3_PAddr(swp_page_ptr));
 }
+
+
+
+/*
+int v3_is_mapped_fault(struct guest_info * info, pte32_t * shadow_pte, pte32_t * guest_pte) {
+    struct list_head * shdw_ptr_list = NULL;
+
+    shdw_ptr_list = (struct list_head * )v3_htable_search(swap_state->shdw_ptr_ht, *(addr_t *)&(guest_pte));
+
+
+    if (shdw_ptr_list != NULL) {
+       PrintError("We faulted on a mapped in page....\n");
+       return -1;
+    }
+    
+    return 0;
+}
+
+
+*/
index 2526f3d..aba5656 100644 (file)
@@ -652,6 +652,11 @@ int v3_vmx_enter(struct guest_info * info) {
     update_irq_entry_state(info);
 #endif
 
+    {
+       addr_t guest_cr3;
+       vmcs_read(VMCS_GUEST_CR3, &guest_cr3);
+       vmcs_write(VMCS_GUEST_CR3, guest_cr3);
+    }
 
     rdtscll(info->time_state.cached_host_tsc);
 
@@ -682,6 +687,8 @@ int v3_vmx_enter(struct guest_info * info) {
     /* Update guest state */
     v3_vmx_save_vmcs(info);
 
+    // info->cpl = info->segments.cs.selector & 0x3;
+
     info->mem_mode = v3_get_vm_mem_mode(info);
     info->cpu_mode = v3_get_vm_cpu_mode(info);