ia64/xen-unstable

changeset 13493:5f340f19bbb7

[HVM] save restore: save restore dev in HV

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

save/restore all dev state in HV such as PIT/PIC/APIC
author Tim Deegan <Tim.Deegan@xensource.com>
date Thu Jan 18 16:48:05 2007 +0000 (2007-01-18)
parents 44668189f354
children 873884fe1827
files xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/i8254.c xen/arch/x86/hvm/intercept.c xen/arch/x86/hvm/rtc.c xen/arch/x86/hvm/vioapic.c xen/arch/x86/hvm/vlapic.c xen/arch/x86/hvm/vpic.c xen/arch/x86/hvm/vpt.c xen/include/asm-x86/hvm/support.h xen/include/asm-x86/hvm/vpt.h
line diff
     1.1 --- a/xen/arch/x86/hvm/hvm.c	Thu Jan 18 16:48:04 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/hvm.c	Thu Jan 18 16:48:05 2007 +0000
     1.3 @@ -197,6 +197,9 @@ int hvm_vcpu_initialise(struct vcpu *v)
     1.4      rtc_init(v, RTC_PORT(0), RTC_IRQ);
     1.5      pmtimer_init(v, ACPI_PM_TMR_BLK_ADDRESS);
     1.6      hpet_init(v);
     1.7 + 
     1.8 +    /* init hvm sharepage */
     1.9 +    shpage_init(v->domain, get_sp(v->domain));
    1.10  
    1.11      /* Init guest TSC to start from zero. */
    1.12      hvm_set_guest_time(v, 0);
     2.1 --- a/xen/arch/x86/hvm/i8254.c	Thu Jan 18 16:48:04 2007 +0000
     2.2 +++ b/xen/arch/x86/hvm/i8254.c	Thu Jan 18 16:48:05 2007 +0000
     2.3 @@ -207,11 +207,11 @@ static inline void pit_load_count(PITCha
     2.4      switch (s->mode) {
     2.5          case 2:
     2.6              /* create periodic time */
     2.7 -            create_periodic_time(&s->pt, period, 0, 0, pit_time_fired, s);
     2.8 +            create_periodic_time(current, &s->pt, period, 0, 0, pit_time_fired, s);
     2.9              break;
    2.10          case 1:
    2.11              /* create one shot time */
    2.12 -            create_periodic_time(&s->pt, period, 0, 1, pit_time_fired, s);
    2.13 +            create_periodic_time(current, &s->pt, period, 0, 1, pit_time_fired, s);
    2.14  #ifdef DEBUG_PIT
    2.15              printk("HVM_PIT: create one shot time.\n");
    2.16  #endif
    2.17 @@ -356,6 +356,154 @@ void pit_stop_channel0_irq(PITState * pi
    2.18      destroy_periodic_time(&s->pt);
    2.19  }
    2.20  
    2.21 +#ifdef HVM_DEBUG_SUSPEND
    2.22 +static void pit_info(PITState *pit)
    2.23 +{
    2.24 +    PITChannelState *s;
    2.25 +    int i;
    2.26 +
    2.27 +    for(i = 0; i < 3; i++) {
    2.28 +        printk("*****pit channel %d's state:*****\n", i);
    2.29 +        s = &pit->channels[i];
    2.30 +        printk("pit 0x%x.\n", s->count);
    2.31 +        printk("pit 0x%x.\n", s->latched_count);
    2.32 +        printk("pit 0x%x.\n", s->count_latched);
    2.33 +        printk("pit 0x%x.\n", s->status_latched);
    2.34 +        printk("pit 0x%x.\n", s->status);
    2.35 +        printk("pit 0x%x.\n", s->read_state);
    2.36 +        printk("pit 0x%x.\n", s->write_state);
    2.37 +        printk("pit 0x%x.\n", s->write_latch);
    2.38 +        printk("pit 0x%x.\n", s->rw_mode);
    2.39 +        printk("pit 0x%x.\n", s->mode);
    2.40 +        printk("pit 0x%x.\n", s->bcd);
    2.41 +        printk("pit 0x%x.\n", s->gate);
    2.42 +        printk("pit %"PRId64"\n", s->count_load_time);
    2.43 +
    2.44 +        if (s->pt) {
    2.45 +            struct periodic_time *pt = s->pt;
    2.46 +            printk("pit channel %d has a periodic timer:\n", i);
    2.47 +            printk("pt %d.\n", pt->enabled);
    2.48 +            printk("pt %d.\n", pt->one_shot);
    2.49 +            printk("pt %d.\n", pt->irq);
    2.50 +            printk("pt %d.\n", pt->first_injected);
    2.51 +
    2.52 +            printk("pt %d.\n", pt->pending_intr_nr);
    2.53 +            printk("pt %d.\n", pt->period);
    2.54 +            printk("pt %"PRId64"\n", pt->period_cycles);
    2.55 +            printk("pt %"PRId64"\n", pt->last_plt_gtime);
    2.56 +        }
    2.57 +    }
    2.58 +
    2.59 +}
    2.60 +#else
    2.61 +static void pit_info(PITState *pit)
    2.62 +{
    2.63 +}
    2.64 +#endif
    2.65 +
    2.66 +static void pit_save(hvm_domain_context_t *h, void *opaque)
    2.67 +{
    2.68 +    struct domain *d = opaque;
    2.69 +    PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
    2.70 +    PITChannelState *s;
    2.71 +    struct periodic_time *pt;
    2.72 +    int i, pti = -1;
    2.73 +    
    2.74 +    pit_info(pit);
    2.75 +
    2.76 +    for(i = 0; i < 3; i++) {
    2.77 +        s = &pit->channels[i];
    2.78 +        hvm_put_32u(h, s->count);
    2.79 +        hvm_put_16u(h, s->latched_count);
    2.80 +        hvm_put_8u(h, s->count_latched);
    2.81 +        hvm_put_8u(h, s->status_latched);
    2.82 +        hvm_put_8u(h, s->status);
    2.83 +        hvm_put_8u(h, s->read_state);
    2.84 +        hvm_put_8u(h, s->write_state);
    2.85 +        hvm_put_8u(h, s->write_latch);
    2.86 +        hvm_put_8u(h, s->rw_mode);
    2.87 +        hvm_put_8u(h, s->mode);
    2.88 +        hvm_put_8u(h, s->bcd);
    2.89 +        hvm_put_8u(h, s->gate);
    2.90 +        hvm_put_64u(h, s->count_load_time);
    2.91 +
    2.92 +        if (s->pt.enabled && pti == -1)
    2.93 +            pti = i;
    2.94 +    }
    2.95 +
    2.96 +    pt = &pit->channels[pti].pt;
    2.97 +
    2.98 +    /* save the vcpu for pt */
    2.99 +    hvm_put_32u(h, pt->vcpu->vcpu_id);
   2.100 +
   2.101 +    /* save guest time */
   2.102 +    hvm_put_8u(h, pti);
   2.103 +    hvm_put_32u(h, pt->pending_intr_nr);
   2.104 +    hvm_put_64u(h, pt->last_plt_gtime);
   2.105 +
   2.106 +}
   2.107 +
   2.108 +static int pit_load(hvm_domain_context_t *h, void *opaque, int version_id)
   2.109 +{
   2.110 +    struct domain *d = opaque;
   2.111 +    PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
   2.112 +    PITChannelState *s;
   2.113 +    int i, pti, vcpu_id;
   2.114 +    u32 period;
   2.115 +
   2.116 +    if (version_id != 1)
   2.117 +        return -EINVAL;
   2.118 +
   2.119 +    for(i = 0; i < 3; i++) {
   2.120 +        s = &pit->channels[i];
   2.121 +        s->count = hvm_get_32u(h);
   2.122 +        s->latched_count = hvm_get_16u(h);
   2.123 +        s->count_latched = hvm_get_8u(h);
   2.124 +        s->status_latched = hvm_get_8u(h);
   2.125 +        s->status = hvm_get_8u(h);
   2.126 +        s->read_state = hvm_get_8u(h);
   2.127 +        s->write_state = hvm_get_8u(h);
   2.128 +        s->write_latch = hvm_get_8u(h);
   2.129 +        s->rw_mode = hvm_get_8u(h);
   2.130 +        s->mode = hvm_get_8u(h);
   2.131 +        s->bcd = hvm_get_8u(h);
   2.132 +        s->gate = hvm_get_8u(h);
   2.133 +        s->count_load_time = hvm_get_64u(h);
   2.134 +    }
   2.135 +
   2.136 +    vcpu_id = hvm_get_32u(h);
   2.137 +
   2.138 +    pti = hvm_get_8u(h);
   2.139 +    if ( pti < 0 || pti > 2) {
   2.140 +        printk("pit load get a wrong channel %d when HVM resume.\n", pti);
   2.141 +        return -EINVAL;
   2.142 +    }
   2.143 +
   2.144 +    s = &pit->channels[pti];
   2.145 +    period = DIV_ROUND((s->count * 1000000000ULL), PIT_FREQ);
   2.146 +
   2.147 +    printk("recreate periodic timer %d in mode %d, freq=%d.\n", pti, s->mode, period);
   2.148 +    switch (s->mode) {
   2.149 +        case 2:
   2.150 +            /* create periodic time */
   2.151 +            create_periodic_time(d->vcpu[vcpu_id], &s->pt, period, 0, 0, pit_time_fired, s);
   2.152 +            break;
   2.153 +        case 1:
   2.154 +            /* create one shot time */
   2.155 +            create_periodic_time(d->vcpu[vcpu_id], &s->pt, period, 0, 1, pit_time_fired, s);
   2.156 +            break;
   2.157 +        default:
   2.158 +            printk("pit mode %"PRId8" should not use periodic timer!\n", s->mode);
   2.159 +            return -EINVAL;
   2.160 +    }
   2.161 +    s->pt.pending_intr_nr = hvm_get_32u(h);
   2.162 +    s->pt.last_plt_gtime = hvm_get_64u(h);
   2.163 +
   2.164 +    pit_info(pit);
   2.165 +
   2.166 +    return 0;
   2.167 +}
   2.168 +
   2.169  static void pit_reset(void *opaque)
   2.170  {
   2.171      PITState *pit = opaque;
   2.172 @@ -383,6 +531,7 @@ void pit_init(struct vcpu *v, unsigned l
   2.173      s++; s->pt.vcpu = v;
   2.174      s++; s->pt.vcpu = v;
   2.175  
   2.176 +    hvm_register_savevm(v->domain, "xen_hvm_i8254", PIT_BASE, 1, pit_save, pit_load, v->domain);
   2.177      register_portio_handler(v->domain, PIT_BASE, 4, handle_pit_io);
   2.178      /* register the speaker port */
   2.179      register_portio_handler(v->domain, 0x61, 1, handle_speaker_io);
     3.1 --- a/xen/arch/x86/hvm/intercept.c	Thu Jan 18 16:48:04 2007 +0000
     3.2 +++ b/xen/arch/x86/hvm/intercept.c	Thu Jan 18 16:48:05 2007 +0000
     3.3 @@ -386,6 +386,65 @@ int arch_sethvm_ctxt(
     3.4      return hvm_load(v, c);
     3.5  }
     3.6  
     3.7 +#ifdef HVM_DEBUG_SUSPEND
     3.8 +static void shpage_info(shared_iopage_t *sh)
     3.9 +{
    3.10 +
    3.11 +    vcpu_iodata_t *p = &sh->vcpu_iodata[0];
    3.12 +    ioreq_t *req = &p->vp_ioreq;
    3.13 +    printk("*****sharepage_info******!\n");
    3.14 +    printk("vp_eport=%d\n", p->vp_eport);
    3.15 +    printk("io packet: "
    3.16 +                     "state:%x, pvalid: %x, dir:%x, port: %"PRIx64", "
    3.17 +                     "data: %"PRIx64", count: %"PRIx64", size: %"PRIx64"\n",
    3.18 +                     req->state, req->data_is_ptr, req->dir, req->addr,
    3.19 +                     req->data, req->count, req->size);
    3.20 +}
    3.21 +#else
    3.22 +static void shpage_info(shared_iopage_t *sh)
    3.23 +{
    3.24 +}
    3.25 +#endif
    3.26 +
    3.27 +static void shpage_save(hvm_domain_context_t *h, void *opaque)
    3.28 +{
    3.29 +    /* XXX:no action required for shpage save/restore, since it's in guest memory
    3.30 +     * keep it for debug purpose only */
    3.31 +
    3.32 +#if 0
    3.33 +    struct shared_iopage *s = opaque;
    3.34 +    /* XXX:smp */
    3.35 +    struct ioreq *req = &s->vcpu_iodata[0].vp_ioreq;
    3.36 +    
    3.37 +    shpage_info(s);
    3.38 +
    3.39 +    hvm_put_buffer(h, (char*)req, sizeof(struct ioreq));
    3.40 +#endif
    3.41 +}
    3.42 +
    3.43 +static int shpage_load(hvm_domain_context_t *h, void *opaque, int version_id)
    3.44 +{
    3.45 +    struct shared_iopage *s = opaque;
    3.46 +#if 0
    3.47 +    /* XXX:smp */
    3.48 +    struct ioreq *req = &s->vcpu_iodata[0].vp_ioreq;
    3.49 +
    3.50 +    if (version_id != 1)
    3.51 +        return -EINVAL;
    3.52 +
    3.53 +    hvm_get_buffer(h, (char*)req, sizeof(struct ioreq));
    3.54 +
    3.55 +
    3.56 +#endif
    3.57 +    shpage_info(s);
    3.58 +    return 0;
    3.59 +}
    3.60 +
    3.61 +void shpage_init(struct domain *d, shared_iopage_t *sp)
    3.62 +{
    3.63 +    hvm_register_savevm(d, "xen_hvm_shpage", 0x10, 1, shpage_save, shpage_load, sp);
    3.64 +}
    3.65 +
    3.66  int hvm_buffered_io_intercept(ioreq_t *p)
    3.67  {
    3.68      struct vcpu *v = current;
     4.1 --- a/xen/arch/x86/hvm/rtc.c	Thu Jan 18 16:48:04 2007 +0000
     4.2 +++ b/xen/arch/x86/hvm/rtc.c	Thu Jan 18 16:48:05 2007 +0000
     4.3 @@ -62,7 +62,7 @@ static void rtc_timer_update(RTCState *s
     4.4  #ifdef DEBUG_RTC
     4.5          printk("HVM_RTC: period = %uns\n", period);
     4.6  #endif
     4.7 -        create_periodic_time(&s->pt, period, RTC_IRQ, 0, rtc_periodic_cb, s);
     4.8 +        create_periodic_time(current, &s->pt, period, RTC_IRQ, 0, rtc_periodic_cb, s);
     4.9      } 
    4.10      else
    4.11          destroy_periodic_time(&s->pt);
     5.1 --- a/xen/arch/x86/hvm/vioapic.c	Thu Jan 18 16:48:04 2007 +0000
     5.2 +++ b/xen/arch/x86/hvm/vioapic.c	Thu Jan 18 16:48:05 2007 +0000
     5.3 @@ -473,11 +473,139 @@ void vioapic_update_EOI(struct domain *d
     5.4      spin_unlock(&hvm_irq->lock);
     5.5  }
     5.6  
     5.7 +#ifdef HVM_DEBUG_SUSPEND
     5.8 +static void ioapic_info(struct vioapic *s)
     5.9 +{
    5.10 +    int i;
    5.11 +    printk("*****ioapic state:*****\n");
    5.12 +    printk("ioapic 0x%x.\n", s->ioregsel);
    5.13 +    printk("ioapic 0x%x.\n", s->id);
    5.14 +    printk("ioapic 0x%lx.\n", s->base_address);
    5.15 +    for (i = 0; i < VIOAPIC_NUM_PINS; i++) {
    5.16 +        printk("ioapic redirtbl[%d]:0x%"PRIx64"\n", i, s->redirtbl[i].bits);
    5.17 +    }
    5.18 +
    5.19 +}
    5.20 +static void hvmirq_info(struct hvm_irq *hvm_irq)
    5.21 +{
    5.22 +    int i;
    5.23 +    printk("*****hvmirq state:*****\n");
    5.24 +    for (i = 0; i < BITS_TO_LONGS(32*4); i++)
    5.25 +        printk("hvmirq pci_intx[%d]:0x%lx.\n", i, hvm_irq->pci_intx[i]);
    5.26 +
    5.27 +    for (i = 0; i < BITS_TO_LONGS(16); i++)
    5.28 +        printk("hvmirq isa_irq[%d]:0x%lx.\n", i, hvm_irq->isa_irq[i]);
    5.29 +
    5.30 +    for (i = 0; i < BITS_TO_LONGS(1); i++)
    5.31 +        printk("hvmirq callback_irq_wire[%d]:0x%lx.\n", i, hvm_irq->callback_irq_wire[i]);
    5.32 +
    5.33 +    printk("hvmirq callback_gsi:0x%x.\n", hvm_irq->callback_gsi);
    5.34 +
    5.35 +    for (i = 0; i < 4; i++)
    5.36 +        printk("hvmirq pci_link_route[%d]:0x%"PRIx8".\n", i, hvm_irq->pci_link_route[i]);
    5.37 +
    5.38 +    for (i = 0; i < 4; i++)
    5.39 +        printk("hvmirq pci_link_assert_count[%d]:0x%"PRIx8".\n", i, hvm_irq->pci_link_assert_count[i]);
    5.40 +
    5.41 +    for (i = 0; i < 4; i++)
    5.42 +        printk("hvmirq gsi_assert_count[%d]:0x%"PRIx8".\n", i, hvm_irq->gsi_assert_count[i]);
    5.43 +
    5.44 +    printk("hvmirq round_robin_prev_vcpu:0x%"PRIx8".\n", hvm_irq->round_robin_prev_vcpu);
    5.45 +}
    5.46 +#else
    5.47 +static void ioapic_info(struct vioapic *s)
    5.48 +{
    5.49 +}
    5.50 +static void hvmirq_info(struct hvm_irq *hvm_irq)
    5.51 +{
    5.52 +}
    5.53 +#endif
    5.54 +
    5.55 +static void ioapic_save(hvm_domain_context_t *h, void *opaque)
    5.56 +{
    5.57 +    int i;
    5.58 +    struct domain *d = opaque;
    5.59 +    struct vioapic *s = domain_vioapic(d);
    5.60 +    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
    5.61 +
    5.62 +    ioapic_info(s);
    5.63 +    hvmirq_info(hvm_irq);
    5.64 +
    5.65 +    /* save iopaic state*/
    5.66 +    hvm_put_32u(h, s->ioregsel);
    5.67 +    hvm_put_32u(h, s->id);
    5.68 +    hvm_put_64u(h, s->base_address);
    5.69 +    for (i = 0; i < VIOAPIC_NUM_PINS; i++) {
    5.70 +        hvm_put_64u(h, s->redirtbl[i].bits);
    5.71 +    }
    5.72 +
    5.73 +    /* save hvm irq state */
    5.74 +    hvm_put_buffer(h, (char*)hvm_irq->pci_intx, 16);
    5.75 +    hvm_put_buffer(h, (char*)hvm_irq->isa_irq, 2);
    5.76 +    hvm_put_buffer(h, (char*)hvm_irq->callback_irq_wire, 1);
    5.77 +    hvm_put_32u(h, hvm_irq->callback_gsi);
    5.78 +
    5.79 +    for (i = 0; i < 4; i++)
    5.80 +        hvm_put_8u(h, hvm_irq->pci_link_route[i]);
    5.81 +
    5.82 +    for (i = 0; i < 4; i++)
    5.83 +        hvm_put_8u(h, hvm_irq->pci_link_assert_count[i]);
    5.84 +
    5.85 +    for (i = 0; i < VIOAPIC_NUM_PINS; i++)
    5.86 +        hvm_put_8u(h, hvm_irq->gsi_assert_count[i]);
    5.87 +
    5.88 +    hvm_put_8u(h, hvm_irq->round_robin_prev_vcpu);
    5.89 +
    5.90 +}
    5.91 +
    5.92 +static int ioapic_load(hvm_domain_context_t *h, void *opaque, int version_id)
    5.93 +{
    5.94 +    int i;
    5.95 +    struct domain *d = opaque;
    5.96 +    struct vioapic *s = domain_vioapic(d);
    5.97 +    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
    5.98 +    
    5.99 +    if (version_id != 1)
   5.100 +        return -EINVAL;
   5.101 +
   5.102 +    /* restore ioapic state */
   5.103 +    s->ioregsel = hvm_get_32u(h);
   5.104 +    s->id = hvm_get_32u(h);
   5.105 +    s->base_address = hvm_get_64u(h);
   5.106 +    for (i = 0; i < VIOAPIC_NUM_PINS; i++) {
   5.107 +        s->redirtbl[i].bits = hvm_get_64u(h);
   5.108 +    }
   5.109 +
   5.110 +    /* restore irq state */
   5.111 +    hvm_get_buffer(h, (char*)hvm_irq->pci_intx, 16);
   5.112 +    hvm_get_buffer(h, (char*)hvm_irq->isa_irq, 2);
   5.113 +    hvm_get_buffer(h, (char*)hvm_irq->callback_irq_wire, 1);
   5.114 +    hvm_irq->callback_gsi = hvm_get_32u(h);
   5.115 +
   5.116 +    for (i = 0; i < 4; i++)
   5.117 +        hvm_irq->pci_link_route[i] = hvm_get_8u(h);
   5.118 +
   5.119 +    for (i = 0; i < 4; i++)
   5.120 +        hvm_irq->pci_link_assert_count[i] = hvm_get_8u(h);
   5.121 +
   5.122 +    for (i = 0; i < VIOAPIC_NUM_PINS; i++)
   5.123 +        hvm_irq->gsi_assert_count[i] = hvm_get_8u(h);
   5.124 +
   5.125 +    hvm_irq->round_robin_prev_vcpu = hvm_get_8u(h);
   5.126 +
   5.127 +    ioapic_info(s);
   5.128 +    hvmirq_info(hvm_irq);
   5.129 +
   5.130 +    return 0;
   5.131 +}
   5.132 +
   5.133  void vioapic_init(struct domain *d)
   5.134  {
   5.135      struct vioapic *vioapic = domain_vioapic(d);
   5.136      int i;
   5.137  
   5.138 +    hvm_register_savevm(d, "xen_hvm_ioapic", 0, 1, ioapic_save, ioapic_load, d);
   5.139 +
   5.140      memset(vioapic, 0, sizeof(*vioapic));
   5.141      for ( i = 0; i < VIOAPIC_NUM_PINS; i++ )
   5.142          vioapic->redirtbl[i].fields.mask = 1;
     6.1 --- a/xen/arch/x86/hvm/vlapic.c	Thu Jan 18 16:48:04 2007 +0000
     6.2 +++ b/xen/arch/x86/hvm/vlapic.c	Thu Jan 18 16:48:05 2007 +0000
     6.3 @@ -659,7 +659,7 @@ static void vlapic_write(struct vcpu *v,
     6.4          uint64_t period = APIC_BUS_CYCLE_NS * (uint32_t)val * vlapic->timer_divisor;
     6.5  
     6.6          vlapic_set_reg(vlapic, APIC_TMICT, val);
     6.7 -        create_periodic_time(&vlapic->pt, period, vlapic->pt.irq,
     6.8 +        create_periodic_time(current, &vlapic->pt, period, vlapic->pt.irq,
     6.9                               vlapic_lvtt_period(vlapic), NULL, vlapic);
    6.10  
    6.11          HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
    6.12 @@ -795,6 +795,77 @@ static int vlapic_reset(struct vlapic *v
    6.13      return 1;
    6.14  }
    6.15  
    6.16 +#ifdef HVM_DEBUG_SUSPEND
    6.17 +static void lapic_info(struct vlapic *s)
    6.18 +{
    6.19 +    printk("*****lapic state:*****\n");
    6.20 +    printk("lapic 0x%"PRIx64".\n", s->apic_base_msr);
    6.21 +    printk("lapic 0x%x.\n", s->disabled);
    6.22 +    printk("lapic 0x%x.\n", s->timer_divisor);
    6.23 +    printk("lapic 0x%x.\n", s->timer_pending_count);
    6.24 +}
    6.25 +#else
    6.26 +static void lapic_info(struct vlapic *s)
    6.27 +{
    6.28 +}
    6.29 +#endif
    6.30 +
    6.31 +static void lapic_save(hvm_domain_context_t *h, void *opaque)
    6.32 +{
    6.33 +    struct vlapic *s = opaque;
    6.34 +
    6.35 +    lapic_info(s);
    6.36 +
    6.37 +    hvm_put_64u(h, s->apic_base_msr);
    6.38 +    hvm_put_32u(h, s->disabled);
    6.39 +    hvm_put_32u(h, s->timer_divisor);
    6.40 +
    6.41 +    /*XXX: need this?*/
    6.42 +    hvm_put_32u(h, s->timer_pending_count);
    6.43 +
    6.44 +    hvm_put_buffer(h, (char*)s->regs, 0x3f0);
    6.45 +
    6.46 +}
    6.47 +
    6.48 +static int lapic_load(hvm_domain_context_t *h, void *opaque, int version_id)
    6.49 +{
    6.50 +    struct vlapic *s = opaque;
    6.51 +    struct vcpu *v = vlapic_vcpu(s);
    6.52 +    unsigned long tmict;
    6.53 +
    6.54 +    if (version_id != 1)
    6.55 +        return -EINVAL;
    6.56 +
    6.57 +    s->apic_base_msr = hvm_get_64u(h);
    6.58 +    s->disabled = hvm_get_32u(h);
    6.59 +    s->timer_divisor = hvm_get_32u(h);
    6.60 +
    6.61 +    /*XXX: need this?*/
    6.62 +    s->timer_pending_count = hvm_get_32u(h);
    6.63 +
    6.64 +    hvm_get_buffer(h, (char*)s->regs, 0x3f0);
    6.65 +
    6.66 +    /* rearm the actiemr if needed */
    6.67 +    tmict = vlapic_get_reg(s, APIC_TMICT);
    6.68 +    if (tmict > 0) {
    6.69 +        uint64_t period = APIC_BUS_CYCLE_NS * (uint32_t)tmict * s->timer_divisor;
    6.70 +
    6.71 +        create_periodic_time(v, &s->pt, period, s->pt.irq,
    6.72 +                             vlapic_lvtt_period(s), NULL, s);
    6.73 +
    6.74 +        printk("lapic_load to rearm the actimer:"
    6.75 +                    "bus cycle is %uns, "
    6.76 +                    "saved tmict count %lu, period %"PRIu64"ns\n",
    6.77 +                    APIC_BUS_CYCLE_NS, tmict, period);
    6.78 +
    6.79 +    }
    6.80 +
    6.81 +
    6.82 +    lapic_info(s);
    6.83 +
    6.84 +    return 0;
    6.85 +}
    6.86 +
    6.87  int vlapic_init(struct vcpu *v)
    6.88  {
    6.89      struct vlapic *vlapic = vcpu_vlapic(v);
    6.90 @@ -813,6 +884,7 @@ int vlapic_init(struct vcpu *v)
    6.91      vlapic->regs = map_domain_page_global(page_to_mfn(vlapic->regs_page));
    6.92      memset(vlapic->regs, 0, PAGE_SIZE);
    6.93  
    6.94 +    hvm_register_savevm(v->domain, "xen_hvm_lapic", v->vcpu_id, 1, lapic_save, lapic_load, vlapic);
    6.95      vlapic_reset(vlapic);
    6.96  
    6.97      vlapic->apic_base_msr = MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
     7.1 --- a/xen/arch/x86/hvm/vpic.c	Thu Jan 18 16:48:04 2007 +0000
     7.2 +++ b/xen/arch/x86/hvm/vpic.c	Thu Jan 18 16:48:05 2007 +0000
     7.3 @@ -378,6 +378,87 @@ static int vpic_intercept_elcr_io(ioreq_
     7.4      return 1;
     7.5  }
     7.6  
     7.7 +#ifdef HVM_DEBUG_SUSPEND
     7.8 +static void vpic_info(struct vpic *s)
     7.9 +{
    7.10 +    printk("*****pic state:*****\n");
    7.11 +    printk("pic 0x%x.\n", s->irr);
    7.12 +    printk("pic 0x%x.\n", s->imr);
    7.13 +    printk("pic 0x%x.\n", s->isr);
    7.14 +    printk("pic 0x%x.\n", s->irq_base);
    7.15 +    printk("pic 0x%x.\n", s->init_state);
    7.16 +    printk("pic 0x%x.\n", s->priority_add);
    7.17 +    printk("pic 0x%x.\n", s->readsel_isr);
    7.18 +    printk("pic 0x%x.\n", s->poll);
    7.19 +    printk("pic 0x%x.\n", s->auto_eoi);
    7.20 +    printk("pic 0x%x.\n", s->rotate_on_auto_eoi);
    7.21 +    printk("pic 0x%x.\n", s->special_fully_nested_mode);
    7.22 +    printk("pic 0x%x.\n", s->special_mask_mode);
    7.23 +    printk("pic 0x%x.\n", s->elcr);
    7.24 +    printk("pic 0x%x.\n", s->int_output);
    7.25 +    printk("pic 0x%x.\n", s->is_master);
    7.26 +}
    7.27 +#else
    7.28 +static void vpic_info(struct vpic *s)
    7.29 +{
    7.30 +}
    7.31 +#endif
    7.32 +
    7.33 +static void vpic_save(hvm_domain_context_t *h, void *opaque)
    7.34 +{
    7.35 +    struct vpic *s = opaque;
    7.36 +    
    7.37 +    vpic_info(s);
    7.38 +
    7.39 +    hvm_put_8u(h, s->irr);
    7.40 +    hvm_put_8u(h, s->imr);
    7.41 +    hvm_put_8u(h, s->isr);
    7.42 +    hvm_put_8u(h, s->irq_base);
    7.43 +    hvm_put_8u(h, s->init_state);
    7.44 +    hvm_put_8u(h, s->priority_add);
    7.45 +    hvm_put_8u(h, s->readsel_isr);
    7.46 +
    7.47 +    hvm_put_8u(h, s->poll);
    7.48 +    hvm_put_8u(h, s->auto_eoi);
    7.49 +
    7.50 +    hvm_put_8u(h, s->rotate_on_auto_eoi);
    7.51 +    hvm_put_8u(h, s->special_fully_nested_mode);
    7.52 +    hvm_put_8u(h, s->special_mask_mode);
    7.53 +
    7.54 +    hvm_put_8u(h, s->elcr);
    7.55 +    hvm_put_8u(h, s->int_output);
    7.56 +}
    7.57 +
    7.58 +static int vpic_load(hvm_domain_context_t *h, void *opaque, int version_id)
    7.59 +{
    7.60 +    struct vpic *s = opaque;
    7.61 +    
    7.62 +    if (version_id != 1)
    7.63 +        return -EINVAL;
    7.64 +
    7.65 +    s->irr = hvm_get_8u(h);
    7.66 +    s->imr = hvm_get_8u(h);
    7.67 +    s->isr = hvm_get_8u(h);
    7.68 +    s->irq_base = hvm_get_8u(h);
    7.69 +    s->init_state = hvm_get_8u(h);
    7.70 +    s->priority_add = hvm_get_8u(h);
    7.71 +    s->readsel_isr = hvm_get_8u(h);
    7.72 +
    7.73 +    s->poll = hvm_get_8u(h);
    7.74 +    s->auto_eoi = hvm_get_8u(h);
    7.75 +
    7.76 +    s->rotate_on_auto_eoi = hvm_get_8u(h);
    7.77 +    s->special_fully_nested_mode = hvm_get_8u(h);
    7.78 +    s->special_mask_mode = hvm_get_8u(h);
    7.79 +
    7.80 +    s->elcr = hvm_get_8u(h);
    7.81 +    s->int_output = hvm_get_8u(h);
    7.82 +
    7.83 +    vpic_info(s);
    7.84 +
    7.85 +    return 0;
    7.86 +}
    7.87 +
    7.88  void vpic_init(struct domain *d)
    7.89  {
    7.90      struct vpic *vpic;
    7.91 @@ -387,12 +468,14 @@ void vpic_init(struct domain *d)
    7.92      memset(vpic, 0, sizeof(*vpic));
    7.93      vpic->is_master = 1;
    7.94      vpic->elcr      = 1 << 2;
    7.95 +    hvm_register_savevm(d, "xen_hvm_i8259", 0x20, 1, vpic_save, vpic_load, vpic);
    7.96      register_portio_handler(d, 0x20, 2, vpic_intercept_pic_io);
    7.97      register_portio_handler(d, 0x4d0, 1, vpic_intercept_elcr_io);
    7.98  
    7.99      /* Slave PIC. */
   7.100      vpic++;
   7.101      memset(vpic, 0, sizeof(*vpic));
   7.102 +    hvm_register_savevm(d, "xen_hvm_i8259", 0xa0, 1, vpic_save, vpic_load, vpic);
   7.103      register_portio_handler(d, 0xa0, 2, vpic_intercept_pic_io);
   7.104      register_portio_handler(d, 0x4d1, 1, vpic_intercept_elcr_io);
   7.105  }
     8.1 --- a/xen/arch/x86/hvm/vpt.c	Thu Jan 18 16:48:04 2007 +0000
     8.2 +++ b/xen/arch/x86/hvm/vpt.c	Thu Jan 18 16:48:05 2007 +0000
     8.3 @@ -195,7 +195,7 @@ void pt_reset(struct vcpu *v)
     8.4      }
     8.5  }
     8.6  
     8.7 -void create_periodic_time(struct periodic_time *pt, uint64_t period,
     8.8 +void create_periodic_time(struct vcpu *v, struct periodic_time *pt, uint64_t period,
     8.9                            uint8_t irq, char one_shot, time_cb *cb, void *data)
    8.10  {
    8.11      destroy_periodic_time(pt);
    8.12 @@ -209,7 +209,7 @@ void create_periodic_time(struct periodi
    8.13          period = 900000; /* force to 0.9ms */
    8.14      }
    8.15      pt->period = period;
    8.16 -    pt->vcpu = current;
    8.17 +    pt->vcpu = v;
    8.18      pt->last_plt_gtime = hvm_get_guest_time(pt->vcpu);
    8.19      pt->irq = irq;
    8.20      pt->period_cycles = (u64)period * cpu_khz / 1000000L;
    8.21 @@ -218,7 +218,7 @@ void create_periodic_time(struct periodi
    8.22      pt->cb = cb;
    8.23      pt->priv = data;
    8.24  
    8.25 -    list_add(&pt->list, &current->arch.hvm_vcpu.tm_list);
    8.26 +    list_add(&pt->list, &v->arch.hvm_vcpu.tm_list);
    8.27      set_timer(&pt->timer, pt->scheduled);
    8.28  }
    8.29  
     9.1 --- a/xen/include/asm-x86/hvm/support.h	Thu Jan 18 16:48:04 2007 +0000
     9.2 +++ b/xen/include/asm-x86/hvm/support.h	Thu Jan 18 16:48:05 2007 +0000
     9.3 @@ -246,6 +246,8 @@ extern int hvm_load(struct vcpu*, hvm_do
     9.4  extern int arch_sethvm_ctxt(struct vcpu *v, struct hvm_domain_context *c);
     9.5  extern int arch_gethvm_ctxt(struct vcpu *v, struct hvm_domain_context *c);
     9.6  
     9.7 +extern void shpage_init(struct domain *d, shared_iopage_t *sp);
     9.8 +
     9.9  extern int hvm_enabled;
    9.10  
    9.11  int hvm_copy_to_guest_phys(paddr_t paddr, void *buf, int size);
    10.1 --- a/xen/include/asm-x86/hvm/vpt.h	Thu Jan 18 16:48:04 2007 +0000
    10.2 +++ b/xen/include/asm-x86/hvm/vpt.h	Thu Jan 18 16:48:05 2007 +0000
    10.3 @@ -152,7 +152,7 @@ void pt_update_irq(struct vcpu *v);
    10.4  struct periodic_time *is_pt_irq(struct vcpu *v, int vector, int type);
    10.5  void pt_intr_post(struct vcpu *v, int vector, int type);
    10.6  void pt_reset(struct vcpu *v);
    10.7 -void create_periodic_time(struct periodic_time *pt, uint64_t period,
    10.8 +void create_periodic_time(struct vcpu *v, struct periodic_time *pt, uint64_t period,
    10.9                            uint8_t irq, char one_shot, time_cb *cb, void *data);
   10.10  void destroy_periodic_time(struct periodic_time *pt);
   10.11