HVM save restore: device model support
PATCH 5/8 HVM save restore: device model support
[PATCH 5/8] HVM save restore: device model support
Signed-off-by Zhai Edwin <[email protected]>
qemu's save/restore including vga acceleration support
tools/ioemu/hw/cirrus_vga.c +52 -0
@@ -3010,11 +3010,44 @@ static CPUWriteMemoryFunc *cirrus_mmio_w cirrus_mmio_writel, }; +void cirrus_stop_acc (CirrusVGAState *s) +{ +if (s->map_addr){ +int error; + s->map_addr =0 ; + error =unset_vram_mapping (s->cirrus_lfb_addr, + s->cirrus_lfb_end); +fprintf (stderr,"cirrus_stop_acc:unset_vram_mapping.\n" ); + +munmap (s->vram_ptr,VGA_RAM_SIZE ); + } +} + +void cirrus_restart_acc (CirrusVGAState *s) +{ +if (s->cirrus_lfb_addr && s->cirrus_lfb_end) { +void *vram_pointer, *old_vram; +fprintf (stderr,"cirrus_vga_load:re-enable vga acc.lfb_addr=0x%lx, lfb_end=0x%lx.\n" , + s->cirrus_lfb_addr, s->cirrus_lfb_end); + vram_pointer =set_vram_mapping (s->cirrus_lfb_addr ,s->cirrus_lfb_end); +if (!vram_pointer){ +fprintf (stderr,"cirrus_vga_load:NULL vram_pointer\n" ); + }else { + old_vram =vga_update_vram ((VGAState *)s, vram_pointer, +VGA_RAM_SIZE ); +qemu_free (old_vram); + s->map_addr = s->cirrus_lfb_addr; + s->map_end = s->cirrus_lfb_end; + } + } +} +/* load/save state */ static void cirrus_vga_save (QEMUFile *f,void *opaque) {CirrusVGAState *s = opaque; +uint8_t vga_acc;qemu_put_be32s (f, &s->latch);qemu_put_8s (f, &s->sr_index);
@@ -3049,11 +3082,20 @@ static void cirrus_vga_save(QEMUFile *f,qemu_put_be32s (f, &s->hw_cursor_y);/* XXX: we do not save the bitblt state - we assume we do not save the state when the blitter is active */ + + vga_acc = (!!s->map_addr); +qemu_put_8s (f, &vga_acc); +qemu_put_be64s (f, (uint64_t *)&s->cirrus_lfb_addr); +qemu_put_be64s (f, (uint64_t *)&s->cirrus_lfb_end); +qemu_put_buffer (f, s->vram_ptr,VGA_RAM_SIZE ); +if (vga_acc) +cirrus_stop_acc (s); }static int cirrus_vga_load (QEMUFile *f,void *opaque,int version_id) {CirrusVGAState *s = opaque; +uint8_t vga_acc =0 ;if (version_id !=1 )return -EINVAL ;
@@ -3091,6 +3133,14 @@ static int cirrus_vga_load(QEMUFile *f,qemu_get_be32s (f, &s->hw_cursor_x);qemu_get_be32s (f, &s->hw_cursor_y); + +qemu_get_8s (f, &vga_acc); +qemu_get_be64s (f, (uint64_t *)&s->cirrus_lfb_addr); +qemu_get_be64s (f, (uint64_t *)&s->cirrus_lfb_end); +qemu_get_buffer (f, s->vram_ptr,VGA_RAM_SIZE ); +if (vga_acc){ +cirrus_restart_acc (s); + }/* force refresh */ s->graphic_mode =-1 ;
@@ -3297,6 +3347,8 @@ void pci_cirrus_vga_init(PCIBus *bus, Di ds, vga_ram_base, vga_ram_offset, vga_ram_size);cirrus_init_common (s, device_id,1 ); +register_savevm ("cirrus_vga_pci" ,0 ,1 , generic_pci_save, generic_pci_load, d); +/* setup memory space */ /* memory #0 LFB */ /* memory #1 memory-mapped I/O */
tools/ioemu/hw/ide.c +3 -0
@@ -2512,6 +2512,9 @@ void pci_piix3_ide_init(PCIBus *bus, Blo pic_set_irq_new, isa_pic, 15);ide_init_ioport (&d->ide_if[0 ],0x1f0 ,0x3f6 );ide_init_ioport (&d->ide_if[2 ],0x170 ,0x376 ); + +register_savevm ("ide_pci" ,0 ,1 , generic_pci_save, generic_pci_load, d); +#ifdef DMA_MULTI_THREAD dma_create_thread ();#endif //DMA_MULTI_THREAD
tools/ioemu/hw/pci.c +2 -0
@@ -63,6 +63,7 @@ void generic_pci_save(QEMUFile* f, voidqemu_put_buffer (f, s->config,256 ); } +void pci_update_mappings (PCIDevice *d);int generic_pci_load (QEMUFile * f,void *opaque,int version_id) {PCIDevice * s=(PCIDevice *)opaque;
@@ -71,6 +72,7 @@ int generic_pci_load(QEMUFile* f, void *return -EINVAL ;qemu_get_buffer (f, s->config,256 ); +pci_update_mappings (s);return 0 ; }
tools/ioemu/target-i386-dm/helper2.c +14 -1
@@ -546,6 +546,7 @@ int main_loop(void) {extern int vm_running;extern int shutdown_requested; +extern int suspend_requested;CPUState *env = cpu_single_env;int evtchn_fd =xc_evtchn_fd (xce_handle);
@@ -563,12 +564,24 @@ int main_loop(void)qemu_system_reset (); reset_requested =0 ; } +if (suspend_requested) { +fprintf (logfile,"device model received suspend signal!\n" ); +break ; + } }/* Wait up to 10 msec. */ main_loop_wait (10 ); } -destroy_hvm_domain (); +if (!suspend_requested) +destroy_hvm_domain (); +else { +char qemu_file[20 ]; +sprintf (qemu_file,"/tmp/xen.qemu-dm.%d" , domid); +if (qemu_savevm (qemu_file) <0 ) +fprintf (stderr,"qemu save fail.\n" ); + } +return 0 ; }
tools/ioemu/vl.c +34 -0
@@ -4441,6 +4441,11 @@ int qemu_loadvm(const char *filename)qemu_fseek (f, cur_pos + record_len,SEEK_SET ); }fclose (f); + +/* del tmp file */ +if (unlink (filename) ==-1 ) +fprintf (stderr,"delete tmp qemu state file failed.\n" ); + ret =0 ; the_end:if (saved_vm_running)
@@ -5027,6 +5032,7 @@ static QEMUResetEntry *first_reset_entrystatic QEMUResetEntry *first_reset_entry;int reset_requested;int shutdown_requested; +int suspend_requested;static int powerdown_requested;void qemu_register_reset (QEMUResetHandler *func,void *opaque)
@@ -5806,6 +5812,14 @@ int set_mm_mapping(int xc_handle, uint32 }return 0 ; +} + +void suspend (int sig) +{ +fprintf (logfile,"suspend sig handler called with requested=%d!\n" , suspend_requested); +if (sig !=SIGUSR1 ) +fprintf (logfile,"suspend signal dismatch, get sig=%d!\n" , sig); + suspend_requested =1 ; }#if defined(__i386__) || defined(__x86_64__)
@@ -6718,6 +6732,26 @@ int main(int argc, char **argv)vm_start (); } } + +/* register signal for the suspend request when save */ + { +struct sigaction act; +sigset_t set; + act.sa_handler = suspend; + act.sa_flags =SA_RESTART ; +sigemptyset (&act.sa_mask); + +sigaction (SIGUSR1 , &act,NULL ); + +/* control panel mask some signals when spawn qemu, need unmask here*/ +sigemptyset (&set); +sigaddset (&set,SIGUSR1 ); +sigaddset (&set,SIGTERM ); +if (sigprocmask (SIG_UNBLOCK , &set,NULL ) ==-1 ) +fprintf (stderr,"unblock signal fail, possible issue for HVM save!\n" ); + + } +main_loop ();quit_timers ();return 0 ;