direct-io.hg

changeset 13417:239c8504f48d

[HVM] save restore: device model support

Signed-off-by: Zhai Edwin <edwin.zhai@intel.com>

qemu's save/restore including vga acceleration support
author Tim Deegan <Tim.Deegan@xensource.com>
date Thu Jan 18 16:48:07 2007 +0000 (2007-01-18)
parents 873884fe1827
children 4138b80a8a23
files tools/ioemu/hw/cirrus_vga.c tools/ioemu/hw/ide.c tools/ioemu/hw/pci.c tools/ioemu/target-i386-dm/helper2.c tools/ioemu/vl.c
line diff
     1.1 --- a/tools/ioemu/hw/cirrus_vga.c	Tue Jan 16 16:58:16 2007 +0000
     1.2 +++ b/tools/ioemu/hw/cirrus_vga.c	Thu Jan 18 16:48:07 2007 +0000
     1.3 @@ -3010,11 +3010,44 @@ static CPUWriteMemoryFunc *cirrus_mmio_w
     1.4      cirrus_mmio_writel,
     1.5  };
     1.6  
     1.7 +void cirrus_stop_acc(CirrusVGAState *s)
     1.8 +{
     1.9 +    if (s->map_addr){
    1.10 +        int error;
    1.11 +        s->map_addr = 0;
    1.12 +        error = unset_vram_mapping(s->cirrus_lfb_addr,
    1.13 +                s->cirrus_lfb_end);
    1.14 +        fprintf(stderr, "cirrus_stop_acc:unset_vram_mapping.\n");
    1.15 +
    1.16 +        munmap(s->vram_ptr, VGA_RAM_SIZE);
    1.17 +    }
    1.18 +}
    1.19 +
    1.20 +void cirrus_restart_acc(CirrusVGAState *s)
    1.21 +{
    1.22 +    if (s->cirrus_lfb_addr && s->cirrus_lfb_end) {
    1.23 +        void *vram_pointer, *old_vram;
    1.24 +        fprintf(stderr, "cirrus_vga_load:re-enable vga acc.lfb_addr=0x%lx, lfb_end=0x%lx.\n",
    1.25 +                s->cirrus_lfb_addr, s->cirrus_lfb_end);
    1.26 +        vram_pointer = set_vram_mapping(s->cirrus_lfb_addr ,s->cirrus_lfb_end);
    1.27 +        if (!vram_pointer){
    1.28 +            fprintf(stderr, "cirrus_vga_load:NULL vram_pointer\n");
    1.29 +        } else {
    1.30 +            old_vram = vga_update_vram((VGAState *)s, vram_pointer,
    1.31 +                    VGA_RAM_SIZE);
    1.32 +            qemu_free(old_vram);
    1.33 +            s->map_addr = s->cirrus_lfb_addr;
    1.34 +            s->map_end = s->cirrus_lfb_end;
    1.35 +        }
    1.36 +    }
    1.37 +}
    1.38 +
    1.39  /* load/save state */
    1.40  
    1.41  static void cirrus_vga_save(QEMUFile *f, void *opaque)
    1.42  {
    1.43      CirrusVGAState *s = opaque;
    1.44 +    uint8_t vga_acc;
    1.45  
    1.46      qemu_put_be32s(f, &s->latch);
    1.47      qemu_put_8s(f, &s->sr_index);
    1.48 @@ -3049,11 +3082,20 @@ static void cirrus_vga_save(QEMUFile *f,
    1.49      qemu_put_be32s(f, &s->hw_cursor_y);
    1.50      /* XXX: we do not save the bitblt state - we assume we do not save
    1.51         the state when the blitter is active */
    1.52 +
    1.53 +    vga_acc = (!!s->map_addr);
    1.54 +    qemu_put_8s(f, &vga_acc);
    1.55 +    qemu_put_be64s(f, (uint64_t*)&s->cirrus_lfb_addr);
    1.56 +    qemu_put_be64s(f, (uint64_t*)&s->cirrus_lfb_end);
    1.57 +    qemu_put_buffer(f, s->vram_ptr, VGA_RAM_SIZE); 
    1.58 +    if (vga_acc)
    1.59 +        cirrus_stop_acc(s);
    1.60  }
    1.61  
    1.62  static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
    1.63  {
    1.64      CirrusVGAState *s = opaque;
    1.65 +    uint8_t vga_acc = 0;
    1.66  
    1.67      if (version_id != 1)
    1.68          return -EINVAL;
    1.69 @@ -3092,6 +3134,14 @@ static int cirrus_vga_load(QEMUFile *f, 
    1.70      qemu_get_be32s(f, &s->hw_cursor_x);
    1.71      qemu_get_be32s(f, &s->hw_cursor_y);
    1.72  
    1.73 +    qemu_get_8s(f, &vga_acc);
    1.74 +    qemu_get_be64s(f, (uint64_t*)&s->cirrus_lfb_addr);
    1.75 +    qemu_get_be64s(f, (uint64_t*)&s->cirrus_lfb_end);
    1.76 +    qemu_get_buffer(f, s->vram_ptr, VGA_RAM_SIZE); 
    1.77 +    if (vga_acc){
    1.78 +        cirrus_restart_acc(s);
    1.79 +    }
    1.80 +
    1.81      /* force refresh */
    1.82      s->graphic_mode = -1;
    1.83      cirrus_update_bank_ptr(s, 0);
    1.84 @@ -3297,6 +3347,8 @@ void pci_cirrus_vga_init(PCIBus *bus, Di
    1.85                      ds, vga_ram_base, vga_ram_offset, vga_ram_size);
    1.86      cirrus_init_common(s, device_id, 1);
    1.87  
    1.88 +    register_savevm("cirrus_vga_pci", 0, 1, generic_pci_save, generic_pci_load, d);
    1.89 +
    1.90      /* setup memory space */
    1.91      /* memory #0 LFB */
    1.92      /* memory #1 memory-mapped I/O */
     2.1 --- a/tools/ioemu/hw/ide.c	Tue Jan 16 16:58:16 2007 +0000
     2.2 +++ b/tools/ioemu/hw/ide.c	Thu Jan 18 16:48:07 2007 +0000
     2.3 @@ -2512,6 +2512,9 @@ void pci_piix3_ide_init(PCIBus *bus, Blo
     2.4                pic_set_irq_new, isa_pic, 15);
     2.5      ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
     2.6      ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
     2.7 +
     2.8 +    register_savevm("ide_pci", 0, 1, generic_pci_save, generic_pci_load, d);
     2.9 +
    2.10  #ifdef DMA_MULTI_THREAD    
    2.11      dma_create_thread();
    2.12  #endif //DMA_MULTI_THREAD    
     3.1 --- a/tools/ioemu/hw/pci.c	Tue Jan 16 16:58:16 2007 +0000
     3.2 +++ b/tools/ioemu/hw/pci.c	Thu Jan 18 16:48:07 2007 +0000
     3.3 @@ -63,6 +63,7 @@ void generic_pci_save(QEMUFile* f, void 
     3.4      qemu_put_buffer(f, s->config, 256);
     3.5  }
     3.6  
     3.7 +void pci_update_mappings(PCIDevice *d);
     3.8  int generic_pci_load(QEMUFile* f, void *opaque, int version_id)
     3.9  {
    3.10      PCIDevice* s=(PCIDevice*)opaque;
    3.11 @@ -71,6 +72,7 @@ int generic_pci_load(QEMUFile* f, void *
    3.12          return -EINVAL;
    3.13  
    3.14      qemu_get_buffer(f, s->config, 256);
    3.15 +    pci_update_mappings(s);
    3.16      return 0;
    3.17  }
    3.18  
     4.1 --- a/tools/ioemu/target-i386-dm/helper2.c	Tue Jan 16 16:58:16 2007 +0000
     4.2 +++ b/tools/ioemu/target-i386-dm/helper2.c	Thu Jan 18 16:48:07 2007 +0000
     4.3 @@ -546,6 +546,7 @@ int main_loop(void)
     4.4  {
     4.5      extern int vm_running;
     4.6      extern int shutdown_requested;
     4.7 +    extern int suspend_requested;
     4.8      CPUState *env = cpu_single_env;
     4.9      int evtchn_fd = xc_evtchn_fd(xce_handle);
    4.10  
    4.11 @@ -563,12 +564,24 @@ int main_loop(void)
    4.12                  qemu_system_reset();
    4.13                  reset_requested = 0;
    4.14              }
    4.15 +            if (suspend_requested) {
    4.16 +                fprintf(logfile, "device model received suspend signal!\n");
    4.17 +                break;
    4.18 +            }
    4.19          }
    4.20  
    4.21          /* Wait up to 10 msec. */
    4.22          main_loop_wait(10);
    4.23      }
    4.24 -    destroy_hvm_domain();
    4.25 +    if (!suspend_requested)
    4.26 +        destroy_hvm_domain();
    4.27 +    else {
    4.28 +        char qemu_file[20];
    4.29 +        sprintf(qemu_file, "/tmp/xen.qemu-dm.%d", domid);
    4.30 +        if (qemu_savevm(qemu_file) < 0)
    4.31 +            fprintf(stderr, "qemu save fail.\n");
    4.32 +    }
    4.33 +
    4.34      return 0;
    4.35  }
    4.36  
     5.1 --- a/tools/ioemu/vl.c	Tue Jan 16 16:58:16 2007 +0000
     5.2 +++ b/tools/ioemu/vl.c	Thu Jan 18 16:48:07 2007 +0000
     5.3 @@ -4441,6 +4441,11 @@ int qemu_loadvm(const char *filename)
     5.4          qemu_fseek(f, cur_pos + record_len, SEEK_SET);
     5.5      }
     5.6      fclose(f);
     5.7 +
     5.8 +    /* del tmp file */
     5.9 +    if (unlink(filename) == -1)
    5.10 +        fprintf(stderr, "delete tmp qemu state file failed.\n");
    5.11 +
    5.12      ret = 0;
    5.13   the_end:
    5.14      if (saved_vm_running)
    5.15 @@ -5027,6 +5032,7 @@ typedef struct QEMUResetEntry {
    5.16  static QEMUResetEntry *first_reset_entry;
    5.17  int reset_requested;
    5.18  int shutdown_requested;
    5.19 +int suspend_requested;
    5.20  static int powerdown_requested;
    5.21  
    5.22  void qemu_register_reset(QEMUResetHandler *func, void *opaque)
    5.23 @@ -5808,6 +5814,14 @@ int set_mm_mapping(int xc_handle, uint32
    5.24      return 0;
    5.25  }
    5.26  
    5.27 +void suspend(int sig)
    5.28 +{
    5.29 +   fprintf(logfile, "suspend sig handler called with requested=%d!\n", suspend_requested);
    5.30 +    if (sig != SIGUSR1)
    5.31 +        fprintf(logfile, "suspend signal dismatch, get sig=%d!\n", sig);
    5.32 +    suspend_requested = 1;
    5.33 +}
    5.34 +
    5.35  #if defined(__i386__) || defined(__x86_64__)
    5.36  static struct map_cache *mapcache_entry;
    5.37  static unsigned long nr_buckets;
    5.38 @@ -6718,6 +6732,26 @@ int main(int argc, char **argv)
    5.39              vm_start();
    5.40          }
    5.41      }
    5.42 +
    5.43 +    /* register signal for the suspend request when save */
    5.44 +    {
    5.45 +        struct sigaction act;
    5.46 +        sigset_t set;
    5.47 +        act.sa_handler = suspend;
    5.48 +        act.sa_flags = SA_RESTART;
    5.49 +        sigemptyset(&act.sa_mask);
    5.50 +
    5.51 +        sigaction(SIGUSR1, &act, NULL);
    5.52 +
    5.53 +        /* control panel mask some signals when spawn qemu, need unmask here*/
    5.54 +        sigemptyset(&set);
    5.55 +        sigaddset(&set, SIGUSR1);
    5.56 +        sigaddset(&set, SIGTERM);
    5.57 +        if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1)
    5.58 +            fprintf(stderr, "unblock signal fail, possible issue for HVM save!\n");
    5.59 +
    5.60 +    }
    5.61 +
    5.62      main_loop();
    5.63      quit_timers();
    5.64      return 0;