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.


Merge branch 'devel' of newskysaw.cs.northwestern.edu:/home/palacios/palacios into...
Peter Dinda [Tue, 11 Oct 2011 22:12:11 +0000 (17:12 -0500)]
26 files changed:
linux_module/main.c
linux_module/palacios-stubs.c
linux_module/palacios.h
linux_module/vm.c
linux_module/vm.h
linux_usr/Makefile
linux_usr/v3_create.c [new file with mode: 0644]
linux_usr/v3_ctrl.h
linux_usr/v3_free.c [new file with mode: 0644]
linux_usr/v3_launch.c [new file with mode: 0644]
linux_usr/v3_stop.c
palacios/include/devices/pci.h
palacios/include/palacios/vmm_checkpoint.h
palacios/src/devices/8259a.c
palacios/src/devices/atapi-types.h
palacios/src/devices/cga.c
palacios/src/devices/ide.c
palacios/src/devices/keyboard.c
palacios/src/devices/pci.c
palacios/src/palacios/svm.c
palacios/src/palacios/vm_guest.c
palacios/src/palacios/vmcs.c
palacios/src/palacios/vmm.c
palacios/src/palacios/vmm_checkpoint.c
palacios/src/palacios/vmm_dev_mgr.c
palacios/src/palacios/vmx.c

index 9317635..62a0fb5 100644 (file)
@@ -61,7 +61,7 @@ static long v3_dev_ioctl(struct file * filp,
 
 
     switch (ioctl) {
-       case V3_START_GUEST:{
+       case V3_CREATE_GUEST:{
            int vm_minor = 0;
            struct v3_guest_img user_image;
            struct v3_guest * guest = kmalloc(sizeof(struct v3_guest), GFP_KERNEL);
@@ -73,7 +73,7 @@ static long v3_dev_ioctl(struct file * filp,
 
            memset(guest, 0, sizeof(struct v3_guest));
 
-           printk("Palacios: Starting V3 Guest...\n");
+           printk("Palacios: Creating V3 Guest...\n");
 
            vm_minor = register_vm(guest);
 
@@ -106,32 +106,23 @@ static long v3_dev_ioctl(struct file * filp,
 
            strncpy(guest->name, user_image.name, 127);
 
-           printk("Palacios: Launching VM\n");
-
            INIT_LIST_HEAD(&(guest->exts));
 
-           if (start_palacios_vm(guest) == -1) {
-               printk("Palacios: Error starting guest\n");
+           if (create_palacios_vm(guest) == -1) {
+               printk("Palacios: Error creating guest\n");
                return -EFAULT;
            }
 
-           return guest->vm_dev;
+           return vm_minor;
            break;
        }
-       case V3_STOP_GUEST: {
+       case V3_FREE_GUEST: {
            unsigned long vm_idx = arg;
            struct v3_guest * guest = guest_map[vm_idx];
 
-           printk("Stopping VM idx=%d\n", vm_idx);
-           printk("Stopping VM (%s) (%p)\n", guest->name, guest);
-
-
-           if (irqs_disabled()) {
-               printk("WHAT!!?? IRQs are disabled??\n");
-               break;
-           }
+           printk("Freeing VM (%s) (%p)\n", guest->name, guest);
 
-           stop_palacios_vm(guest);
+           free_palacios_vm(guest);
            guest_map[vm_idx] = NULL;
            break;
        }
index 8eeeb7d..21aa4fd 100644 (file)
@@ -155,12 +155,11 @@ palacios_xcall(
 struct lnx_thread_arg {
     int (*fn)(void * arg);
     void * arg;
-    char * name;
 };
 
 static int lnx_thread_target(void * arg) {
     struct lnx_thread_arg * thread_info = (struct lnx_thread_arg *)arg;
-
+    int ret = 0;
     /*
       printk("Daemonizing new Palacios thread (name=%s)\n", thread_info->name);
 
@@ -169,12 +168,14 @@ static int lnx_thread_target(void * arg) {
     */
 
 
-    thread_info->fn(thread_info->arg);
+    ret = thread_info->fn(thread_info->arg);
 
     kfree(thread_info);
     // handle cleanup 
+
+    do_exit(ret);
     
-    return 0;
+    return 0; // should not get here.
 }
 
 /**
@@ -190,7 +191,6 @@ palacios_start_kernel_thread(
 
     thread_info->fn = fn;
     thread_info->arg = arg;
-    thread_info->name = thread_name;
 
     return kthread_run( lnx_thread_target, thread_info, thread_name );
 }
@@ -209,7 +209,6 @@ palacios_start_thread_on_cpu(int cpu_id,
 
     thread_info->fn = fn;
     thread_info->arg = arg;
-    thread_info->name = thread_name;
 
 
     thread = kthread_create( lnx_thread_target, thread_info, thread_name );
index 1ac8c03..5eca55d 100644 (file)
@@ -8,8 +8,6 @@
 
 
 /* Global Control IOCTLs */
-#define V3_START_GUEST 10
-#define V3_STOP_GUEST 11
 #define V3_CREATE_GUEST 12
 #define V3_FREE_GUEST 13
 
index abb798f..9869334 100644 (file)
@@ -127,6 +127,27 @@ static long v3_vm_ioctl(struct file * filp,
     printk("V3 IOCTL %d\n", ioctl);
 
     switch (ioctl) {
+       case V3_VM_LAUNCH: {
+           printk("palacios: launching vm\n");
+
+           if (v3_start_vm(guest->v3_ctx, 0xfffffffe) < 0) { 
+               printk("palacios: launch of vm failed\n");
+               return -1;
+           }
+           
+           break;
+       }
+       case V3_VM_STOP: {
+           printk("Stopping VM (%s) (%p)\n", guest->name, guest);
+
+           if (irqs_disabled()) {
+               printk("WHAT!!?? IRQs are disabled??\n");
+               break;
+           }
+
+           v3_stop_vm(guest->v3_ctx);
+           break;
+       }
        case V3_VM_PAUSE: {
            printk("Pausing VM (%s)\n", guest->name);
            v3_pause_vm(guest->v3_ctx);
@@ -246,7 +267,7 @@ extern u32 pg_frees;
 extern u32 mallocs;
 extern u32 frees;
 
-int start_palacios_vm(struct v3_guest * guest)  {
+int create_palacios_vm(struct v3_guest * guest)  {
     int err;
 
     init_vm_extensions(guest);
@@ -283,17 +304,7 @@ int start_palacios_vm(struct v3_guest * guest)  {
        return -1;
     }
 
-    printk("palacios: launching vm\n");
-
-    if (v3_start_vm(guest->v3_ctx, 0xffffffff) < 0) { 
-       printk("palacios: launch of vm failed\n");
-       device_destroy(v3_class, guest->vm_dev);
-       cdev_del(&(guest->cdev));
-       v3_free_vm(guest->v3_ctx);
-       return -1;
-    }
-    
-    printk("palacios: vm completed.  returning.\n");
+    printk("palacios: vm created at /dev/v3-vm%d\n", MINOR(guest->vm_dev));
 
     return 0;
 }
@@ -301,11 +312,8 @@ int start_palacios_vm(struct v3_guest * guest)  {
 
 
 
-int stop_palacios_vm(struct v3_guest * guest) {
-
-
-    v3_stop_vm(guest->v3_ctx);
 
+int free_palacios_vm(struct v3_guest * guest) {
 
     v3_free_vm(guest->v3_ctx);
 
index f8df6c7..53af2af 100644 (file)
@@ -8,8 +8,8 @@
 
 #include "palacios.h"
 
-int start_palacios_vm(struct v3_guest * guest);
-int stop_palacios_vm(struct v3_guest * guest);
+int create_palacios_vm(struct v3_guest * guest);
+int free_palacios_vm(struct v3_guest * guest);
 
 
 int add_guest_ctrl(struct v3_guest * guest,  unsigned int cmd, 
index c36a212..5bdf906 100644 (file)
@@ -2,13 +2,14 @@ all: v3_ctrl v3_stop v3_cons v3_mem v3_monitor v3_stream v3_user_host_dev_exampl
 
 
 
-v3_ctrl : v3_ctrl.c v3_pause.c v3_continue.c v3_ctrl.h
-       gcc -static v3_ctrl.c -o v3_ctrl 
+v3_ctrl : v3_ctrl.c v3_pause.c v3_continue.c v3_launch.c v3_stop.c v3_create.c v3_free.c
+       gcc -static v3_launch.c -o v3_launch
+       gcc -static v3_stop.c -o v3_stop 
        gcc -static v3_pause.c -o v3_pause
        gcc -static v3_continue.c -o v3_continue
+       gcc -static v3_create.c -o v3_create
+       gcc -static v3_free.c -o v3_free
 
-v3_stop : v3_stop.c v3_ctrl.h
-       gcc -static v3_stop.c -o v3_stop 
 
 v3_save : v3_save.c v3_ctrl.h
        gcc -static v3_save.c -o v3_save 
@@ -19,8 +20,8 @@ v3_mem : v3_mem.c v3_ctrl.h
        gcc -static v3_mem.c -o v3_mem 
 
 v3_cons : v3_cons.c v3_cons_sc.c v3_ctrl.h
-       gcc  v3_cons.c -o v3_cons -lcurses
-       gcc  v3_cons_sc.c -o v3_cons_sc -lcurses
+       gcc  -static v3_cons.c -o v3_cons -lcurses
+       gcc  -static v3_cons_sc.c -o v3_cons_sc -lcurses
 
 v3_stream : v3_stream.c v3_ctrl.h
        gcc -static v3_stream.c -o v3_stream 
diff --git a/linux_usr/v3_create.c b/linux_usr/v3_create.c
new file mode 100644 (file)
index 0000000..a73297f
--- /dev/null
@@ -0,0 +1,113 @@
+/* 
+ * V3 Control utility
+ * (c) Jack lange, 2010
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h> 
+#include <sys/ioctl.h> 
+#include <sys/stat.h> 
+#include <sys/types.h> 
+#include <unistd.h> 
+#include <string.h>
+#include "v3_ctrl.h"
+
+int read_file(int fd, int size, unsigned char * buf);
+
+int main(int argc, char* argv[]) {
+    char * filename = argv[1];
+    char * name = argv[2];
+    int guest_fd = 0;
+    int v3_fd = 0;
+    struct v3_guest_img guest_img;
+    struct stat guest_stats;
+    int dev_idx = 0;
+
+    memset(&guest_img, 0, sizeof(struct v3_guest_img));
+
+    if (argc <= 2) {
+       printf("Usage: ./v3_ctrl <guest_img> <vm name>\n");
+       return -1;
+    }
+
+    printf("Launching guest: %s\n", filename);
+
+    guest_fd = open(filename, O_RDONLY); 
+
+    if (guest_fd == -1) {
+       printf("Error Opening guest image: %s\n", filename);
+       return -1;
+    }
+
+    if (fstat(guest_fd, &guest_stats) == -1) {
+       printf("ERROR: Could not stat guest image file -- %s\n", filename);
+       return -1;
+    }
+
+    
+    guest_img.size = guest_stats.st_size;
+    
+    // load guest image into user memory
+    guest_img.guest_data = malloc(guest_img.size);
+
+    read_file(guest_fd, guest_img.size, guest_img.guest_data);
+    
+    close(guest_fd);
+
+    printf("Loaded guest image. Launching to V3Vee\n");
+    
+    strncpy(guest_img.name, name, 127);
+
+
+    v3_fd = open(v3_dev, O_RDONLY);
+
+    if (v3_fd == -1) {
+       printf("Error opening V3Vee control device\n");
+       return -1;
+    }
+
+    dev_idx = ioctl(v3_fd, V3_CREATE_GUEST, &guest_img); 
+
+
+    if (dev_idx < 0) {
+       printf("Error (%d) creating VM\n", dev_idx);
+       return -1;
+    }
+
+    printf("VM (%s) created at /dev/v3-vm%d\n", name, dev_idx);
+
+    /* Close the file descriptor.  */ 
+    close(v3_fd); 
+
+
+    return 0; 
+} 
+
+
+
+int read_file(int fd, int size, unsigned char * buf) {
+    int left_to_read = size;
+    int have_read = 0;
+
+    while (left_to_read != 0) {
+       int bytes_read = read(fd, buf + have_read, left_to_read);
+
+       if (bytes_read <= 0) {
+           break;
+       }
+
+       have_read += bytes_read;
+       left_to_read -= bytes_read;
+    }
+
+    if (left_to_read != 0) {
+       printf("Error could not finish reading file\n");
+       return -1;
+    }
+    
+    return 0;
+}
index 0826825..442c2d9 100644 (file)
@@ -6,8 +6,6 @@
 #ifndef _v3_ctrl_h
 #define _v3_ctrl_h
 
-#define V3_START_GUEST 10
-#define V3_STOP_GUEST 11
 #define V3_CREATE_GUEST 12
 #define V3_FREE_GUEST 13
 
diff --git a/linux_usr/v3_free.c b/linux_usr/v3_free.c
new file mode 100644 (file)
index 0000000..8e3c41f
--- /dev/null
@@ -0,0 +1,52 @@
+/* 
+ * V3 Control utility
+ * (c) Jack lange, 2011
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h> 
+#include <sys/ioctl.h> 
+#include <sys/stat.h> 
+#include <sys/types.h> 
+#include <unistd.h> 
+#include <string.h>
+#include "v3_ctrl.h"
+
+int main(int argc, char* argv[]) {
+    int vm_fd = 0;
+    unsigned long vm_idx = 0;
+
+
+    if (argc <= 1) {
+       printf("Usage: ./v3_free <vm-dev-idx>\n");
+       return -1;
+    }
+
+
+    vm_idx = atoi(argv[1]);
+
+    printf("Freeing VM %d\n", vm_idx);
+    
+    vm_fd = open("/dev/v3vee", O_RDONLY);
+
+    if (vm_fd == -1) {
+       printf("Error opening V3Vee VM device\n");
+       return -1;
+    }
+
+    ioctl(vm_fd, V3_FREE_GUEST, vm_idx); 
+
+
+
+    /* Close the file descriptor.  */ 
+    close(vm_fd); 
+
+
+    return 0; 
+} 
+
+
diff --git a/linux_usr/v3_launch.c b/linux_usr/v3_launch.c
new file mode 100644 (file)
index 0000000..6eb4dde
--- /dev/null
@@ -0,0 +1,48 @@
+/* 
+ * V3 Control utility
+ * (c) Jack lange, 2010
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h> 
+#include <sys/ioctl.h> 
+#include <sys/stat.h> 
+#include <sys/types.h> 
+#include <unistd.h> 
+#include <string.h>
+#include "v3_ctrl.h"
+
+int main(int argc, char* argv[]) {
+    int vm_fd = 0;
+    char * filename = argv[1];
+
+    if (argc <= 1) {
+       printf("Usage: ./v3_launch <vm-device>\n");
+       return -1;
+    }
+
+    printf("Launching VM (%s)\n", filename);
+    
+    vm_fd = open(filename, O_RDONLY);
+
+    if (vm_fd == -1) {
+       printf("Error opening V3Vee VM device\n");
+       return -1;
+    }
+
+    ioctl(vm_fd, V3_VM_LAUNCH, NULL); 
+
+
+
+    /* Close the file descriptor.  */ 
+    close(vm_fd); 
+
+
+    return 0; 
+} 
+
+
index 061cd28..a5f3249 100644 (file)
  
 #include "v3_ctrl.h"
 
-int read_file(int fd, int size, unsigned char * buf);
-
 int main(int argc, char* argv[]) {
     int vm_fd = 0;
-    unsigned long vm_idx = 0;
-
+    char * filename = argv[1];
 
     if (argc <= 1) {
-       printf("Usage: ./v3_stop <vm-dev-idx>\n");
+       printf("Usage: ./v3_stop <vm-device>\n");
        return -1;
     }
 
-
-    vm_idx = atoi(argv[1]);
-
-    printf("Stopping VM\n");
+    printf("Stopping VM (%s)\n", filename);
     
-    vm_fd = open("/dev/v3vee", O_RDONLY);
+    vm_fd = open(filename, O_RDONLY);
 
     if (vm_fd == -1) {
        printf("Error opening V3Vee VM device\n");
        return -1;
     }
 
-    ioctl(vm_fd, V3_STOP_GUEST, vm_idx); 
+    ioctl(vm_fd, V3_VM_STOP, NULL); 
 
 
 
index 46864fd..ff2e27d 100644 (file)
@@ -83,7 +83,7 @@ struct v3_pci_bar {
 
     // Internal PCI data
     uint32_t val;
-    int updated;
+    uint8_t updated;
     uint32_t mask;
 };
 
index 9bb5e81..17beb58 100644 (file)
@@ -39,9 +39,38 @@ struct v3_chkpt_ctx {
 #define  V3_CHKPT_STD_LOAD(ctx,x) v3_chkpt_load(ctx,#x,sizeof(x),&(x))
 
 
+
 int v3_chkpt_save(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf);
 int v3_chkpt_load(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf);
 
+static inline int v3_chkpt_save_64(struct v3_chkpt_ctx * ctx, char * tag, void * buf) {
+    return v3_chkpt_save(ctx, tag, 8, buf);
+}
+static inline int v3_chkpt_save_32(struct v3_chkpt_ctx * ctx, char * tag, void * buf) {
+    return v3_chkpt_save(ctx, tag, 4, buf);
+}
+static inline int v3_chkpt_save_16(struct v3_chkpt_ctx * ctx, char * tag, void * buf) {
+    return v3_chkpt_save(ctx, tag, 2, buf);
+}
+static inline int v3_chkpt_save_8(struct v3_chkpt_ctx * ctx, char * tag, void * buf) {
+    return v3_chkpt_save(ctx, tag, 1, buf);
+}
+
+static inline int v3_chkpt_load_64(struct v3_chkpt_ctx * ctx, char * tag, void * buf) {
+    return v3_chkpt_load(ctx, tag, 8, buf);
+}
+static inline int v3_chkpt_load_32(struct v3_chkpt_ctx * ctx, char * tag, void * buf) {
+    return v3_chkpt_load(ctx, tag, 4, buf);
+}
+static inline int v3_chkpt_load_16(struct v3_chkpt_ctx * ctx, char * tag, void * buf) {
+    return v3_chkpt_load(ctx, tag, 2, buf);
+}
+static inline int v3_chkpt_load_8(struct v3_chkpt_ctx * ctx, char * tag, void * buf) {
+    return v3_chkpt_load(ctx, tag, 1, buf);
+}
+
+
+
 int v3_chkpt_close_ctx(struct v3_chkpt_ctx * ctx);
 struct v3_chkpt_ctx * v3_chkpt_open_ctx(struct v3_chkpt * chkpt, struct v3_chkpt_ctx * parent, char * name);
 
index 5103791..b383151 100644 (file)
@@ -124,35 +124,35 @@ struct ocw3 {
 struct pic_internal {
 
 
-    uchar_t master_irr;
-    uchar_t slave_irr;
+    uint8_t master_irr;
+    uint8_t slave_irr;
   
-    uchar_t master_isr;
-    uchar_t slave_isr;
+    uint8_t master_isr;
+    uint8_t slave_isr;
 
-    uchar_t master_elcr;
-    uchar_t slave_elcr;
-    uchar_t master_elcr_mask;
-    uchar_t slave_elcr_mask;
+    uint8_t master_elcr;
+    uint8_t slave_elcr;
+    uint8_t master_elcr_mask;
+    uint8_t slave_elcr_mask;
 
-    uchar_t master_icw1;
-    uchar_t master_icw2;
-    uchar_t master_icw3;
-    uchar_t master_icw4;
+    uint8_t master_icw1;
+    uint8_t master_icw2;
+    uint8_t master_icw3;
+    uint8_t master_icw4;
 
 
-    uchar_t slave_icw1;
-    uchar_t slave_icw2;
-    uchar_t slave_icw3;
-    uchar_t slave_icw4;
+    uint8_t slave_icw1;
+    uint8_t slave_icw2;
+    uint8_t slave_icw3;
+    uint8_t slave_icw4;
 
 
-    uchar_t master_imr;
-    uchar_t slave_imr;
-    uchar_t master_ocw2;
-    uchar_t master_ocw3;
-    uchar_t slave_ocw2;
-    uchar_t slave_ocw3;
+    uint8_t master_imr;
+    uint8_t slave_imr;
+    uint8_t master_ocw2;
+    uint8_t master_ocw3;
+    uint8_t slave_ocw2;
+    uint8_t slave_ocw3;
 
     pic_state_t master_state;
     pic_state_t slave_state;
@@ -375,11 +375,11 @@ static int read_master_port1(struct guest_info * core, ushort_t port, void * dst
     }
   
     if ((state->master_ocw3 & 0x03) == 0x02) {
-       *(uchar_t *)dst = state->master_irr;
+       *(uint8_t *)dst = state->master_irr;
     } else if ((state->master_ocw3 & 0x03) == 0x03) {
-       *(uchar_t *)dst = state->master_isr;
+       *(uint8_t *)dst = state->master_isr;
     } else {
-       *(uchar_t *)dst = 0;
+       *(uint8_t *)dst = 0;
     }
   
     return 1;
@@ -393,7 +393,7 @@ static int read_master_port2(struct guest_info * core, ushort_t port, void * dst
        return -1;
     }
 
-    *(uchar_t *)dst = state->master_imr;
+    *(uint8_t *)dst = state->master_imr;
 
     return 1;
   
@@ -408,11 +408,11 @@ static int read_slave_port1(struct guest_info * core, ushort_t port, void * dst,
     }
   
     if ((state->slave_ocw3 & 0x03) == 0x02) {
-       *(uchar_t*)dst = state->slave_irr;
+       *(uint8_t*)dst = state->slave_irr;
     } else if ((state->slave_ocw3 & 0x03) == 0x03) {
-       *(uchar_t *)dst = state->slave_isr;
+       *(uint8_t *)dst = state->slave_isr;
     } else {
-       *(uchar_t *)dst = 0;
+       *(uint8_t *)dst = 0;
     }
 
     return 1;
@@ -426,7 +426,7 @@ static int read_slave_port2(struct guest_info * core, ushort_t port, void * dst,
        return -1;
     }
 
-    *(uchar_t *)dst = state->slave_imr;
+    *(uint8_t *)dst = state->slave_imr;
 
     return 1;
 }
@@ -434,7 +434,7 @@ static int read_slave_port2(struct guest_info * core, ushort_t port, void * dst,
 
 static int write_master_port1(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
     struct pic_internal * state = (struct pic_internal *)priv_data;
-    uchar_t cw = *(uchar_t *)src;
+    uint8_t cw = *(uint8_t *)src;
 
     PrintDebug("8259 PIC: Write master port 1 with 0x%x\n",cw);
 
@@ -502,7 +502,7 @@ static int write_master_port1(struct guest_info * core, ushort_t port, void * sr
 
 static int write_master_port2(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
     struct pic_internal * state = (struct pic_internal *)priv_data;
-    uchar_t cw = *(uchar_t *)src;    
+    uint8_t cw = *(uint8_t *)src;    
 
     PrintDebug("8259 PIC: Write master port 2 with 0x%x\n",cw);
 
@@ -563,7 +563,7 @@ static int write_master_port2(struct guest_info * core, ushort_t port, void * sr
 
 static int write_slave_port1(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
     struct pic_internal * state = (struct pic_internal *)priv_data;
-    uchar_t cw = *(uchar_t *)src;
+    uint8_t cw = *(uint8_t *)src;
 
     PrintDebug("8259 PIC: Write slave port 1 with 0x%x\n",cw);
 
@@ -624,7 +624,7 @@ static int write_slave_port1(struct guest_info * core, ushort_t port, void * src
 
 static int write_slave_port2(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
     struct pic_internal * state = (struct pic_internal *)priv_data;
-    uchar_t cw = *(uchar_t *)src;    
+    uint8_t cw = *(uint8_t *)src;    
 
     PrintDebug("8259 PIC: Write slave port 2 with 0x%x\n",cw);
 
@@ -741,38 +741,38 @@ static int pic_free(struct pic_internal * state) {
 static int pic_save(struct v3_chkpt_ctx * ctx, void * private_data) {
     struct pic_internal * pic = (struct pic_internal *)private_data;
 
-    V3_CHKPT_STD_SAVE(ctx, pic->master_irr);
-    V3_CHKPT_STD_SAVE(ctx, pic->slave_irr);
+    v3_chkpt_save_8(ctx, "MASTER_IRR", &(pic->master_irr));
+    v3_chkpt_save_8(ctx, "SLAVE_IRR", &(pic->slave_irr));
   
-    V3_CHKPT_STD_SAVE(ctx, pic->master_isr);
-    V3_CHKPT_STD_SAVE(ctx, pic->slave_isr);
+    v3_chkpt_save_8(ctx, "MASTER_ISR", &(pic->master_isr));
+    v3_chkpt_save_8(ctx, "SLAVE_ISR", &(pic->slave_isr));
 
-    V3_CHKPT_STD_SAVE(ctx, pic->master_elcr);
-    V3_CHKPT_STD_SAVE(ctx, pic->slave_elcr);
-    V3_CHKPT_STD_SAVE(ctx, pic->master_elcr_mask);
-    V3_CHKPT_STD_SAVE(ctx, pic->slave_elcr_mask);
+    v3_chkpt_save_8(ctx, "MASTER_ELCR", &(pic->master_elcr));
+    v3_chkpt_save_8(ctx, "SLAVE_ELCR", &(pic->slave_elcr));
+    v3_chkpt_save_8(ctx, "MASTER_ELCR_MASK", &(pic->master_elcr_mask));
+    v3_chkpt_save_8(ctx, "SLAVE_ELCR_MASK", &(pic->slave_elcr_mask));
 
-    V3_CHKPT_STD_SAVE(ctx, pic->master_icw1);
-    V3_CHKPT_STD_SAVE(ctx, pic->master_icw2);
-    V3_CHKPT_STD_SAVE(ctx, pic->master_icw3);
-    V3_CHKPT_STD_SAVE(ctx, pic->master_icw4);
+    v3_chkpt_save_8(ctx, "MASTER_ICW1", &(pic->master_icw1));
+    v3_chkpt_save_8(ctx, "MASTER_ICW2", &(pic->master_icw2));
+    v3_chkpt_save_8(ctx, "MASTER_ICW3", &(pic->master_icw3));
+    v3_chkpt_save_8(ctx, "MASTER_ICW4", &(pic->master_icw4));
 
 
-    V3_CHKPT_STD_SAVE(ctx, pic->slave_icw1);
-    V3_CHKPT_STD_SAVE(ctx, pic->slave_icw2);
-    V3_CHKPT_STD_SAVE(ctx, pic->slave_icw3);
-    V3_CHKPT_STD_SAVE(ctx, pic->slave_icw4);
+    v3_chkpt_save_8(ctx, "SLAVE_ICW1", &(pic->slave_icw1));
+    v3_chkpt_save_8(ctx, "SLAVE_ICW2", &(pic->slave_icw2));
+    v3_chkpt_save_8(ctx, "SLAVE_ICW3", &(pic->slave_icw3));
+    v3_chkpt_save_8(ctx, "SLAVE_ICW4", &(pic->slave_icw4));
 
 
-    V3_CHKPT_STD_SAVE(ctx, pic->master_imr);
-    V3_CHKPT_STD_SAVE(ctx, pic->slave_imr);
-    V3_CHKPT_STD_SAVE(ctx, pic->master_ocw2);
-    V3_CHKPT_STD_SAVE(ctx, pic->master_ocw3);
-    V3_CHKPT_STD_SAVE(ctx, pic->slave_ocw2);
-    V3_CHKPT_STD_SAVE(ctx, pic->slave_ocw3);
+    v3_chkpt_save_8(ctx, "MASTER_IMR", &(pic->master_imr));
+    v3_chkpt_save_8(ctx, "SLAVE_IMR", &(pic->slave_imr));
+    v3_chkpt_save_8(ctx, "MASTER_OCW2", &(pic->master_ocw2));
+    v3_chkpt_save_8(ctx, "MASTER_OCW3", &(pic->master_ocw3));
+    v3_chkpt_save_8(ctx, "SLAVE_OCW2", &(pic->slave_ocw2));
+    v3_chkpt_save_8(ctx, "SLAVE_OCW3", &(pic->slave_ocw3));
 
-    V3_CHKPT_STD_SAVE(ctx, pic->master_state);
-    V3_CHKPT_STD_SAVE(ctx, pic->slave_state);
+    v3_chkpt_save_8(ctx, "MASTER_STATE", &(pic->master_state));
+    v3_chkpt_save_8(ctx, "SLAVE_STATE", &(pic->slave_state));
 
     
     return 0;
@@ -782,38 +782,39 @@ static int pic_save(struct v3_chkpt_ctx * ctx, void * private_data) {
 static int pic_load(struct v3_chkpt_ctx * ctx, void * private_data) {
     struct pic_internal * pic = (struct pic_internal *)private_data;
 
-    V3_CHKPT_STD_LOAD(ctx, pic->master_irr);
-    V3_CHKPT_STD_LOAD(ctx, pic->slave_irr);
+   
+    v3_chkpt_load_8(ctx, "MASTER_IRR", &(pic->master_irr));
+    v3_chkpt_load_8(ctx, "SLAVE_IRR", &(pic->slave_irr));
   
-    V3_CHKPT_STD_LOAD(ctx, pic->master_isr);
-    V3_CHKPT_STD_LOAD(ctx, pic->slave_isr);
+    v3_chkpt_load_8(ctx, "MASTER_ISR", &(pic->master_isr));
+    v3_chkpt_load_8(ctx, "SLAVE_ISR", &(pic->slave_isr));
 
-    V3_CHKPT_STD_LOAD(ctx, pic->master_elcr);
-    V3_CHKPT_STD_LOAD(ctx, pic->slave_elcr);
-    V3_CHKPT_STD_LOAD(ctx, pic->master_elcr_mask);
-    V3_CHKPT_STD_LOAD(ctx, pic->slave_elcr_mask);
+    v3_chkpt_load_8(ctx, "MASTER_ELCR", &(pic->master_elcr));
+    v3_chkpt_load_8(ctx, "SLAVE_ELCR", &(pic->slave_elcr));
+    v3_chkpt_load_8(ctx, "MASTER_ELCR_MASK", &(pic->master_elcr_mask));
+    v3_chkpt_load_8(ctx, "SLAVE_ELCR_MASK", &(pic->slave_elcr_mask));
 
-    V3_CHKPT_STD_LOAD(ctx, pic->master_icw1);
-    V3_CHKPT_STD_LOAD(ctx, pic->master_icw2);
-    V3_CHKPT_STD_LOAD(ctx, pic->master_icw3);
-    V3_CHKPT_STD_LOAD(ctx, pic->master_icw4);
+    v3_chkpt_load_8(ctx, "MASTER_ICW1", &(pic->master_icw1));
+    v3_chkpt_load_8(ctx, "MASTER_ICW2", &(pic->master_icw2));
+    v3_chkpt_load_8(ctx, "MASTER_ICW3", &(pic->master_icw3));
+    v3_chkpt_load_8(ctx, "MASTER_ICW4", &(pic->master_icw4));
 
 
-    V3_CHKPT_STD_LOAD(ctx, pic->slave_icw1);
-    V3_CHKPT_STD_LOAD(ctx, pic->slave_icw2);
-    V3_CHKPT_STD_LOAD(ctx, pic->slave_icw3);
-    V3_CHKPT_STD_LOAD(ctx, pic->slave_icw4);
+    v3_chkpt_load_8(ctx, "SLAVE_ICW1", &(pic->slave_icw1));
+    v3_chkpt_load_8(ctx, "SLAVE_ICW2", &(pic->slave_icw2));
+    v3_chkpt_load_8(ctx, "SLAVE_ICW3", &(pic->slave_icw3));
+    v3_chkpt_load_8(ctx, "SLAVE_ICW4", &(pic->slave_icw4));
 
 
-    V3_CHKPT_STD_LOAD(ctx, pic->master_imr);
-    V3_CHKPT_STD_LOAD(ctx, pic->slave_imr);
-    V3_CHKPT_STD_LOAD(ctx, pic->master_ocw2);
-    V3_CHKPT_STD_LOAD(ctx, pic->master_ocw3);
-    V3_CHKPT_STD_LOAD(ctx, pic->slave_ocw2);
-    V3_CHKPT_STD_LOAD(ctx, pic->slave_ocw3);
+    v3_chkpt_load_8(ctx, "MASTER_IMR", &(pic->master_imr));
+    v3_chkpt_load_8(ctx, "SLAVE_IMR", &(pic->slave_imr));
+    v3_chkpt_load_8(ctx, "MASTER_OCW2", &(pic->master_ocw2));
+    v3_chkpt_load_8(ctx, "MASTER_OCW3", &(pic->master_ocw3));
+    v3_chkpt_load_8(ctx, "SLAVE_OCW2", &(pic->slave_ocw2));
+    v3_chkpt_load_8(ctx, "SLAVE_OCW3", &(pic->slave_ocw3));
 
-    V3_CHKPT_STD_LOAD(ctx, pic->master_state);
-    V3_CHKPT_STD_LOAD(ctx, pic->slave_state);
+    v3_chkpt_load_8(ctx, "MASTER_STATE", &(pic->master_state));
+    v3_chkpt_load_8(ctx, "SLAVE_STATE", &(pic->slave_state));
 
     return 0;
 }
index 3fd752d..299a2bb 100644 (file)
@@ -67,6 +67,36 @@ struct atapi_sense_data {
 } __attribute__((packed));
 
 
+struct atapi_error_recovery {
+    union {
+       uint8_t buf[12];
+       struct {
+           uint8_t page_code     : 6;
+           uint8_t rsvd          : 1;
+           uint8_t page_ctrl     : 1;
+           uint8_t page_len;
+           uint8_t dcr           : 1;
+           uint8_t dte           : 1;
+           uint8_t per           : 1;
+           uint8_t rsvd1         : 1;
+           uint8_t rc            : 1;
+           uint8_t tb            : 1;
+           uint8_t arre          : 1;
+           uint8_t awre          : 1;
+           uint8_t rd_retry_cnt;
+           uint8_t correct_spin;
+           uint8_t head_offset;
+           uint8_t data_strobe_offset;
+           uint8_t emcdr         : 2;
+           uint8_t rsvd2         : 6;
+           uint8_t wr_retry_cnt;
+           uint8_t rsvd3;
+           uint16_t recovery_time_limit;
+       } __attribute__((packed));
+    } __attribute__((packed));
+} __attribute__((packed));
+
+
 
 
 struct atapi_read10_cmd {
@@ -282,29 +312,6 @@ struct atapi_inquiry_resp {
 
 
 
-struct atapi_error_recovery {
-    uint8_t page_code     : 6;
-    uint8_t rsvd          : 1;
-    uint8_t page_ctrl     : 1;
-    uint8_t page_len;
-    uint8_t dcr           : 1;
-    uint8_t dte           : 1;
-    uint8_t per           : 1;
-    uint8_t rsvd1         : 1;
-    uint8_t rc            : 1;
-    uint8_t tb            : 1;
-    uint8_t arre          : 1;
-    uint8_t awre          : 1;
-    uint8_t rd_retry_cnt;
-    uint8_t correct_spin;
-    uint8_t head_offset;
-    uint8_t data_strobe_offset;
-    uint8_t emcdr         : 2;
-    uint8_t rsvd2         : 6;
-    uint8_t wr_retry_cnt;
-    uint8_t rsvd3;
-    uint16_t recovery_time_limit;
-} __attribute__((packed));
 
 
 struct atapi_cdrom_caps {
index 0081609..3fe3743 100644 (file)
@@ -1116,6 +1116,8 @@ static int cga_free(struct video_internal * video_state) {
 static int cga_save(struct v3_chkpt_ctx * ctx, void * private_data) {
     struct video_internal * cga = (struct video_internal *)private_data;
 
+    v3_chkpt_save(ctx, "FRAMEBUFFER", FRAMEBUF_SIZE, cga->framebuf);
+
     V3_CHKPT_STD_SAVE(ctx, cga->misc_outp_reg);
     V3_CHKPT_STD_SAVE(ctx, cga->seq_index_reg);                
     V3_CHKPT_STD_SAVE(ctx, cga->seq_data_regs[SEQ_REG_COUNT]); 
@@ -1146,12 +1148,18 @@ static int cga_save(struct v3_chkpt_ctx * ctx, void * private_data) {
 
     V3_CHKPT_STD_SAVE(ctx, cga->passthrough);
 
+    v3_chkpt_save_16(ctx, "SCREEN_OFFSET", &(cga->screen_offset));
+    v3_chkpt_save_16(ctx, "CURSOR_OFFSET", &(cga->cursor_offset));
+
     return 0;
 }
 
 static int cga_load(struct v3_chkpt_ctx * ctx, void * private_data) {
     struct video_internal * cga = (struct video_internal *)private_data;
 
+    v3_chkpt_load(ctx, "FRAMEBUFFER", FRAMEBUF_SIZE, cga->framebuf);
+
+
     V3_CHKPT_STD_LOAD(ctx, cga->misc_outp_reg);
     V3_CHKPT_STD_LOAD(ctx, cga->seq_index_reg);                
     V3_CHKPT_STD_LOAD(ctx, cga->seq_data_regs[SEQ_REG_COUNT]); 
@@ -1182,6 +1190,10 @@ static int cga_load(struct v3_chkpt_ctx * ctx, void * private_data) {
 
     V3_CHKPT_STD_LOAD(ctx, cga->passthrough);
 
+    v3_chkpt_load_16(ctx, "SCREEN_OFFSET", &(cga->screen_offset));
+    v3_chkpt_load_16(ctx, "CURSOR_OFFSET", &(cga->cursor_offset));
+
+
     return 0;
 }
 
index d407551..f5baf95 100644 (file)
@@ -110,16 +110,16 @@ struct ide_cd_state {
 };
 
 struct ide_hd_state {
-    int accessed;
+    uint32_t accessed;
 
     /* this is the multiple sector transfer size as configured for read/write multiple sectors*/
-    uint_t mult_sector_num;
+    uint32_t mult_sector_num;
 
     /* This is the current op sector size:
      * for multiple sector ops this equals mult_sector_num
      * for standard ops this equals 1
      */
-    uint_t cur_sector_num;
+    uint32_t cur_sector_num;
 };
 
 struct ide_drive {
@@ -137,11 +137,11 @@ struct ide_drive {
     char model[41];
 
     // Where we are in the data transfer
-    uint_t transfer_index;
+    uint32_t transfer_index;
 
     // the length of a transfer
     // calculated for easy access
-    uint_t transfer_length;
+    uint32_t transfer_length;
 
     uint64_t current_lba;
 
@@ -209,7 +209,7 @@ struct ide_channel {
     struct ide_dma_cmd_reg dma_cmd;
     struct ide_dma_status_reg dma_status;
     uint32_t dma_prd_addr;
-    uint_t dma_tbl_index;
+    uint32_t dma_tbl_index;
 };
 
 
@@ -1507,9 +1507,146 @@ static int ide_free(struct ide_internal * ide) {
     return 0;
 }
 
+#ifdef V3_CONFIG_CHECKPOINT
+
+#include <palacios/vmm_sprintf.h>
+static int ide_save(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct ide_internal * ide = (struct ide_internal *)private_data;
+    int ch_num = 0;
+    int drive_num = 0;
+    char buf[128];
+    
+
+    for (ch_num = 0; ch_num < 2; ch_num++) {
+       struct v3_chkpt_ctx * ch_ctx = NULL;
+       struct ide_channel * ch = &(ide->channels[ch_num]);
+
+       snprintf(buf, 128, "channel-%d", ch_num);
+       ch_ctx = v3_chkpt_open_ctx(ctx->chkpt, ctx, buf);
+
+       v3_chkpt_save_8(ch_ctx, "ERROR", &(ch->error_reg.val));
+       v3_chkpt_save_8(ch_ctx, "FEATURES", &(ch->features.val));
+       v3_chkpt_save_8(ch_ctx, "DRIVE_HEAD", &(ch->drive_head.val));
+       v3_chkpt_save_8(ch_ctx, "STATUS", &(ch->status.val));
+       v3_chkpt_save_8(ch_ctx, "CMD_REG", &(ch->cmd_reg));
+       v3_chkpt_save_8(ch_ctx, "CTRL_REG", &(ch->ctrl_reg.val));
+       v3_chkpt_save_8(ch_ctx, "DMA_CMD", &(ch->dma_cmd.val));
+       v3_chkpt_save_8(ch_ctx, "DMA_STATUS", &(ch->dma_status.val));
+       v3_chkpt_save_32(ch_ctx, "PRD_ADDR", &(ch->dma_prd_addr));
+       v3_chkpt_save_32(ch_ctx, "DMA_TBL_IDX", &(ch->dma_tbl_index));
+
+
+       for (drive_num = 0; drive_num < 2; drive_num++) {
+           struct v3_chkpt_ctx * drive_ctx = NULL;
+           struct ide_drive * drive = &(ch->drives[drive_num]);
+           
+           snprintf(buf, 128, "drive-%d-%d", ch_num, drive_num);
+           drive_ctx = v3_chkpt_open_ctx(ctx->chkpt, ch_ctx, buf);
+           
+           v3_chkpt_save_8(drive_ctx, "DRIVE_TYPE", &(drive->drive_type));
+           v3_chkpt_save_8(drive_ctx, "SECTOR_COUNT", &(drive->sector_count));
+           v3_chkpt_save_8(drive_ctx, "SECTOR_NUM", &(drive->sector_num));
+           v3_chkpt_save_16(drive_ctx, "CYLINDER", &(drive->cylinder));
+
+           v3_chkpt_save_64(drive_ctx, "CURRENT_LBA", &(drive->current_lba));
+           v3_chkpt_save_32(drive_ctx, "TRANSFER_LENGTH", &(drive->transfer_length));
+           v3_chkpt_save_32(drive_ctx, "TRANSFER_INDEX", &(drive->transfer_index));
+
+           v3_chkpt_save(drive_ctx, "DATA_BUF", DATA_BUFFER_SIZE, drive->data_buf);
+
+
+           /* For now we'll just pack the type specific data at the end... */
+           /* We should probably add a new context here in the future... */
+           if (drive->drive_type == BLOCK_CDROM) {
+               v3_chkpt_save(drive_ctx, "ATAPI_SENSE_DATA", 18, drive->cd_state.sense.buf);
+               v3_chkpt_save_8(drive_ctx, "ATAPI_CMD", &(drive->cd_state.atapi_cmd));
+               v3_chkpt_save(drive_ctx, "ATAPI_ERR_RECOVERY", 12, drive->cd_state.err_recovery.buf);
+           } else if (drive->drive_type == BLOCK_DISK) {
+               v3_chkpt_save_32(drive_ctx, "ACCESSED", &(drive->hd_state.accessed));
+               v3_chkpt_save_32(drive_ctx, "MULT_SECT_NUM", &(drive->hd_state.mult_sector_num));
+               v3_chkpt_save_32(drive_ctx, "CUR_SECT_NUM", &(drive->hd_state.cur_sector_num));
+           }
+       }
+    }
+
+    return 0;
+}
+
+
+
+static int ide_load(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct ide_internal * ide = (struct ide_internal *)private_data;
+    int ch_num = 0;
+    int drive_num = 0;
+    char buf[128];
+    
+
+    for (ch_num = 0; ch_num < 2; ch_num++) {
+       struct v3_chkpt_ctx * ch_ctx = NULL;
+       struct ide_channel * ch = &(ide->channels[ch_num]);
+
+       snprintf(buf, 128, "channel-%d", ch_num);
+       ch_ctx = v3_chkpt_open_ctx(ctx->chkpt, ctx, buf);
+
+       v3_chkpt_load_8(ch_ctx, "ERROR", &(ch->error_reg.val));
+       v3_chkpt_load_8(ch_ctx, "FEATURES", &(ch->features.val));
+       v3_chkpt_load_8(ch_ctx, "DRIVE_HEAD", &(ch->drive_head.val));
+       v3_chkpt_load_8(ch_ctx, "STATUS", &(ch->status.val));
+       v3_chkpt_load_8(ch_ctx, "CMD_REG", &(ch->cmd_reg));
+       v3_chkpt_load_8(ch_ctx, "CTRL_REG", &(ch->ctrl_reg.val));
+       v3_chkpt_load_8(ch_ctx, "DMA_CMD", &(ch->dma_cmd.val));
+       v3_chkpt_load_8(ch_ctx, "DMA_STATUS", &(ch->dma_status.val));
+       v3_chkpt_load_32(ch_ctx, "PRD_ADDR", &(ch->dma_prd_addr));
+       v3_chkpt_load_32(ch_ctx, "DMA_TBL_IDX", &(ch->dma_tbl_index));
+
+
+       for (drive_num = 0; drive_num < 2; drive_num++) {
+           struct v3_chkpt_ctx * drive_ctx = NULL;
+           struct ide_drive * drive = &(ch->drives[drive_num]);
+           
+           snprintf(buf, 128, "drive-%d-%d", ch_num, drive_num);
+           drive_ctx = v3_chkpt_open_ctx(ctx->chkpt, ch_ctx, buf);
+           
+           v3_chkpt_load_8(drive_ctx, "DRIVE_TYPE", &(drive->drive_type));
+           v3_chkpt_load_8(drive_ctx, "SECTOR_COUNT", &(drive->sector_count));
+           v3_chkpt_load_8(drive_ctx, "SECTOR_NUM", &(drive->sector_num));
+           v3_chkpt_load_16(drive_ctx, "CYLINDER", &(drive->cylinder));
+
+           v3_chkpt_load_64(drive_ctx, "CURRENT_LBA", &(drive->current_lba));
+           v3_chkpt_load_32(drive_ctx, "TRANSFER_LENGTH", &(drive->transfer_length));
+           v3_chkpt_load_32(drive_ctx, "TRANSFER_INDEX", &(drive->transfer_index));
+
+           v3_chkpt_load(drive_ctx, "DATA_BUF", DATA_BUFFER_SIZE, drive->data_buf);
+
+
+           /* For now we'll just pack the type specific data at the end... */
+           /* We should probably add a new context here in the future... */
+           if (drive->drive_type == BLOCK_CDROM) {
+               v3_chkpt_load(drive_ctx, "ATAPI_SENSE_DATA", 18, drive->cd_state.sense.buf);
+               v3_chkpt_load_8(drive_ctx, "ATAPI_CMD", &(drive->cd_state.atapi_cmd));
+               v3_chkpt_load(drive_ctx, "ATAPI_ERR_RECOVERY", 12, drive->cd_state.err_recovery.buf);
+           } else if (drive->drive_type == BLOCK_DISK) {
+               v3_chkpt_load_32(drive_ctx, "ACCESSED", &(drive->hd_state.accessed));
+               v3_chkpt_load_32(drive_ctx, "MULT_SECT_NUM", &(drive->hd_state.mult_sector_num));
+               v3_chkpt_load_32(drive_ctx, "CUR_SECT_NUM", &(drive->hd_state.cur_sector_num));
+           }
+       }
+    }
+
+    return 0;
+}
+
+
+
+#endif
+
 
 static struct v3_device_ops dev_ops = {
     .free = (int (*)(void *))ide_free,
+#ifdef V3_CONFIG_CHECKPOINT
+    .save = ide_save,
+    .load = ide_load
+#endif
 
 };
 
index 5943fd3..1dc482d 100644 (file)
@@ -211,8 +211,8 @@ struct keyboard_internal {
     // Data for system
     uint8_t wrap;     
 
-    int mouse_enabled;
-    int scancode_set;
+    uint8_t mouse_enabled;
+    uint8_t scancode_set;
 
     struct queue kbd_queue;
     struct queue mouse_queue;
@@ -1053,6 +1053,18 @@ static int keyboard_reset_device(struct keyboard_internal * kbd) {
 
 #ifdef V3_CONFIG_CHECKPOINT
 static int keyboard_save(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct keyboard_internal * kbd = (struct keyboard_internal *)private_data;
+
+    v3_chkpt_save_8(ctx, "CMD_REG", &(kbd->cmd.val));
+    v3_chkpt_save_8(ctx, "STATUS_REG", &(kbd->status.val));
+    v3_chkpt_save_8(ctx, "STATE", &(kbd->state));
+    v3_chkpt_save_8(ctx, "MOUSE_STATE", &(kbd->mouse_state));
+    v3_chkpt_save_8(ctx, "OUTPUT", &(kbd->output_byte));
+    v3_chkpt_save_8(ctx, "INPUT", &(kbd->input_byte));
+    v3_chkpt_save_8(ctx, "SCANCODE_SET", &(kbd->scancode_set));
+    v3_chkpt_save_8(ctx, "MOUSE_ENABLED", &(kbd->mouse_enabled));
+
+
     return 0;
 }
 
@@ -1060,6 +1072,17 @@ static int keyboard_save(struct v3_chkpt_ctx * ctx, void * private_data) {
 static int keyboard_load(struct v3_chkpt_ctx * ctx, void * private_data) {
     struct keyboard_internal * kbd = (struct keyboard_internal *)private_data;
     keyboard_reset_device(kbd);
+
+    v3_chkpt_load_8(ctx, "CMD_REG", &(kbd->cmd.val));
+    v3_chkpt_load_8(ctx, "STATUS_REG", &(kbd->status.val));
+    v3_chkpt_load_8(ctx, "STATE", &(kbd->state));
+    v3_chkpt_load_8(ctx, "MOUSE_STATE", &(kbd->mouse_state));
+    v3_chkpt_load_8(ctx, "OUTPUT", &(kbd->output_byte));
+    v3_chkpt_load_8(ctx, "INPUT", &(kbd->input_byte));
+    v3_chkpt_load_8(ctx, "SCANCODE_SET", &(kbd->scancode_set));
+    v3_chkpt_load_8(ctx, "MOUSE_ENABLED", &(kbd->mouse_enabled));
+
+
     return 0;
 }
 
index 0400751..05272a8 100644 (file)
@@ -634,10 +634,105 @@ static int pci_free(struct pci_internal * pci_state) {
     return 0;
 }
 
+#ifdef V3_CONFIG_CHECKPOINT
+
+#include <palacios/vmm_sprintf.h>
+
+static int pci_save(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct pci_internal * pci = (struct pci_internal *)private_data;
+    char buf[128];
+    int i = 0;    
+    
+    v3_chkpt_save_32(ctx, "ADDR_REG", &(pci->addr_reg.val));
+    v3_chkpt_save_16(ctx, "IO_BASE", &(pci->dev_io_base));
+
+    for (i = 0; i < PCI_BUS_COUNT; i++) {
+       struct pci_bus * bus = &(pci->bus_list[i]);
+       struct rb_node * node = v3_rb_first(&(bus->devices));
+       struct pci_device * dev = NULL;
+       struct v3_chkpt_ctx * bus_ctx = NULL;
+
+       snprintf(buf, 128, "pci-%d\n", i);
+       
+       bus_ctx = v3_chkpt_open_ctx(ctx->chkpt, ctx, buf);
+
+       while (node) {
+           struct v3_chkpt_ctx * dev_ctx = NULL;
+           int bar_idx = 0;
+           dev = rb_entry(node, struct pci_device, dev_tree_node);
+
+           snprintf(buf, 128, "pci-%d.%d-%d", i, dev->dev_num, dev->fn_num);
+           dev_ctx = v3_chkpt_open_ctx(bus_ctx->chkpt, bus_ctx, buf);
+           
+           v3_chkpt_save(dev_ctx, "CONFIG_SPACE", 256, dev->config_space);
+
+           for (bar_idx = 0; bar_idx < 6; bar_idx++) {
+               snprintf(buf, 128, "BAR-%d", bar_idx);
+               v3_chkpt_save_32(dev_ctx, buf, &(dev->bar[bar_idx].val));
+           }
+
+           node = v3_rb_next(node);
+       }
+    }
+
+
+    return 0;
+}
+
+
+static int pci_load(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct pci_internal * pci = (struct pci_internal *)private_data;
+    char buf[128];
+    int i = 0;    
+    
+    v3_chkpt_load_32(ctx, "ADDR_REG", &(pci->addr_reg.val));
+    v3_chkpt_load_16(ctx, "IO_BASE", &(pci->dev_io_base));
+
+    for (i = 0; i < PCI_BUS_COUNT; i++) {
+       struct pci_bus * bus = &(pci->bus_list[i]);
+       struct rb_node * node = v3_rb_first(&(bus->devices));
+       struct pci_device * dev = NULL;
+       struct v3_chkpt_ctx * bus_ctx = NULL;
+
+       snprintf(buf, 128, "pci-%d\n", i);
+       
+       bus_ctx = v3_chkpt_open_ctx(ctx->chkpt, ctx, buf);
+
+       while (node) {
+           struct v3_chkpt_ctx * dev_ctx = NULL;
+           int bar_idx = 0;
+           dev = rb_entry(node, struct pci_device, dev_tree_node);
+
+           snprintf(buf, 128, "pci-%d.%d-%d", i, dev->dev_num, dev->fn_num);
+           dev_ctx = v3_chkpt_open_ctx(bus_ctx->chkpt, bus_ctx, buf);
+           
+           v3_chkpt_load(dev_ctx, "CONFIG_SPACE", 256, dev->config_space);
+
+           for (bar_idx = 0; bar_idx < 6; bar_idx++) {
+               snprintf(buf, 128, "BAR-%d", bar_idx);
+               v3_chkpt_load_32(dev_ctx, buf, &(dev->bar[bar_idx].val));
+           }
+
+           node = v3_rb_next(node);
+       }
+    }
+
+
+    return 0;
+}
+
+
+#endif
+
+
+
 
 static struct v3_device_ops dev_ops = {
     .free = (int (*)(void *))pci_free,
-
+#ifdef V3_CONFIG_CHECKPOINT
+    .save = pci_save,
+    .load = pci_load
+#endif
 };
 
 
index 5319f90..6064855 100644 (file)
@@ -345,61 +345,20 @@ int v3_deinit_svm_vmcb(struct guest_info * core) {
 #ifdef V3_CONFIG_CHECKPOINT
 int v3_svm_save_core(struct guest_info * core, void * ctx){
 
+    v3_chkpt_save_8(ctx, "cpl", &(core->cpl));
     v3_chkpt_save(ctx, "vmcb_data", PAGE_SIZE, core->vmm_data);
 
     return 0;
 }
 
-int v3_svm_load_core(struct guest_info * core, void * chkpt_ctx){
-    struct cr0_32 * shadow_cr0;
-    vmcb_saved_state_t * guest_state; 
-    vmcb_ctrl_t * guest_ctrl;
-
-
+int v3_svm_load_core(struct guest_info * core, void * ctx){
+    
+    v3_chkpt_load_8(ctx, "cpl", &(core->cpl));
 
-    if (v3_chkpt_load(chkpt_ctx, "vmcb_data", PAGE_SIZE, core->vmm_data) == -1){
+    if (v3_chkpt_load(ctx, "vmcb_data", PAGE_SIZE, core->vmm_data) == -1) {
        return -1;
     }
 
-    guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t *)(core->vmm_data));
-    guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t *)(core->vmm_data));
-
-       
-    core->rip = guest_state->rip;
-    core->vm_regs.rsp = guest_state->rsp;
-    core->vm_regs.rax = guest_state->rax;
-
-    core->cpl = guest_state->cpl;
-
-    core->ctrl_regs.cr0 = guest_state->cr0;
-    core->ctrl_regs.cr2 = guest_state->cr2;
-    core->ctrl_regs.cr4 = guest_state->cr4;
-    core->dbg_regs.dr6 = guest_state->dr6;
-    core->dbg_regs.dr7 = guest_state->dr7;
-    core->ctrl_regs.cr8 = guest_ctrl->guest_ctrl.V_TPR;
-    core->ctrl_regs.rflags = guest_state->rflags;
-    core->ctrl_regs.efer = guest_state->efer;
-
-               
-    shadow_cr0 = (struct cr0_32 *)&(core->ctrl_regs.cr0);
-
-
-    if (core->shdw_pg_mode == SHADOW_PAGING) {
-       if (v3_get_vm_mem_mode(core) == VIRTUAL_MEM) {
-           if (v3_activate_shadow_pt(core) == -1) {
-               PrintError("Failed to activate shadow page tables\n");
-               return -1;
-           }
-       } else {
-           if (v3_activate_passthrough_pt(core) == -1) {
-               PrintError("Failed to activate passthrough page tables\n");
-               return -1;
-           }
-       }
-    }
-
-
-    v3_get_vmcb_segments((vmcb_t *)(core->vmm_data), &(core->segments));
     return 0;
 }
 #endif
index 7bd275f..72f980c 100644 (file)
@@ -321,6 +321,14 @@ void v3_print_guest_state(struct guest_info * info) {
 
     V3_Print("NumExits: %u\n", (uint32_t)info->num_exits);
 
+    V3_Print("IRQ STATE: started=%d, pending=%d\n", 
+            info->intr_core_state.irq_started, 
+            info->intr_core_state.irq_pending);
+    V3_Print("EXCP STATE: err_code_valid=%d, err_code=%x\n", 
+            info->excp_state.excp_error_code_valid, 
+            info->excp_state.excp_error_code);
+
+
     v3_print_segments(&(info->segments));
     v3_print_ctrl_regs(info);
 
index 2d36a3f..1de8e6a 100644 (file)
@@ -277,8 +277,12 @@ int v3_vmx_restore_vmcs(struct guest_info * info) {
 int v3_update_vmcs_host_state(struct guest_info * info) {
     int vmx_ret = 0;
     addr_t tmp;
-    struct vmx_data * arch_data = (struct vmx_data *)(info->vmm_data);
     struct v3_msr tmp_msr;
+    addr_t gdtr_base;
+    struct {
+        uint16_t selector;
+        addr_t   base;
+    } __attribute__((packed)) tmp_seg;
 
 #ifdef __V3_64BIT__
     __asm__ __volatile__ ( "movq    %%cr0, %0; "               
@@ -322,12 +326,48 @@ int v3_update_vmcs_host_state(struct guest_info * info) {
     vmx_ret |= check_vmcs_write(VMCS_HOST_CR4, tmp);
 
 
+    __asm__ __volatile__(
+                        "sgdt (%0);"
+                        :
+                        : "q"(&tmp_seg)
+                        : "memory"
+                        );
+    gdtr_base = tmp_seg.base;
+    vmx_ret |= check_vmcs_write(VMCS_HOST_GDTR_BASE, tmp_seg.base);
+
+    __asm__ __volatile__(
+                        "sidt (%0);"
+                        :
+                        : "q"(&tmp_seg)
+                        : "memory"
+                        );
+    vmx_ret |= check_vmcs_write(VMCS_HOST_IDTR_BASE, tmp_seg.base);
+
+    __asm__ __volatile__(
+                        "str (%0);"
+                        :
+                        : "q"(&tmp_seg)
+                        : "memory"
+                        );
+    vmx_ret |= check_vmcs_write(VMCS_HOST_TR_SELECTOR, tmp_seg.selector);
+
+    /* The GDTR *index* is bits 3-15 of the selector. */
+    {
+       struct tss_descriptor * desc = NULL;
+       desc = (struct tss_descriptor *)(gdtr_base + (8 * (tmp_seg.selector >> 3)));
+
+       tmp_seg.base = ((desc->base1) |
+                       (desc->base2 << 16) |
+                       (desc->base3 << 24) |
+#ifdef __V3_64BIT__
+                       ((uint64_t)desc->base4 << 32)
+#else
+                       (0)
+#endif
+                       );
 
-    vmx_ret |= check_vmcs_write(VMCS_HOST_GDTR_BASE, arch_data->host_state.gdtr.base);
-    vmx_ret |= check_vmcs_write(VMCS_HOST_IDTR_BASE, arch_data->host_state.idtr.base);
-    vmx_ret |= check_vmcs_write(VMCS_HOST_TR_BASE, arch_data->host_state.tr.base);
-
-
+       vmx_ret |= check_vmcs_write(VMCS_HOST_TR_BASE, tmp_seg.base);
+    }
 
 
 #ifdef __V3_64BIT__
@@ -408,8 +448,6 @@ int v3_update_vmcs_host_state(struct guest_info * info) {
 #endif
     vmx_ret |= check_vmcs_write(VMCS_HOST_GS_SELECTOR, tmp);
 
-    vmx_ret |= check_vmcs_write(VMCS_HOST_TR_SELECTOR, arch_data->host_state.tr.selector);
-
 
 #define SYSENTER_CS_MSR 0x00000174
 #define SYSENTER_ESP_MSR 0x00000175
index 87746ef..341996a 100644 (file)
@@ -414,13 +414,9 @@ int v3_move_vm_core(struct v3_vm_info * vm, int vcore_id, int target_cpu) {
        */
        core->pcpu_id = target_cpu;
 
-       V3_Print("core now at %d\n", core->pcpu_id);
-       
+       V3_Print("core now at %d\n", core->pcpu_id);    
     }
 
-
-
-
     v3_lower_barrier(vm);
 
     return 0;
index f33f64e..3258779 100644 (file)
@@ -26,6 +26,7 @@
 #include <palacios/vmx.h>
 #include <palacios/vmm_checkpoint.h>
 #include <palacios/vmm_hashtable.h>
+#include <palacios/vmm_direct_paging.h>
 
 #include <palacios/vmm_dev_mgr.h>
 
@@ -310,6 +311,8 @@ static int load_core(struct guest_info * info, struct v3_chkpt * chkpt) {
 
     ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name);
 
+    v3_chkpt_load_64(ctx, "RIP", &(info->rip));
+
     V3_CHKPT_STD_LOAD(ctx, info->vm_regs);
 
     V3_CHKPT_STD_LOAD(ctx, info->ctrl_regs.cr0);
@@ -331,6 +334,20 @@ static int load_core(struct guest_info * info, struct v3_chkpt * chkpt) {
     info->cpu_mode = v3_get_vm_cpu_mode(info);
     info->mem_mode = v3_get_vm_mem_mode(info);
 
+    if (info->shdw_pg_mode == SHADOW_PAGING) {
+       if (v3_get_vm_mem_mode(info) == VIRTUAL_MEM) {
+           if (v3_activate_shadow_pt(info) == -1) {
+               PrintError("Failed to activate shadow page tables\n");
+               return -1;
+           }
+       } else {
+           if (v3_activate_passthrough_pt(info) == -1) {
+               PrintError("Failed to activate passthrough page tables\n");
+               return -1;
+           }
+       }
+    }
+
 
     switch (cpu_type) {
        case V3_SVM_CPU:
@@ -371,6 +388,8 @@ static int load_core(struct guest_info * info, struct v3_chkpt * chkpt) {
            return -1;
     }
 
+    v3_print_guest_state(info);
+
     return 0;
 }
 
@@ -382,11 +401,15 @@ static int save_core(struct guest_info * info, struct v3_chkpt * chkpt) {
 
     memset(key_name, 0, 16);
 
+    v3_print_guest_state(info);
+
 
     snprintf(key_name, 16, "guest_info%d", info->vcpu_id);
 
     ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name);
 
+    v3_chkpt_save_64(ctx, "RIP", &(info->rip));
+
     V3_CHKPT_STD_SAVE(ctx, info->vm_regs);
 
     V3_CHKPT_STD_SAVE(ctx, info->ctrl_regs.cr0);
index de6209b..d08b227 100644 (file)
@@ -153,7 +153,8 @@ int v3_save_vm_devices(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
 
        if (dev->ops->save) {
            struct v3_chkpt_ctx * dev_ctx = NULL;
-
+           
+           V3_Print("Saving state for device (%s)\n", dev->name);
            
            dev_ctx = v3_chkpt_open_ctx(chkpt, dev_mgr_ctx, dev->name);
 
@@ -436,6 +437,13 @@ struct vm_device * v3_add_device(struct v3_vm_info * vm,
     struct vmm_dev_mgr * mgr = &(vm->dev_mgr);
     struct vm_device * dev = NULL;
 
+
+    // Check if we already registered a device of the same name
+    if (v3_htable_search(mgr->dev_table, (addr_t)name) != (addr_t)NULL) {
+       PrintError("Device with name (%s) already registered with VM\n", name); 
+       return NULL;
+    }
+
     dev = (struct vm_device *)V3_Malloc(sizeof(struct vm_device));
 
     if (dev == NULL) {
index 1b286ae..bdfc8c0 100644 (file)
@@ -136,53 +136,6 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state)
     /******* Setup Host State **********/
 
     /* Cache GDTR, IDTR, and TR in host struct */
-    addr_t gdtr_base;
-    struct {
-        uint16_t selector;
-        addr_t   base;
-    } __attribute__((packed)) tmp_seg;
-    
-
-    __asm__ __volatile__(
-                        "sgdt (%0);"
-                        :
-                        : "q"(&tmp_seg)
-                        : "memory"
-                        );
-    gdtr_base = tmp_seg.base;
-    vmx_state->host_state.gdtr.base = gdtr_base;
-
-    __asm__ __volatile__(
-                        "sidt (%0);"
-                        :
-                        : "q"(&tmp_seg)
-                        : "memory"
-                        );
-    vmx_state->host_state.idtr.base = tmp_seg.base;
-
-    __asm__ __volatile__(
-                        "str (%0);"
-                        :
-                        : "q"(&tmp_seg)
-                        : "memory"
-                        );
-    vmx_state->host_state.tr.selector = tmp_seg.selector;
-
-    /* The GDTR *index* is bits 3-15 of the selector. */
-    struct tss_descriptor * desc = NULL;
-    desc = (struct tss_descriptor *)(gdtr_base + (8 * (tmp_seg.selector >> 3)));
-
-    tmp_seg.base = ((desc->base1) |
-                   (desc->base2 << 16) |
-                   (desc->base3 << 24) |
-#ifdef __V3_64BIT__
-                   ((uint64_t)desc->base4 << 32)
-#else 
-                   (0)
-#endif
-                   );
-
-    vmx_state->host_state.tr.base = tmp_seg.base;
 
 
     /********** Setup VMX Control Fields ***********/
@@ -213,10 +166,6 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state)
 
 
 
-    
-
-
-
 #ifdef __V3_64BIT__
     // Ensure host runs in 64-bit mode at each VM EXIT
     vmx_state->exit_ctrls.host_64_on = 1;