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 device checkpoint hooks
Madhav Suresh [Fri, 16 Sep 2011 22:59:58 +0000 (18:59 -0400)]
palacios/include/palacios/vmm_checkpoint.h
palacios/include/palacios/vmm_dev_mgr.h
palacios/src/devices/8254.c
palacios/src/devices/8259a.c
palacios/src/devices/apic.c
palacios/src/devices/cga.c
palacios/src/devices/io_apic.c
palacios/src/devices/keyboard.c
palacios/src/devices/os_debug.c
palacios/src/palacios/vmm_checkpoint.c
palacios/src/palacios/vmm_dev_mgr.c

index d62d98f..9bb5e81 100644 (file)
@@ -23,7 +23,7 @@
 #ifdef __V3VEE__
 
 #include <palacios/vmm.h>
-#include <palacios/vm_guest.h>
+
 
 struct v3_chkpt;
 
@@ -34,7 +34,9 @@ struct v3_chkpt_ctx {
     void * store_ctx;
 };
 
-
+/* Temporary */
+#define  V3_CHKPT_STD_SAVE(ctx,x) v3_chkpt_save(ctx,#x,sizeof(x),&(x))
+#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);
index 1f10874..156b560 100644 (file)
 #include <palacios/vmm_config.h>
 #include <palacios/vmm_ethernet.h>
 
+#ifdef V3_CONFIG_CHECKPOINT
+#include <palacios/vmm_checkpoint.h>
+#endif
+
 struct v3_vm_info;
 
 struct v3_device_ops;
@@ -92,9 +96,10 @@ int v3_deinit_dev_mgr(struct v3_vm_info * vm);
 
 int v3_free_vm_devices(struct v3_vm_info * vm);
 
-
-
-
+#ifdef V3_CONFIG_CHECKPOINT
+int v3_save_vm_devices(struct v3_vm_info * vm, struct v3_chkpt * chkpt);
+int v3_load_vm_devices(struct v3_vm_info * vm, struct v3_chkpt * chkpt);
+#endif
 
 
 
@@ -102,16 +107,12 @@ int V3_init_devices();
 int V3_deinit_devices();
 
 
-#ifdef V3_CONFIG_KEYED_STREAMS
-#include <interfaces/vmm_keyed_stream.h>
-#endif 
-
 struct v3_device_ops {
     int (*free)(void * private_data);
 
-#ifdef V3_CONFIG_KEYED_STREAMS
-    int (*checkpoint)(struct vm_device *dev, v3_keyed_stream_t stream);
-    int (*restore)(struct vm_device *dev, v3_keyed_stream_t stream);
+#ifdef V3_CONFIG_CHECKPOINT
+    int (*save)(struct v3_chkpt_ctx * ctx, void * private_data);
+    int (*load)(struct v3_chkpt_ctx * ctx, void * privata_data);
 #endif
 };
 
index 9a9ee99..1a44399 100644 (file)
@@ -682,65 +682,39 @@ static int pit_free(void * private_data) {
     return 0;
 }
 
-#ifdef V3_CONFIG_KEYED_STREAMS
-static int pit_checkpoint(struct vm_device *dev, v3_keyed_stream_t stream)
-{
-    struct pit *p = (struct pit *) (dev->private_data);
-
-    v3_keyed_stream_key_t ks;
-
-    ks = v3_keyed_stream_open_key(stream,dev->name);
-
-    if (!ks) { 
-       return -1;
-    }
-
-    STD_SAVE(stream,ks,p->pit_counter);
-    STD_SAVE(stream,ks,p->pit_reload);
-    STD_SAVE(stream,ks,p->ch_0);
-    STD_SAVE(stream,ks,p->ch_1);
-    STD_SAVE(stream,ks,p->ch_2);
-    STD_SAVE(stream,ks,p->speaker);
-
-    v3_keyed_stream_close_key(stream,ks);
+#ifdef V3_CONFIG_CHECKPOINT
+static int pit_save(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct pit * pit_state = (struct pit *)private_data; 
+
+    V3_CHKPT_STD_SAVE(ctx, pit_state->pit_counter);
+    V3_CHKPT_STD_SAVE(ctx, pit_state->pit_reload);
+    V3_CHKPT_STD_SAVE(ctx, pit_state->ch_0);
+    V3_CHKPT_STD_SAVE(ctx, pit_state->ch_1);
+    V3_CHKPT_STD_SAVE(ctx, pit_state->ch_2);
+    V3_CHKPT_STD_SAVE(ctx, pit_state->speaker);
     
     return 0;
-
-
 }
 
-static int pit_restore(struct vm_device *dev, v3_keyed_stream_t stream)
-{
-    struct pit *p = (struct pit *) (dev->private_data);
+static int pit_load(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct pit * pit_state = (struct pit *)private_data;
 
-    v3_keyed_stream_key_t ks;
+    V3_CHKPT_STD_LOAD(ctx, pit_state->pit_counter);
+    V3_CHKPT_STD_LOAD(ctx, pit_state->pit_reload);
+    V3_CHKPT_STD_LOAD(ctx, pit_state->ch_0);
+    V3_CHKPT_STD_LOAD(ctx, pit_state->ch_1);
+    V3_CHKPT_STD_LOAD(ctx, pit_state->ch_2);
+    V3_CHKPT_STD_LOAD(ctx, pit_state->speaker);
 
-    ks = v3_keyed_stream_open_key(stream,dev->name);
-
-    if (!ks) { 
-       return -1;
-    }
-
-    STD_LOAD(stream,ks,p->pit_counter);
-    STD_LOAD(stream,ks,p->pit_reload);
-    STD_LOAD(stream,ks,p->ch_0);
-    STD_LOAD(stream,ks,p->ch_1);
-    STD_LOAD(stream,ks,p->ch_2);
-    STD_LOAD(stream,ks,p->speaker);
-
-    v3_keyed_stream_close_key(stream,ks);
-    
     return 0;
-
-
 }
 #endif
 
 static struct v3_device_ops dev_ops = {
     .free = (int (*)(void *))pit_free,
-#ifdef V3_CONFIG_KEYED_STREAMS
-    .checkpoint = pit_checkpoint,
-    .restore = pit_restore,
+#ifdef V3_CONFIG_CHECKPOINT
+    .save = pit_save,
+    .load = pit_load,
 #endif
 };
 
index c24402d..5103791 100644 (file)
@@ -737,10 +737,96 @@ static int pic_free(struct pic_internal * state) {
     return 0;
 }
 
+#ifdef V3_CONFIG_CHECKPOINT
+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_STD_SAVE(ctx, pic->master_isr);
+    V3_CHKPT_STD_SAVE(ctx, 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_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_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_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_STD_SAVE(ctx, pic->master_state);
+    V3_CHKPT_STD_SAVE(ctx, pic->slave_state);
+
+    
+    return 0;
+
+}
+
+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_STD_LOAD(ctx, pic->master_isr);
+    V3_CHKPT_STD_LOAD(ctx, 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_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_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_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_STD_LOAD(ctx, pic->master_state);
+    V3_CHKPT_STD_LOAD(ctx, pic->slave_state);
+
+    return 0;
+}
+
+#endif
+
 
 static struct v3_device_ops dev_ops = {
     .free = (int (*)(void *))pic_free,
-
+#ifdef V3_CONFIG_CHECKPOINT
+    .save = pic_save,
+    .load = pic_load
+#endif
 };
 
 
index 508f221..6b21f81 100644 (file)
@@ -1714,9 +1714,109 @@ static int apic_free(struct apic_dev_state * apic_dev) {
     return 0;
 }
 
+#ifdef V3_CONFIG_CHECKPOINT
+static int apic_save(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct apic_dev_state * apic_state = (struct apic_dev_state *)private_data;
+    int i = 0;
+
+    V3_CHKPT_STD_SAVE(ctx, apic_state->num_apics);
+
+    //V3_CHKPT_STD_SAVE(ctx,apic_state->state_lock);
+    for (i = 0; i < apic_state->num_apics; i++) {
+
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].base_addr);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].base_addr_msr);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].lapic_id);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].apic_ver);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].ext_apic_ctrl);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].local_vec_tbl);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].tmr_vec_tbl);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].tmr_div_cfg);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].lint0_vec_tbl);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].lint1_vec_tbl);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].perf_ctr_loc_vec_tbl);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].therm_loc_vec_tbl);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].err_vec_tbl);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].err_status);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].spurious_int);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].int_cmd);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].log_dst);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].dst_fmt);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].arb_prio);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].task_prio);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].proc_prio);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].ext_apic_feature);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].spec_eoi);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].tmr_cur_cnt);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].tmr_init_cnt);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].ext_intr_vec_tbl);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].rem_rd_data);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].ipi_state);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].int_req_reg);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].int_svc_reg);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].int_en_reg);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].trig_mode_reg);
+       V3_CHKPT_STD_SAVE(ctx, apic_state->apics[i].eoi);
+
+    }
+
+    return 0;
+}
+
+static int apic_load(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct apic_dev_state *apic_state = (struct apic_dev_state *)private_data;
+    int i = 0;
+
+    V3_CHKPT_STD_LOAD(ctx,apic_state->num_apics);
+
+    for (i = 0; i < apic_state->num_apics; i++) {
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].base_addr);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].base_addr_msr);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].lapic_id);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].apic_ver);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].ext_apic_ctrl);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].local_vec_tbl);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].tmr_vec_tbl);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].tmr_div_cfg);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].lint0_vec_tbl);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].lint1_vec_tbl);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].perf_ctr_loc_vec_tbl);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].therm_loc_vec_tbl);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].err_vec_tbl);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].err_status);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].spurious_int);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].int_cmd);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].log_dst);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].dst_fmt);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].arb_prio);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].task_prio);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].proc_prio);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].ext_apic_feature);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].spec_eoi);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].tmr_cur_cnt);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].tmr_init_cnt);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].ext_intr_vec_tbl);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].rem_rd_data);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].ipi_state);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].int_req_reg);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].int_svc_reg);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].int_en_reg);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].trig_mode_reg);
+       V3_CHKPT_STD_LOAD(ctx, apic_state->apics[i].eoi);
+    }
+
+
+    return 0;
+}
+
+#endif
 
 static struct v3_device_ops dev_ops = {
     .free = (int (*)(void *))apic_free,
+#ifdef V3_CONFIG_CHECKPOINT
+    .save = apic_save,
+    .load = apic_load
+#endif
 };
 
 
index 7997818..0081609 100644 (file)
@@ -1097,7 +1097,7 @@ int v3_cons_get_fb(struct vm_device * frontend_dev, uint8_t * dst, uint_t offset
     }
 }
 
-static int free_cga(struct video_internal * video_state) {
+static int cga_free(struct video_internal * video_state) {
 
     if (video_state->framebuf_pa) {
        PrintError("Freeing framebuffer PA %p\n", (void *)(video_state->framebuf_pa));
@@ -1112,8 +1112,89 @@ static int free_cga(struct video_internal * video_state) {
 }
 
 
+#ifdef V3_CONFIG_CHECKPOINT
+static int cga_save(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct video_internal * cga = (struct video_internal *)private_data;
+
+    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]); 
+    V3_CHKPT_STD_SAVE(ctx, cga->crtc_index_reg);               
+    V3_CHKPT_STD_SAVE(ctx, cga->crtc_data_regs[CRTC_REG_COUNT]);
+    V3_CHKPT_STD_SAVE(ctx, cga->graphc_index_reg);             
+    V3_CHKPT_STD_SAVE(ctx, cga->graphc_data_regs[GRAPHC_REG_COUNT]);
+    V3_CHKPT_STD_SAVE(ctx, cga->attrc_index_flipflop);
+    V3_CHKPT_STD_SAVE(ctx, cga->attrc_index_reg);      
+    V3_CHKPT_STD_SAVE(ctx, cga->attrc_data_regs[ATTRC_REG_COUNT]);     
+    V3_CHKPT_STD_SAVE(ctx, cga->dac_indexr_reg);       
+    V3_CHKPT_STD_SAVE(ctx, cga->dac_indexr_color);
+    V3_CHKPT_STD_SAVE(ctx, cga->dac_indexw_reg);               
+    V3_CHKPT_STD_SAVE(ctx, cga->dac_indexw_color);
+    V3_CHKPT_STD_SAVE(ctx, cga->dac_data_regs[DAC_REG_COUNT]);
+
+    V3_CHKPT_STD_SAVE(ctx, cga->activefb_addr);
+    V3_CHKPT_STD_SAVE(ctx, cga->activefb_len);
+    V3_CHKPT_STD_SAVE(ctx, cga->iorange);
+    V3_CHKPT_STD_SAVE(ctx, cga->vres);
+    V3_CHKPT_STD_SAVE(ctx, cga->hres);
+    V3_CHKPT_STD_SAVE(ctx, cga->vchars);
+    V3_CHKPT_STD_SAVE(ctx, cga->hchars);
+    V3_CHKPT_STD_SAVE(ctx, cga->graphmode);
+
+    V3_CHKPT_STD_SAVE(ctx, cga->dirty);
+    V3_CHKPT_STD_SAVE(ctx, cga->reschanged);
+
+    V3_CHKPT_STD_SAVE(ctx, cga->passthrough);
+
+    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_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]); 
+    V3_CHKPT_STD_LOAD(ctx, cga->crtc_index_reg);               
+    V3_CHKPT_STD_LOAD(ctx, cga->crtc_data_regs[CRTC_REG_COUNT]);
+    V3_CHKPT_STD_LOAD(ctx, cga->graphc_index_reg);             
+    V3_CHKPT_STD_LOAD(ctx, cga->graphc_data_regs[GRAPHC_REG_COUNT]);
+    V3_CHKPT_STD_LOAD(ctx, cga->attrc_index_flipflop);
+    V3_CHKPT_STD_LOAD(ctx, cga->attrc_index_reg);      
+    V3_CHKPT_STD_LOAD(ctx, cga->attrc_data_regs[ATTRC_REG_COUNT]);     
+    V3_CHKPT_STD_LOAD(ctx, cga->dac_indexr_reg);       
+    V3_CHKPT_STD_LOAD(ctx, cga->dac_indexr_color);
+    V3_CHKPT_STD_LOAD(ctx, cga->dac_indexw_reg);               
+    V3_CHKPT_STD_LOAD(ctx, cga->dac_indexw_color);
+    V3_CHKPT_STD_LOAD(ctx, cga->dac_data_regs[DAC_REG_COUNT]);
+
+    V3_CHKPT_STD_LOAD(ctx, cga->activefb_addr);
+    V3_CHKPT_STD_LOAD(ctx, cga->activefb_len);
+    V3_CHKPT_STD_LOAD(ctx, cga->iorange);
+    V3_CHKPT_STD_LOAD(ctx, cga->vres);
+    V3_CHKPT_STD_LOAD(ctx, cga->hres);
+    V3_CHKPT_STD_LOAD(ctx, cga->vchars);
+    V3_CHKPT_STD_LOAD(ctx, cga->hchars);
+    V3_CHKPT_STD_LOAD(ctx, cga->graphmode);
+
+    V3_CHKPT_STD_LOAD(ctx, cga->dirty);
+    V3_CHKPT_STD_LOAD(ctx, cga->reschanged);
+
+    V3_CHKPT_STD_LOAD(ctx, cga->passthrough);
+
+    return 0;
+}
+
+#endif
+
+
 static struct v3_device_ops dev_ops = {
-    .free = (int (*)(void *))free_cga,
+    .free = (int (*)(void *))cga_free,
+#ifdef V3_CONFIG_CHECKPOINT
+    .save = cga_save, 
+    .load = cga_load
+#endif
+
 };
 
 static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
index 3579fde..0817e9b 100644 (file)
@@ -325,10 +325,42 @@ static int io_apic_free(struct io_apic_state * ioapic) {
     return 0;
 }
 
+#ifdef V3_CONFIG_CHECKPOINT
+static int io_apic_save(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct io_apic_state * io_apic = (struct io_apic_state *)private_data;
+
+    V3_CHKPT_STD_SAVE(ctx, io_apic->base_addr);
+    V3_CHKPT_STD_SAVE(ctx, io_apic->index_reg);
+    V3_CHKPT_STD_SAVE(ctx, io_apic->ioapic_id);
+    V3_CHKPT_STD_SAVE(ctx, io_apic->ioapic_ver);
+    V3_CHKPT_STD_SAVE(ctx, io_apic->ioapic_arb_id);
+    V3_CHKPT_STD_SAVE(ctx, io_apic->redir_tbl);
+
+    return 0;
+}
+
+static int io_apic_load(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct io_apic_state * io_apic = (struct io_apic_state *)private_data;
+
+    V3_CHKPT_STD_LOAD(ctx, io_apic->base_addr);
+    V3_CHKPT_STD_LOAD(ctx, io_apic->index_reg);
+    V3_CHKPT_STD_LOAD(ctx, io_apic->ioapic_id);
+    V3_CHKPT_STD_LOAD(ctx, io_apic->ioapic_ver);
+    V3_CHKPT_STD_LOAD(ctx, io_apic->ioapic_arb_id);
+    V3_CHKPT_STD_LOAD(ctx, io_apic->redir_tbl);
+
+    return 0;
+}
+#endif
+
+
 
 static struct v3_device_ops dev_ops = {
     .free = (int (*)(void *))io_apic_free,
-
+#ifdef V3_CONFIG_CHECKPOINT
+    .save = io_apic_save, 
+    .load = io_apic_load
+#endif
 };
 
 
index e974503..6d39878 100644 (file)
@@ -1051,9 +1051,27 @@ 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) {
+    return 0;
+}
+
+
+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);
+    return 0;
+}
+
+#endif
+
+
 static struct v3_device_ops dev_ops = { 
     .free = (int (*)(void *))keyboard_free,
-
+#ifdef V3_CONFIG_CHECKPOINT
+    .save = keyboard_save,
+    .load = keyboard_load
+#endif
 };
 
 
index 97cdabc..f821415 100644 (file)
@@ -89,11 +89,36 @@ static int debug_free(struct debug_state * state) {
     return 0;
 };
 
+#ifdef V3_CONFIG_CHECKPOINT
+static int debug_save(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct debug_state * dbg = (struct debug_state *)private_data;
+    
+    V3_CHKPT_STD_SAVE(ctx, dbg->debug_buf);
+    V3_CHKPT_STD_SAVE(ctx, dbg->debug_offset);
+    
+    return 0;
+}
+
+
+static int debug_load(struct v3_chkpt_ctx * ctx, void * private_data) {
+    struct debug_state * dbg = (struct debug_state *)private_data;
+    
+    V3_CHKPT_STD_LOAD(ctx, dbg->debug_buf);
+    V3_CHKPT_STD_LOAD(ctx, dbg->debug_offset);
+    
+    return 0;
+}
+
+#endif
 
 
 
 static struct v3_device_ops dev_ops = {
     .free = (int (*)(void *))debug_free,
+#ifdef V3_CONFIG_CHECKPOINT
+    .save = debug_save,
+    .load = debug_load
+#endif 
 };
 
 
index 8f5e5ac..fbe922d 100644 (file)
@@ -186,9 +186,7 @@ int v3_chkpt_close_ctx(struct v3_chkpt_ctx * ctx) {
 }
 
 
-/* Temporary */
-#define  V3_CHKPT_STD_SAVE(ctx,x) v3_chkpt_save(ctx,#x,sizeof(x),&(x))
-#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) {
@@ -490,12 +488,11 @@ int v3_chkpt_save_vm(struct v3_vm_info * vm, char * store, char * url) {
     }
     
     for (i = 0; i < vm->num_cores; i++){
-       
        if ((ret = save_core(&(vm->cores[i]), chkpt)) == -1) {
            PrintError("chkpt of core %d failed\n", i);
            goto out;
        }
-    }  
+    }
     
  out:
     
index a6f71e5..e6fad69 100644 (file)
 #include <palacios/vmm.h>
 #include <palacios/vmm_decoder.h>
 
+#ifdef V3_CONFIG_CHECKPOINT
+#include <palacios/vmm_checkpoint.h>
+#endif
+
 
 #ifndef V3_CONFIG_DEBUG_DEV_MGR
 #undef PrintDebug
@@ -126,6 +130,72 @@ int v3_free_vm_devices(struct v3_vm_info * vm) {
     return 0;
 }
 
+#ifdef V3_CONFIG_CHECKPOINT
+
+int v3_save_vm_devices(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
+    struct vmm_dev_mgr * mgr = &(vm->dev_mgr);
+    struct vm_device * dev;
+    struct v3_chkpt_ctx * dev_mgr_ctx = NULL;
+
+    uint32_t num_saved_devs = 0;
+    uint32_t table_len = mgr->num_devs * 32;
+    char * name_table = NULL;
+    uint32_t tbl_offset = 0;
+    
+    name_table = V3_Malloc(table_len);
+
+    memset(name_table, 0, table_len);
+    
+
+    dev_mgr_ctx = v3_chkpt_open_ctx(chkpt, NULL, "devices");
+
+    list_for_each_entry(dev, &(mgr->dev_list), dev_link) {
+
+       if (dev->ops->save) {
+           struct v3_chkpt_ctx * dev_ctx = NULL;
+
+           
+           dev_ctx = v3_chkpt_open_ctx(chkpt, dev_mgr_ctx, dev->name);
+
+           dev->ops->save(dev_ctx, dev->private_data);
+
+           v3_chkpt_close_ctx(dev_ctx);
+
+           // Error checking?? 
+
+           strncpy(name_table + tbl_offset, dev->name, 32);
+           tbl_offset += 32;
+           num_saved_devs++;
+       } else {
+           PrintError("Error: %s save() not implemented\n",  dev->name);
+       }
+    }
+
+    
+    // Specify which devices were saved
+    v3_chkpt_save(dev_mgr_ctx, "num_devs", 4, &num_saved_devs); 
+    v3_chkpt_save(dev_mgr_ctx, "names", table_len, name_table);
+    V3_Free(name_table);
+
+    v3_chkpt_close_ctx(dev_mgr_ctx);
+    
+    return 0;
+}
+
+
+int v3_load_vm_devices(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
+
+    PrintError("TODO... \n");
+
+    // Read devices from checkpoint data
+    // selectively load them
+
+    return 0;
+}
+
+
+#endif
+
 static int free_frontends(struct v3_vm_info * vm, struct vmm_dev_mgr * mgr);
 
 int v3_deinit_dev_mgr(struct v3_vm_info * vm) {