# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Date 1170675502 0
# Node ID 7a7509570af92be274d3c5ef5d224d07e591bab6
# Parent 01ec7dba9ff805a5c74a0318997b747d3e3e3327
[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@xxxxxxxxxxxxx>
---
xen/arch/x86/hvm/hpet.c | 3 +
xen/arch/x86/hvm/i8254.c | 26 +++++-----
xen/arch/x86/hvm/svm/svm.c | 1
xen/arch/x86/hvm/vmx/vmx.c | 7 --
xen/include/asm-x86/hvm/vpt.h | 4 +
xen/include/public/hvm/save.h | 101 ++++++++++++++++++++----------------------
6 files changed, 72 insertions(+), 70 deletions(-)
diff -r 01ec7dba9ff8 -r 7a7509570af9 xen/arch/x86/hvm/hpet.c
--- a/xen/arch/x86/hvm/hpet.c Fri Feb 02 16:07:13 2007 +0000
+++ b/xen/arch/x86/hvm/hpet.c Mon Feb 05 11:38:22 2007 +0000
@@ -383,6 +383,9 @@ static int hpet_save(struct domain *d, h
{
HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet;
+ /* Write the proper value into the main counter */
+ hp->hpet.mc64 = hp->mc_offset + hvm_get_guest_time(hp->vcpu);
+
/* Save the HPET registers */
return hvm_save_entry(HPET, 0, h, &hp->hpet);
}
diff -r 01ec7dba9ff8 -r 7a7509570af9 xen/arch/x86/hvm/i8254.c
--- a/xen/arch/x86/hvm/i8254.c Fri Feb 02 16:07:13 2007 +0000
+++ b/xen/arch/x86/hvm/i8254.c Mon Feb 05 11:38:22 2007 +0000
@@ -83,8 +83,8 @@ static int pit_get_count(PITState *s, in
struct hvm_hw_pit_channel *c = &s->hw.channels[channel];
struct periodic_time *pt = &s->pt[channel];
- d = muldiv64(hvm_get_guest_time(pt->vcpu)
- - c->count_load_time, PIT_FREQ, ticks_per_sec(pt->vcpu));
+ d = muldiv64(hvm_get_guest_time(pt->vcpu) - s->count_load_time[channel],
+ PIT_FREQ, ticks_per_sec(pt->vcpu));
switch(c->mode) {
case 0:
case 1:
@@ -110,7 +110,7 @@ int pit_get_out(PITState *pit, int chann
uint64_t d;
int out;
- d = muldiv64(current_time - s->count_load_time,
+ d = muldiv64(current_time - pit->count_load_time[channel],
PIT_FREQ, ticks_per_sec(pit->pt[channel].vcpu));
switch(s->mode) {
default:
@@ -153,7 +153,7 @@ void pit_set_gate(PITState *pit, int cha
case 5:
if (s->gate < val) {
/* restart counting on rising edge */
- s->count_load_time = hvm_get_guest_time(pt->vcpu);
+ pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
// pit_irq_timer_update(s, s->count_load_time);
}
break;
@@ -161,7 +161,7 @@ void pit_set_gate(PITState *pit, int cha
case 3:
if (s->gate < val) {
/* restart counting on rising edge */
- s->count_load_time = hvm_get_guest_time(pt->vcpu);
+ pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
// pit_irq_timer_update(s, s->count_load_time);
}
/* XXX: disable/enable counting */
@@ -177,8 +177,8 @@ int pit_get_gate(PITState *pit, int chan
void pit_time_fired(struct vcpu *v, void *priv)
{
- struct hvm_hw_pit_channel *s = priv;
- s->count_load_time = hvm_get_guest_time(v);
+ uint64_t *count_load_time = priv;
+ *count_load_time = hvm_get_guest_time(v);
}
static inline void pit_load_count(PITState *pit, int channel, int val)
@@ -190,7 +190,7 @@ static inline void pit_load_count(PITSta
if (val == 0)
val = 0x10000;
- s->count_load_time = hvm_get_guest_time(pt->vcpu);
+ pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
s->count = val;
period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ);
@@ -203,7 +203,7 @@ static inline void pit_load_count(PITSta
val,
period,
s->mode,
- (long long)s->count_load_time);
+ (long long)pit->count_load_time[channel]);
#endif
/* Choose a vcpu to set the timer on: current if appropriate else vcpu 0 */
@@ -216,11 +216,13 @@ static inline void pit_load_count(PITSta
switch (s->mode) {
case 2:
/* create periodic time */
- create_periodic_time(v, pt, period, 0, 0, pit_time_fired, s);
+ create_periodic_time(v, pt, period, 0, 0, pit_time_fired,
+ &pit->count_load_time[channel]);
break;
case 1:
/* create one shot time */
- create_periodic_time(v, pt, period, 0, 1, pit_time_fired, s);
+ create_periodic_time(v, pt, period, 0, 1, pit_time_fired,
+ &pit->count_load_time[channel]);
#ifdef DEBUG_PIT
printk("HVM_PIT: create one shot time.\n");
#endif
@@ -387,7 +389,7 @@ static void pit_info(PITState *pit)
printk("pit 0x%x.\n", s->mode);
printk("pit 0x%x.\n", s->bcd);
printk("pit 0x%x.\n", s->gate);
- printk("pit %"PRId64"\n", s->count_load_time);
+ printk("pit %"PRId64"\n", pit->count_load_time[i]);
pt = &pit->pt[i];
if (pt) {
diff -r 01ec7dba9ff8 -r 7a7509570af9 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Fri Feb 02 16:07:13 2007 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c Mon Feb 05 11:38:22 2007 +0000
@@ -591,6 +591,7 @@ void svm_load_cpu_state(struct vcpu *v,
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+ vmcb->kerngsbase = data->shadow_gs;
/* MSR_LSTAR, MSR_STAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_EFER */
vmcb->lstar = data->msr_items[0];
vmcb->star = data->msr_items[1];
diff -r 01ec7dba9ff8 -r 7a7509570af9 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Fri Feb 02 16:07:13 2007 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c Mon Feb 05 11:38:22 2007 +0000
@@ -588,7 +588,7 @@ void vmx_save_cpu_state(struct vcpu *v,
int i = 0;
data->shadow_gs = guest_state->shadow_gs;
- data->vmxassist_enabled = v->arch.hvm_vmx.vmxassist_enabled;
+
/* save msrs */
data->flags = guest_flags;
for (i = 0; i < VMX_MSR_COUNT; i++)
@@ -611,10 +611,7 @@ void vmx_load_cpu_state(struct vcpu *v,
guest_state->shadow_gs = data->shadow_gs;
- /*XXX:no need to restore msrs, current!=vcpu as not called by
arch_vmx_do_launch */
-/* vmx_restore_guest_msrs(v);*/
-
- v->arch.hvm_vmx.vmxassist_enabled = data->vmxassist_enabled;
+ v->arch.hvm_vmx.vmxassist_enabled = !(data->cr0 & X86_CR0_PE);
hvm_set_guest_time(v, data->tsc);
diff -r 01ec7dba9ff8 -r 7a7509570af9 xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h Fri Feb 02 16:07:13 2007 +0000
+++ b/xen/include/asm-x86/hvm/vpt.h Mon Feb 05 11:38:22 2007 +0000
@@ -66,7 +66,7 @@ struct periodic_time {
u64 last_plt_gtime; /* platform time when last IRQ is injected */
struct timer timer; /* ac_timer */
time_cb *cb;
- void *priv; /* ponit back to platform time source */
+ void *priv; /* point back to platform time source */
};
@@ -76,6 +76,8 @@ typedef struct PITState {
typedef struct PITState {
/* Hardware state */
struct hvm_hw_pit hw;
+ /* Last time the counters read zero, for calcuating counter reads */
+ int64_t count_load_time[3];
/* irq handling */
struct periodic_time pt[3];
} PITState;
diff -r 01ec7dba9ff8 -r 7a7509570af9 xen/include/public/hvm/save.h
--- a/xen/include/public/hvm/save.h Fri Feb 02 16:07:13 2007 +0000
+++ b/xen/include/public/hvm/save.h Mon Feb 05 11:38:22 2007 +0000
@@ -140,45 +140,16 @@ struct hvm_hw_cpu {
uint64_t sysenter_esp;
uint64_t sysenter_eip;
- /* msr for em64t */
+ /* MSRs */
uint64_t shadow_gs;
uint64_t flags;
-
- /* same size as VMX_MSR_COUNT */
uint64_t msr_items[6];
- uint64_t vmxassist_enabled;
/* guest's idea of what rdtsc() would return */
uint64_t tsc;
};
DECLARE_HVM_SAVE_TYPE(CPU, 2, struct hvm_hw_cpu);
-
-
-/*
- * PIT
- */
-
-struct hvm_hw_pit {
- struct hvm_hw_pit_channel {
- int64_t count_load_time;
- uint32_t count; /* can be 65536 */
- uint16_t latched_count;
- uint8_t count_latched;
- uint8_t status_latched;
- uint8_t status;
- uint8_t read_state;
- uint8_t write_state;
- uint8_t write_latch;
- uint8_t rw_mode;
- uint8_t mode;
- uint8_t bcd; /* not supported */
- uint8_t gate; /* timer start */
- } channels[3]; /* 3 x 24 bytes */
- uint32_t speaker_data_on;
-};
-
-DECLARE_HVM_SAVE_TYPE(PIT, 3, struct hvm_hw_pit);
/*
@@ -233,7 +204,7 @@ struct hvm_hw_vpic {
uint8_t int_output;
};
-DECLARE_HVM_SAVE_TYPE(PIC, 4, struct hvm_hw_vpic);
+DECLARE_HVM_SAVE_TYPE(PIC, 3, struct hvm_hw_vpic);
/*
@@ -275,7 +246,27 @@ struct hvm_hw_vioapic {
} redirtbl[VIOAPIC_NUM_PINS];
};
-DECLARE_HVM_SAVE_TYPE(IOAPIC, 5, struct hvm_hw_vioapic);
+DECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic);
+
+
+/*
+ * LAPIC
+ */
+
+struct hvm_hw_lapic {
+ uint64_t apic_base_msr;
+ uint32_t disabled; /* VLAPIC_xx_DISABLED */
+ uint32_t timer_divisor;
+};
+
+DECLARE_HVM_SAVE_TYPE(LAPIC, 5, struct hvm_hw_lapic);
+
+struct hvm_hw_lapic_regs {
+ /* A 4k page of register state */
+ uint8_t data[0x400];
+};
+
+DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 6, struct hvm_hw_lapic_regs);
/*
@@ -344,26 +335,32 @@ struct hvm_hw_irq {
u8 round_robin_prev_vcpu;
};
-DECLARE_HVM_SAVE_TYPE(IRQ, 6, struct hvm_hw_irq);
-
-/*
- * LAPIC
- */
-
-struct hvm_hw_lapic {
- uint64_t apic_base_msr;
- uint32_t disabled; /* VLAPIC_xx_DISABLED */
- uint32_t timer_divisor;
-};
-
-DECLARE_HVM_SAVE_TYPE(LAPIC, 7, struct hvm_hw_lapic);
-
-struct hvm_hw_lapic_regs {
- /* A 4k page of register state */
- uint8_t data[0x400];
-};
-
-DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 8, struct hvm_hw_lapic_regs);
+DECLARE_HVM_SAVE_TYPE(IRQ, 7, struct hvm_hw_irq);
+
+
+/*
+ * PIT
+ */
+
+struct hvm_hw_pit {
+ struct hvm_hw_pit_channel {
+ uint32_t count; /* can be 65536 */
+ uint16_t latched_count;
+ uint8_t count_latched;
+ uint8_t status_latched;
+ uint8_t status;
+ uint8_t read_state;
+ uint8_t write_state;
+ uint8_t write_latch;
+ uint8_t rw_mode;
+ uint8_t mode;
+ uint8_t bcd; /* not supported */
+ uint8_t gate; /* timer start */
+ } channels[3]; /* 3 x 16 bytes */
+ uint32_t speaker_data_on;
+};
+
+DECLARE_HVM_SAVE_TYPE(PIT, 8, struct hvm_hw_pit);
/*
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|