ia64/xen-unstable
changeset 16245:b5a2cbca3930
hvm, x86: Allow virtual timer mode to be specified.
In HVM config file:
timer_mode=0 # Default: virtual time is delayed when timer ticks are
# missed dur to preemption
timer_mode=1 # Virtual time always equals wall time, even while missed
# ticks are pending
From: Haitao Shan <haitao.shan@intel.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
In HVM config file:
timer_mode=0 # Default: virtual time is delayed when timer ticks are
# missed dur to preemption
timer_mode=1 # Virtual time always equals wall time, even while missed
# ticks are pending
From: Haitao Shan <haitao.shan@intel.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author | Keir Fraser <keir@xensource.com> |
---|---|
date | Fri Oct 26 09:56:54 2007 +0100 (2007-10-26) |
parents | a9171b9c3fd8 |
children | fd09283562e2 |
files | tools/python/xen/xend/XendConfig.py tools/python/xen/xend/XendConstants.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xm/create.py tools/python/xen/xm/xenapi_create.py xen/arch/x86/domain.c xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/vlapic.c xen/arch/x86/hvm/vpt.c xen/include/asm-x86/hvm/hvm.h xen/include/asm-x86/hvm/vpt.h xen/include/public/hvm/params.h |
line diff
1.1 --- a/tools/python/xen/xend/XendConfig.py Thu Oct 25 17:27:57 2007 +0100 1.2 +++ b/tools/python/xen/xend/XendConfig.py Fri Oct 26 09:56:54 2007 +0100 1.3 @@ -127,7 +127,7 @@ XENAPI_PLATFORM_CFG = [ 'acpi', 'apic', 1.4 'fda', 'fdb', 'keymap', 'isa', 'localtime', 'monitor', 1.5 'nographic', 'pae', 'rtc_timeoffset', 'serial', 'sdl', 1.6 'soundhw','stdvga', 'usb', 'usbdevice', 'vnc', 1.7 - 'vncconsole', 'vncdisplay', 'vnclisten', 1.8 + 'vncconsole', 'vncdisplay', 'vnclisten', 'timer_mode', 1.9 'vncpasswd', 'vncunused', 'xauthority', 'pci', 'vhpt'] 1.10 1.11 # Xen API console 'other_config' keys.
2.1 --- a/tools/python/xen/xend/XendConstants.py Thu Oct 25 17:27:57 2007 +0100 2.2 +++ b/tools/python/xen/xend/XendConstants.py Fri Oct 26 09:56:54 2007 +0100 2.3 @@ -46,6 +46,7 @@ HVM_PARAM_BUFIOREQ_PFN = 6 2.4 HVM_PARAM_NVRAM_FD = 7 2.5 HVM_PARAM_VHPT_SIZE = 8 2.6 HVM_PARAM_BUFPIOREQ_PFN = 9 2.7 +HVM_PARAM_TIMER_MODE = 10 2.8 2.9 restart_modes = [ 2.10 "restart",
3.1 --- a/tools/python/xen/xend/XendDomainInfo.py Thu Oct 25 17:27:57 2007 +0100 3.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Fri Oct 26 09:56:54 2007 +0100 3.3 @@ -1596,6 +1596,11 @@ class XendDomainInfo: 3.4 3.5 self._recreateDom() 3.6 3.7 + # Set timer configration of domain 3.8 + if hvm: 3.9 + xc.hvm_set_param(self.domid, HVM_PARAM_TIMER_MODE, 3.10 + long(self.info["platform"].get("timer_mode"))) 3.11 + 3.12 # Set maximum number of vcpus in domain 3.13 xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max'])) 3.14
4.1 --- a/tools/python/xen/xm/create.py Thu Oct 25 17:27:57 2007 +0100 4.2 +++ b/tools/python/xen/xm/create.py Fri Oct 26 09:56:54 2007 +0100 4.3 @@ -194,6 +194,11 @@ gopts.var('pae', val='PAE', 4.4 fn=set_int, default=1, 4.5 use="Disable or enable PAE of HVM domain.") 4.6 4.7 +gopts.var('timer_mode', val='TIMER_MODE', 4.8 + fn=set_int, default=0, 4.9 + use="""Timer mode (0=delay virtual time when ticks are missed; 4.10 + 1=virtual time is always wallclock time.""") 4.11 + 4.12 gopts.var('acpi', val='ACPI', 4.13 fn=set_int, default=1, 4.14 use="Disable or enable ACPI of HVM domain.") 4.15 @@ -724,7 +729,7 @@ def configure_vifs(config_devs, vals): 4.16 def configure_hvm(config_image, vals): 4.17 """Create the config for HVM devices. 4.18 """ 4.19 - args = [ 'device_model', 'pae', 'vcpus', 'boot', 'fda', 'fdb', 4.20 + args = [ 'device_model', 'pae', 'vcpus', 'boot', 'fda', 'fdb', 'timer_mode', 4.21 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw', 4.22 'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten', 4.23 'sdl', 'display', 'xauthority', 'rtc_timeoffset', 'monitor',
5.1 --- a/tools/python/xen/xm/xenapi_create.py Thu Oct 25 17:27:57 2007 +0100 5.2 +++ b/tools/python/xen/xm/xenapi_create.py Fri Oct 26 09:56:54 2007 +0100 5.3 @@ -818,7 +818,7 @@ class sxp2xml: 5.4 5.5 5.6 def extract_platform(self, image, document): 5.7 - platform_keys = ['acpi', 'apic', 'pae', 'vhpt'] 5.8 + platform_keys = ['acpi', 'apic', 'pae', 'vhpt', 'timer_mode'] 5.9 5.10 def extract_platform_key(key): 5.11 platform = document.createElement("platform")
6.1 --- a/xen/arch/x86/domain.c Thu Oct 25 17:27:57 2007 +0100 6.2 +++ b/xen/arch/x86/domain.c Fri Oct 26 09:56:54 2007 +0100 6.3 @@ -1279,7 +1279,7 @@ void context_switch(struct vcpu *prev, s 6.4 local_irq_disable(); 6.5 6.6 if ( is_hvm_vcpu(prev) && !list_empty(&prev->arch.hvm_vcpu.tm_list) ) 6.7 - pt_freeze_time(prev); 6.8 + pt_save_timer(prev); 6.9 6.10 set_current(next); 6.11
7.1 --- a/xen/arch/x86/hvm/hvm.c Thu Oct 25 17:27:57 2007 +0100 7.2 +++ b/xen/arch/x86/hvm/hvm.c Fri Oct 26 09:56:54 2007 +0100 7.3 @@ -89,17 +89,17 @@ void hvm_enable(struct hvm_function_tabl 7.4 } 7.5 } 7.6 7.7 -void hvm_set_guest_time(struct vcpu *v, u64 gtime) 7.8 +void hvm_set_guest_tsc(struct vcpu *v, u64 guest_tsc) 7.9 { 7.10 u64 host_tsc; 7.11 7.12 rdtscll(host_tsc); 7.13 7.14 - v->arch.hvm_vcpu.cache_tsc_offset = gtime - host_tsc; 7.15 + v->arch.hvm_vcpu.cache_tsc_offset = guest_tsc - host_tsc; 7.16 hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset); 7.17 } 7.18 7.19 -u64 hvm_get_guest_time(struct vcpu *v) 7.20 +u64 hvm_get_guest_tsc(struct vcpu *v) 7.21 { 7.22 u64 host_tsc; 7.23 7.24 @@ -121,7 +121,7 @@ void hvm_do_resume(struct vcpu *v) 7.25 if ( !v->fpu_dirtied ) 7.26 hvm_funcs.stts(v); 7.27 7.28 - pt_thaw_time(v); 7.29 + pt_restore_timer(v); 7.30 7.31 /* NB. Optimised for common case (p->state == STATE_IOREQ_NONE). */ 7.32 p = &get_ioreq(v)->vp_ioreq; 7.33 @@ -1843,6 +1843,12 @@ long do_hvm_op(unsigned long op, XEN_GUE 7.34 hvm_set_callback_via(d, a.value); 7.35 hvm_latch_shinfo_size(d); 7.36 break; 7.37 + case HVM_PARAM_TIMER_MODE: 7.38 + rc = -EINVAL; 7.39 + if ( (a.value != HVMPTM_delay_for_missed_ticks) && 7.40 + (a.value != HVMPTM_no_delay_for_missed_ticks) ) 7.41 + goto param_fail; 7.42 + break; 7.43 } 7.44 d->arch.hvm_domain.params[a.index] = a.value; 7.45 rc = 0;
8.1 --- a/xen/arch/x86/hvm/vlapic.c Thu Oct 25 17:27:57 2007 +0100 8.2 +++ b/xen/arch/x86/hvm/vlapic.c Fri Oct 26 09:56:54 2007 +0100 8.3 @@ -430,7 +430,7 @@ static uint32_t vlapic_get_tmcct(struct 8.4 uint32_t tmcct, tmict = vlapic_get_reg(vlapic, APIC_TMICT); 8.5 uint64_t counter_passed; 8.6 8.7 - counter_passed = (hvm_get_guest_time(v) - vlapic->pt.last_plt_gtime) // TSC 8.8 + counter_passed = (hvm_get_guest_time(v) - vlapic->timer_last_update) // TSC 8.9 * 1000000000ULL / ticks_per_sec(v) // NS 8.10 / APIC_BUS_CYCLE_NS / vlapic->hw.timer_divisor; 8.11 tmcct = tmict - counter_passed; 8.12 @@ -531,6 +531,11 @@ static unsigned long vlapic_read(struct 8.13 return 0; 8.14 } 8.15 8.16 +void vlapic_pt_cb(struct vcpu *v, void *data) 8.17 +{ 8.18 + *(s_time_t *)data = hvm_get_guest_time(v); 8.19 +} 8.20 + 8.21 static void vlapic_write(struct vcpu *v, unsigned long address, 8.22 unsigned long len, unsigned long val) 8.23 { 8.24 @@ -660,7 +665,8 @@ static void vlapic_write(struct vcpu *v, 8.25 8.26 vlapic_set_reg(vlapic, APIC_TMICT, val); 8.27 create_periodic_time(current, &vlapic->pt, period, vlapic->pt.irq, 8.28 - !vlapic_lvtt_period(vlapic), NULL, vlapic); 8.29 + !vlapic_lvtt_period(vlapic), vlapic_pt_cb, 8.30 + &vlapic->timer_last_update); 8.31 8.32 HVM_DBG_LOG(DBG_LEVEL_VLAPIC, 8.33 "bus cycle is %uns, " 8.34 @@ -820,7 +826,8 @@ static void lapic_rearm(struct vlapic *s 8.35 8.36 s->pt.irq = lvtt & APIC_VECTOR_MASK; 8.37 create_periodic_time(vlapic_vcpu(s), &s->pt, period, s->pt.irq, 8.38 - !vlapic_lvtt_period(s), NULL, s); 8.39 + !vlapic_lvtt_period(s), vlapic_pt_cb, 8.40 + &s->timer_last_update); 8.41 8.42 printk("lapic_load to rearm the actimer:" 8.43 "bus cycle is %uns, "
9.1 --- a/xen/arch/x86/hvm/vpt.c Thu Oct 25 17:27:57 2007 +0100 9.2 +++ b/xen/arch/x86/hvm/vpt.c Fri Oct 26 09:56:54 2007 +0100 9.3 @@ -23,6 +23,12 @@ 9.4 #include <asm/hvm/vpt.h> 9.5 #include <asm/event.h> 9.6 9.7 +static int pt_support_time_frozen(struct domain *d) 9.8 +{ 9.9 + return (d->arch.hvm_domain.params[HVM_PARAM_TIMER_MODE] == 9.10 + HVMPTM_delay_for_missed_ticks); 9.11 +} 9.12 + 9.13 static void pt_lock(struct periodic_time *pt) 9.14 { 9.15 struct vcpu *v; 9.16 @@ -67,7 +73,12 @@ static void missed_ticks(struct periodic 9.17 pt->scheduled += missed_ticks * pt->period; 9.18 } 9.19 9.20 -void pt_freeze_time(struct vcpu *v) 9.21 +static __inline__ void pt_freeze_time(struct vcpu *v) 9.22 +{ 9.23 + v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); 9.24 +} 9.25 + 9.26 +void pt_save_timer(struct vcpu *v) 9.27 { 9.28 struct list_head *head = &v->arch.hvm_vcpu.tm_list; 9.29 struct periodic_time *pt; 9.30 @@ -77,32 +88,39 @@ void pt_freeze_time(struct vcpu *v) 9.31 9.32 spin_lock(&v->arch.hvm_vcpu.tm_lock); 9.33 9.34 - v->arch.hvm_vcpu.guest_time = hvm_get_guest_time(v); 9.35 - 9.36 list_for_each_entry ( pt, head, list ) 9.37 stop_timer(&pt->timer); 9.38 9.39 + if ( pt_support_time_frozen(v->domain) ) 9.40 + pt_freeze_time(v); 9.41 + 9.42 spin_unlock(&v->arch.hvm_vcpu.tm_lock); 9.43 } 9.44 9.45 -void pt_thaw_time(struct vcpu *v) 9.46 +static __inline__ void pt_thaw_time(struct vcpu *v) 9.47 +{ 9.48 + if ( v->arch.hvm_vcpu.guest_time ) 9.49 + { 9.50 + hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time); 9.51 + v->arch.hvm_vcpu.guest_time = 0; 9.52 + } 9.53 +} 9.54 + 9.55 +void pt_restore_timer(struct vcpu *v) 9.56 { 9.57 struct list_head *head = &v->arch.hvm_vcpu.tm_list; 9.58 struct periodic_time *pt; 9.59 9.60 spin_lock(&v->arch.hvm_vcpu.tm_lock); 9.61 9.62 - if ( v->arch.hvm_vcpu.guest_time ) 9.63 + list_for_each_entry ( pt, head, list ) 9.64 { 9.65 - hvm_set_guest_time(v, v->arch.hvm_vcpu.guest_time); 9.66 - v->arch.hvm_vcpu.guest_time = 0; 9.67 + missed_ticks(pt); 9.68 + set_timer(&pt->timer, pt->scheduled); 9.69 + } 9.70 9.71 - list_for_each_entry ( pt, head, list ) 9.72 - { 9.73 - missed_ticks(pt); 9.74 - set_timer(&pt->timer, pt->scheduled); 9.75 - } 9.76 - } 9.77 + if ( pt_support_time_frozen(v->domain) ) 9.78 + pt_thaw_time(v); 9.79 9.80 spin_unlock(&v->arch.hvm_vcpu.tm_lock); 9.81 } 9.82 @@ -218,7 +236,8 @@ void pt_intr_post(struct vcpu *v, struct 9.83 pt->last_plt_gtime += pt->period_cycles; 9.84 } 9.85 9.86 - if ( hvm_get_guest_time(v) < pt->last_plt_gtime ) 9.87 + if ( pt_support_time_frozen(v->domain) && 9.88 + hvm_get_guest_time(v) < pt->last_plt_gtime ) 9.89 hvm_set_guest_time(v, pt->last_plt_gtime); 9.90 9.91 cb = pt->cb;
10.1 --- a/xen/include/asm-x86/hvm/hvm.h Thu Oct 25 17:27:57 2007 +0100 10.2 +++ b/xen/include/asm-x86/hvm/hvm.h Fri Oct 26 09:56:54 2007 +0100 10.3 @@ -175,8 +175,10 @@ void hvm_vcpu_reset(struct vcpu *vcpu); 10.4 10.5 void hvm_send_assist_req(struct vcpu *v); 10.6 10.7 -void hvm_set_guest_time(struct vcpu *v, u64 gtime); 10.8 -u64 hvm_get_guest_time(struct vcpu *v); 10.9 +void hvm_set_guest_tsc(struct vcpu *v, u64 guest_tsc); 10.10 +u64 hvm_get_guest_tsc(struct vcpu *v); 10.11 +#define hvm_set_guest_time(vcpu, gtime) hvm_set_guest_tsc(vcpu, gtime) 10.12 +#define hvm_get_guest_time(vcpu) hvm_get_guest_tsc(vcpu) 10.13 10.14 #define hvm_paging_enabled(v) \ 10.15 (!!((v)->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PG))
11.1 --- a/xen/include/asm-x86/hvm/vpt.h Thu Oct 25 17:27:57 2007 +0100 11.2 +++ b/xen/include/asm-x86/hvm/vpt.h Fri Oct 26 09:56:54 2007 +0100 11.3 @@ -133,8 +133,8 @@ struct pl_time { /* platform time */ 11.4 11.5 #define ticks_per_sec(v) (v->domain->arch.hvm_domain.tsc_frequency) 11.6 11.7 -void pt_freeze_time(struct vcpu *v); 11.8 -void pt_thaw_time(struct vcpu *v); 11.9 +void pt_save_timer(struct vcpu *v); 11.10 +void pt_restore_timer(struct vcpu *v); 11.11 void pt_update_irq(struct vcpu *v); 11.12 void pt_intr_post(struct vcpu *v, struct hvm_intack intack); 11.13 void pt_reset(struct vcpu *v);
12.1 --- a/xen/include/public/hvm/params.h Thu Oct 25 17:27:57 2007 +0100 12.2 +++ b/xen/include/public/hvm/params.h Fri Oct 26 09:56:54 2007 +0100 12.3 @@ -54,9 +54,23 @@ 12.4 #define HVM_PARAM_NVRAM_FD 7 12.5 #define HVM_PARAM_VHPT_SIZE 8 12.6 #define HVM_PARAM_BUFPIOREQ_PFN 9 12.7 -#define HVM_NR_PARAMS 10 12.8 -#else 12.9 -#define HVM_NR_PARAMS 7 12.10 #endif 12.11 12.12 +/* 12.13 + * Set mode for virtual timers (currently x86 only): 12.14 + * delay_for_missed_ticks (default): 12.15 + * Do not advance a vcpu's time beyond the correct delivery time for 12.16 + * interrupts that have been missed due to preemption. Deliver missed 12.17 + * interrupts when the vcpu is rescheduled and advance the vcpu's virtual 12.18 + * time stepwise for each one. 12.19 + * no_delay_for_missed_ticks: 12.20 + * As above, missed interrupts are delivered, but guest time always tracks 12.21 + * wallclock (i.e., real) time while doing so. 12.22 + */ 12.23 +#define HVM_PARAM_TIMER_MODE 10 12.24 +#define HVMPTM_delay_for_missed_ticks 0 12.25 +#define HVMPTM_no_delay_for_missed_ticks 1 12.26 + 12.27 +#define HVM_NR_PARAMS 11 12.28 + 12.29 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */