#ifdef __V3VEE__
#include <palacios/vmm.h>
-#include <palacios/vm_guest.h>
+
struct v3_chkpt;
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);
#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;
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
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
};
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
};
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
};
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
};
}
}
-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));
}
+#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) {
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
};
}
+#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
};
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
};
}
-/* 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) {
}
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:
#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
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) {