direct-io.hg

changeset 13801:7a7509570af9

[HVM] Save/restore: misc tidying
- Don't save PIT's last-load-time or CPU's vmx-assist bits
- Reorder save as cpu, PICs, irqs, timers
- Save the correct value in the HPET's counter.

Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
author Tim Deegan <Tim.Deegan@xensource.com>
date Mon Feb 05 11:38:22 2007 +0000 (2007-02-05)
parents 01ec7dba9ff8
children e825954d4179
files xen/arch/x86/hvm/hpet.c xen/arch/x86/hvm/i8254.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/vpt.h xen/include/public/hvm/save.h
line diff
     1.1 --- a/xen/arch/x86/hvm/hpet.c	Fri Feb 02 16:07:13 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/hpet.c	Mon Feb 05 11:38:22 2007 +0000
     1.3 @@ -383,6 +383,9 @@ static int hpet_save(struct domain *d, h
     1.4  {
     1.5      HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet;
     1.6  
     1.7 +    /* Write the proper value into the main counter */
     1.8 +    hp->hpet.mc64 = hp->mc_offset + hvm_get_guest_time(hp->vcpu);
     1.9 +
    1.10      /* Save the HPET registers */
    1.11      return hvm_save_entry(HPET, 0, h, &hp->hpet);
    1.12  }
     2.1 --- a/xen/arch/x86/hvm/i8254.c	Fri Feb 02 16:07:13 2007 +0000
     2.2 +++ b/xen/arch/x86/hvm/i8254.c	Mon Feb 05 11:38:22 2007 +0000
     2.3 @@ -83,8 +83,8 @@ static int pit_get_count(PITState *s, in
     2.4      struct hvm_hw_pit_channel *c = &s->hw.channels[channel];
     2.5      struct periodic_time *pt = &s->pt[channel];
     2.6  
     2.7 -    d = muldiv64(hvm_get_guest_time(pt->vcpu) 
     2.8 -                 - c->count_load_time, PIT_FREQ, ticks_per_sec(pt->vcpu));
     2.9 +    d = muldiv64(hvm_get_guest_time(pt->vcpu) - s->count_load_time[channel],
    2.10 +                 PIT_FREQ, ticks_per_sec(pt->vcpu));
    2.11      switch(c->mode) {
    2.12      case 0:
    2.13      case 1:
    2.14 @@ -110,7 +110,7 @@ int pit_get_out(PITState *pit, int chann
    2.15      uint64_t d;
    2.16      int out;
    2.17  
    2.18 -    d = muldiv64(current_time - s->count_load_time, 
    2.19 +    d = muldiv64(current_time - pit->count_load_time[channel], 
    2.20                   PIT_FREQ, ticks_per_sec(pit->pt[channel].vcpu));
    2.21      switch(s->mode) {
    2.22      default:
    2.23 @@ -153,7 +153,7 @@ void pit_set_gate(PITState *pit, int cha
    2.24      case 5:
    2.25          if (s->gate < val) {
    2.26              /* restart counting on rising edge */
    2.27 -            s->count_load_time = hvm_get_guest_time(pt->vcpu);
    2.28 +            pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
    2.29  //            pit_irq_timer_update(s, s->count_load_time);
    2.30          }
    2.31          break;
    2.32 @@ -161,7 +161,7 @@ void pit_set_gate(PITState *pit, int cha
    2.33      case 3:
    2.34          if (s->gate < val) {
    2.35              /* restart counting on rising edge */
    2.36 -            s->count_load_time = hvm_get_guest_time(pt->vcpu);
    2.37 +            pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
    2.38  //            pit_irq_timer_update(s, s->count_load_time);
    2.39          }
    2.40          /* XXX: disable/enable counting */
    2.41 @@ -177,8 +177,8 @@ int pit_get_gate(PITState *pit, int chan
    2.42  
    2.43  void pit_time_fired(struct vcpu *v, void *priv)
    2.44  {
    2.45 -    struct hvm_hw_pit_channel *s = priv;
    2.46 -    s->count_load_time = hvm_get_guest_time(v);
    2.47 +    uint64_t *count_load_time = priv;
    2.48 +    *count_load_time = hvm_get_guest_time(v);
    2.49  }
    2.50  
    2.51  static inline void pit_load_count(PITState *pit, int channel, int val)
    2.52 @@ -190,7 +190,7 @@ static inline void pit_load_count(PITSta
    2.53  
    2.54      if (val == 0)
    2.55          val = 0x10000;
    2.56 -    s->count_load_time = hvm_get_guest_time(pt->vcpu);
    2.57 +    pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
    2.58      s->count = val;
    2.59      period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ);
    2.60  
    2.61 @@ -203,7 +203,7 @@ static inline void pit_load_count(PITSta
    2.62              val,
    2.63              period,
    2.64              s->mode,
    2.65 -            (long long)s->count_load_time);
    2.66 +            (long long)pit->count_load_time[channel]);
    2.67  #endif
    2.68  
    2.69      /* Choose a vcpu to set the timer on: current if appropriate else vcpu 0 */
    2.70 @@ -216,11 +216,13 @@ static inline void pit_load_count(PITSta
    2.71      switch (s->mode) {
    2.72          case 2:
    2.73              /* create periodic time */
    2.74 -            create_periodic_time(v, pt, period, 0, 0, pit_time_fired, s);
    2.75 +            create_periodic_time(v, pt, period, 0, 0, pit_time_fired, 
    2.76 +                                 &pit->count_load_time[channel]);
    2.77              break;
    2.78          case 1:
    2.79              /* create one shot time */
    2.80 -            create_periodic_time(v, pt, period, 0, 1, pit_time_fired, s);
    2.81 +            create_periodic_time(v, pt, period, 0, 1, pit_time_fired,
    2.82 +                                 &pit->count_load_time[channel]);
    2.83  #ifdef DEBUG_PIT
    2.84              printk("HVM_PIT: create one shot time.\n");
    2.85  #endif
    2.86 @@ -387,7 +389,7 @@ static void pit_info(PITState *pit)
    2.87          printk("pit 0x%x.\n", s->mode);
    2.88          printk("pit 0x%x.\n", s->bcd);
    2.89          printk("pit 0x%x.\n", s->gate);
    2.90 -        printk("pit %"PRId64"\n", s->count_load_time);
    2.91 +        printk("pit %"PRId64"\n", pit->count_load_time[i]);
    2.92  
    2.93          pt = &pit->pt[i];
    2.94          if (pt) {
     3.1 --- a/xen/arch/x86/hvm/svm/svm.c	Fri Feb 02 16:07:13 2007 +0000
     3.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Mon Feb 05 11:38:22 2007 +0000
     3.3 @@ -591,6 +591,7 @@ void svm_load_cpu_state(struct vcpu *v, 
     3.4  {
     3.5      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     3.6  
     3.7 +    vmcb->kerngsbase = data->shadow_gs;
     3.8      /* MSR_LSTAR, MSR_STAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_EFER */
     3.9      vmcb->lstar  = data->msr_items[0];
    3.10      vmcb->star   = data->msr_items[1];
     4.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Feb 02 16:07:13 2007 +0000
     4.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Mon Feb 05 11:38:22 2007 +0000
     4.3 @@ -588,7 +588,7 @@ void vmx_save_cpu_state(struct vcpu *v, 
     4.4      int i = 0;
     4.5  
     4.6      data->shadow_gs = guest_state->shadow_gs;
     4.7 -    data->vmxassist_enabled = v->arch.hvm_vmx.vmxassist_enabled;
     4.8 +
     4.9      /* save msrs */
    4.10      data->flags = guest_flags;
    4.11      for (i = 0; i < VMX_MSR_COUNT; i++)
    4.12 @@ -611,10 +611,7 @@ void vmx_load_cpu_state(struct vcpu *v, 
    4.13  
    4.14      guest_state->shadow_gs = data->shadow_gs;
    4.15  
    4.16 -    /*XXX:no need to restore msrs, current!=vcpu as not called by arch_vmx_do_launch */
    4.17 -/*    vmx_restore_guest_msrs(v);*/
    4.18 -
    4.19 -    v->arch.hvm_vmx.vmxassist_enabled = data->vmxassist_enabled;
    4.20 +    v->arch.hvm_vmx.vmxassist_enabled = !(data->cr0 & X86_CR0_PE);
    4.21  
    4.22      hvm_set_guest_time(v, data->tsc);
    4.23  
     5.1 --- a/xen/include/asm-x86/hvm/vpt.h	Fri Feb 02 16:07:13 2007 +0000
     5.2 +++ b/xen/include/asm-x86/hvm/vpt.h	Mon Feb 05 11:38:22 2007 +0000
     5.3 @@ -66,7 +66,7 @@ struct periodic_time {
     5.4      u64 last_plt_gtime;         /* platform time when last IRQ is injected */
     5.5      struct timer timer;         /* ac_timer */
     5.6      time_cb *cb;
     5.7 -    void *priv;                 /* ponit back to platform time source */
     5.8 +    void *priv;                 /* point back to platform time source */
     5.9  };
    5.10  
    5.11  
    5.12 @@ -76,6 +76,8 @@ struct periodic_time {
    5.13  typedef struct PITState {
    5.14      /* Hardware state */
    5.15      struct hvm_hw_pit hw;
    5.16 +    /* Last time the counters read zero, for calcuating counter reads */
    5.17 +    int64_t count_load_time[3];
    5.18      /* irq handling */
    5.19      struct periodic_time pt[3];
    5.20  } PITState;
     6.1 --- a/xen/include/public/hvm/save.h	Fri Feb 02 16:07:13 2007 +0000
     6.2 +++ b/xen/include/public/hvm/save.h	Mon Feb 05 11:38:22 2007 +0000
     6.3 @@ -140,13 +140,10 @@ struct hvm_hw_cpu {
     6.4      uint64_t sysenter_esp;
     6.5      uint64_t sysenter_eip;
     6.6  
     6.7 -    /* msr for em64t */
     6.8 +    /* MSRs */
     6.9      uint64_t shadow_gs;
    6.10      uint64_t flags;
    6.11 -
    6.12 -    /* same size as VMX_MSR_COUNT */
    6.13      uint64_t msr_items[6];
    6.14 -    uint64_t vmxassist_enabled;
    6.15  
    6.16      /* guest's idea of what rdtsc() would return */
    6.17      uint64_t tsc;
    6.18 @@ -155,32 +152,6 @@ struct hvm_hw_cpu {
    6.19  DECLARE_HVM_SAVE_TYPE(CPU, 2, struct hvm_hw_cpu);
    6.20  
    6.21  
    6.22 -/* 
    6.23 - *  PIT
    6.24 - */
    6.25 -
    6.26 -struct hvm_hw_pit {
    6.27 -    struct hvm_hw_pit_channel {
    6.28 -        int64_t count_load_time;
    6.29 -        uint32_t count; /* can be 65536 */
    6.30 -        uint16_t latched_count;
    6.31 -        uint8_t count_latched;
    6.32 -        uint8_t status_latched;
    6.33 -        uint8_t status;
    6.34 -        uint8_t read_state;
    6.35 -        uint8_t write_state;
    6.36 -        uint8_t write_latch;
    6.37 -        uint8_t rw_mode;
    6.38 -        uint8_t mode;
    6.39 -        uint8_t bcd; /* not supported */
    6.40 -        uint8_t gate; /* timer start */
    6.41 -    } channels[3];  /* 3 x 24 bytes */
    6.42 -    uint32_t speaker_data_on;
    6.43 -};
    6.44 -
    6.45 -DECLARE_HVM_SAVE_TYPE(PIT, 3, struct hvm_hw_pit);
    6.46 -
    6.47 -
    6.48  /*
    6.49   * PIC
    6.50   */
    6.51 @@ -233,7 +204,7 @@ struct hvm_hw_vpic {
    6.52      uint8_t int_output;
    6.53  };
    6.54  
    6.55 -DECLARE_HVM_SAVE_TYPE(PIC, 4, struct hvm_hw_vpic);
    6.56 +DECLARE_HVM_SAVE_TYPE(PIC, 3, struct hvm_hw_vpic);
    6.57  
    6.58  
    6.59  /*
    6.60 @@ -275,7 +246,27 @@ struct hvm_hw_vioapic {
    6.61      } redirtbl[VIOAPIC_NUM_PINS];
    6.62  };
    6.63  
    6.64 -DECLARE_HVM_SAVE_TYPE(IOAPIC, 5, struct hvm_hw_vioapic);
    6.65 +DECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic);
    6.66 +
    6.67 +
    6.68 +/*
    6.69 + * LAPIC
    6.70 + */
    6.71 +
    6.72 +struct hvm_hw_lapic {
    6.73 +    uint64_t             apic_base_msr;
    6.74 +    uint32_t             disabled; /* VLAPIC_xx_DISABLED */
    6.75 +    uint32_t             timer_divisor;
    6.76 +};
    6.77 +
    6.78 +DECLARE_HVM_SAVE_TYPE(LAPIC, 5, struct hvm_hw_lapic);
    6.79 +
    6.80 +struct hvm_hw_lapic_regs {
    6.81 +    /* A 4k page of register state */
    6.82 +    uint8_t  data[0x400];
    6.83 +};
    6.84 +
    6.85 +DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 6, struct hvm_hw_lapic_regs);
    6.86  
    6.87  
    6.88  /*
    6.89 @@ -344,26 +335,32 @@ struct hvm_hw_irq {
    6.90      u8 round_robin_prev_vcpu;
    6.91  };
    6.92  
    6.93 -DECLARE_HVM_SAVE_TYPE(IRQ, 6, struct hvm_hw_irq);
    6.94 +DECLARE_HVM_SAVE_TYPE(IRQ, 7, struct hvm_hw_irq);
    6.95 +
    6.96  
    6.97 -/*
    6.98 - * LAPIC
    6.99 +/* 
   6.100 + *  PIT
   6.101   */
   6.102  
   6.103 -struct hvm_hw_lapic {
   6.104 -    uint64_t             apic_base_msr;
   6.105 -    uint32_t             disabled; /* VLAPIC_xx_DISABLED */
   6.106 -    uint32_t             timer_divisor;
   6.107 +struct hvm_hw_pit {
   6.108 +    struct hvm_hw_pit_channel {
   6.109 +        uint32_t count; /* can be 65536 */
   6.110 +        uint16_t latched_count;
   6.111 +        uint8_t count_latched;
   6.112 +        uint8_t status_latched;
   6.113 +        uint8_t status;
   6.114 +        uint8_t read_state;
   6.115 +        uint8_t write_state;
   6.116 +        uint8_t write_latch;
   6.117 +        uint8_t rw_mode;
   6.118 +        uint8_t mode;
   6.119 +        uint8_t bcd; /* not supported */
   6.120 +        uint8_t gate; /* timer start */
   6.121 +    } channels[3];  /* 3 x 16 bytes */
   6.122 +    uint32_t speaker_data_on;
   6.123  };
   6.124  
   6.125 -DECLARE_HVM_SAVE_TYPE(LAPIC, 7, struct hvm_hw_lapic);
   6.126 -
   6.127 -struct hvm_hw_lapic_regs {
   6.128 -    /* A 4k page of register state */
   6.129 -    uint8_t  data[0x400];
   6.130 -};
   6.131 -
   6.132 -DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 8, struct hvm_hw_lapic_regs);
   6.133 +DECLARE_HVM_SAVE_TYPE(PIT, 8, struct hvm_hw_pit);
   6.134  
   6.135  
   6.136  /*