Index: ioemu/hw/cirrus_vga.c
===================================================================
--- ioemu.orig/hw/cirrus_vga.c	2007-05-09 14:09:12.000000000 +0100
+++ ioemu/hw/cirrus_vga.c	2007-05-09 14:10:58.000000000 +0100
@@ -3016,11 +3016,42 @@
     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, s->vram_ptr);
+        fprintf(stderr, "cirrus_stop_acc:unset_vram_mapping.\n");
+    }
+}
+
+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;
 
     if (s->pci_dev)
         pci_device_save(s->pci_dev, f);
@@ -3058,11 +3089,20 @@
     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;
     int ret;
 
     if (version_id > 2)
@@ -3108,6 +3148,14 @@
     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;
     cirrus_update_bank_ptr(s, 0);
Index: ioemu/vl.c
===================================================================
--- ioemu.orig/vl.c	2007-05-09 14:09:12.000000000 +0100
+++ ioemu/vl.c	2007-05-09 14:10:50.000000000 +0100
@@ -5025,6 +5025,11 @@
     if (ret < 0) {
         term_printf("Error %d while loading VM state\n", ret);
     }
+
+    /* del tmp file */
+    if (unlink(name) == -1)
+        fprintf(stderr, "delete tmp qemu state file failed.\n");
+
  the_end:
     if (saved_vm_running)
         vm_start();
@@ -5942,6 +5947,7 @@
 static 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)
@@ -6731,6 +6737,15 @@
     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;
+}
+
 int main(int argc, char **argv)
 {
 #ifdef CONFIG_GDBSTUB
@@ -7625,6 +7640,25 @@
 	close(fd);
     }
 
+    /* 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;
Index: ioemu/target-i386-dm/helper2.c
===================================================================
--- ioemu.orig/target-i386-dm/helper2.c	2007-05-09 14:09:11.000000000 +0100
+++ ioemu/target-i386-dm/helper2.c	2007-05-09 14:10:49.000000000 +0100
@@ -540,8 +540,10 @@
 {
     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);
+    char qemu_file[20];
 
     qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, env);
 
@@ -549,7 +551,14 @@
         /* Wait up to 10 msec. */
         main_loop_wait(10);
 
-    destroy_hvm_domain();
+    fprintf(logfile, "device model received suspend signal!\n");
+
+    /* Pull all outstanding ioreqs through the system */
+    main_loop_wait(1); /* For the select() on events */
+
+    /* Save the device state */
+    sprintf(qemu_file, "/tmp/xen.qemu-dm.%d", domid);
+    do_savevm(qemu_file);
 
     return 0;
 }
