From: Madhav Suresh Date: Fri, 16 Sep 2011 22:59:58 +0000 (-0400) Subject: added device checkpoint hooks X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=5d1bbcc86de011e3f0d115b6f10fd8645cdf855e added device checkpoint hooks --- diff --git a/palacios/include/palacios/vmm_checkpoint.h b/palacios/include/palacios/vmm_checkpoint.h index d62d98f..9bb5e81 100644 --- a/palacios/include/palacios/vmm_checkpoint.h +++ b/palacios/include/palacios/vmm_checkpoint.h @@ -23,7 +23,7 @@ #ifdef __V3VEE__ #include -#include + 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); diff --git a/palacios/include/palacios/vmm_dev_mgr.h b/palacios/include/palacios/vmm_dev_mgr.h index 1f10874..156b560 100644 --- a/palacios/include/palacios/vmm_dev_mgr.h +++ b/palacios/include/palacios/vmm_dev_mgr.h @@ -30,6 +30,10 @@ #include #include +#ifdef V3_CONFIG_CHECKPOINT +#include +#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 -#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 }; diff --git a/palacios/src/devices/8254.c b/palacios/src/devices/8254.c index 9a9ee99..1a44399 100644 --- a/palacios/src/devices/8254.c +++ b/palacios/src/devices/8254.c @@ -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 }; diff --git a/palacios/src/devices/8259a.c b/palacios/src/devices/8259a.c index c24402d..5103791 100644 --- a/palacios/src/devices/8259a.c +++ b/palacios/src/devices/8259a.c @@ -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 }; diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index 508f221..6b21f81 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -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 }; diff --git a/palacios/src/devices/cga.c b/palacios/src/devices/cga.c index 7997818..0081609 100644 --- a/palacios/src/devices/cga.c +++ b/palacios/src/devices/cga.c @@ -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) { diff --git a/palacios/src/devices/io_apic.c b/palacios/src/devices/io_apic.c index 3579fde..0817e9b 100644 --- a/palacios/src/devices/io_apic.c +++ b/palacios/src/devices/io_apic.c @@ -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 }; diff --git a/palacios/src/devices/keyboard.c b/palacios/src/devices/keyboard.c index e974503..6d39878 100644 --- a/palacios/src/devices/keyboard.c +++ b/palacios/src/devices/keyboard.c @@ -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 }; diff --git a/palacios/src/devices/os_debug.c b/palacios/src/devices/os_debug.c index 97cdabc..f821415 100644 --- a/palacios/src/devices/os_debug.c +++ b/palacios/src/devices/os_debug.c @@ -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 }; diff --git a/palacios/src/palacios/vmm_checkpoint.c b/palacios/src/palacios/vmm_checkpoint.c index 8f5e5ac..fbe922d 100644 --- a/palacios/src/palacios/vmm_checkpoint.c +++ b/palacios/src/palacios/vmm_checkpoint.c @@ -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: diff --git a/palacios/src/palacios/vmm_dev_mgr.c b/palacios/src/palacios/vmm_dev_mgr.c index a6f71e5..e6fad69 100644 --- a/palacios/src/palacios/vmm_dev_mgr.c +++ b/palacios/src/palacios/vmm_dev_mgr.c @@ -22,6 +22,10 @@ #include #include +#ifdef V3_CONFIG_CHECKPOINT +#include +#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) {