diff -aru ../xen-2.0.7-orig/xen/arch/x86/domain.c xen/arch/x86/domain.c --- ../xen-2.0.7-orig/xen/arch/x86/domain.c 2005-08-03 16:57:58.000000000 -0700 +++ xen/arch/x86/domain.c 2005-09-22 18:18:47.000000000 -0700 @@ -876,6 +876,9 @@ l1start = l1tab = (l1_pgentry_t *)l2_pgentry_to_phys(*l2tab); } + /* DG: setup tdf in shared_info */ + p->shared_info->time_dilation_factor = 1; + /* Mask all upcalls... */ for ( i = 0; i < MAX_VIRT_CPUS; i++ ) p->shared_info->vcpu_data[i].evtchn_upcall_mask = 1; diff -aru ../xen-2.0.7-orig/xen/arch/x86/time.c xen/arch/x86/time.c --- ../xen-2.0.7-orig/xen/arch/x86/time.c 2005-08-03 16:57:58.000000000 -0700 +++ xen/arch/x86/time.c 2005-09-22 18:18:47.000000000 -0700 @@ -33,6 +33,9 @@ #include #include +/* DG: include for do_div used in update_dom_time */ +#include + /* GLOBAL */ unsigned long cpu_khz; /* Detected as we calibrate the TSC */ unsigned long ticks_per_usec; /* TSC ticks per microsecond. */ @@ -280,9 +283,23 @@ { shared_info_t *si = d->shared_info; unsigned long flags; + u32 tdf = si->time_dilation_factor; + if(tdf == 0 || tdf > 1000) + { + printk("update_dom_time: OOPS! bad tdf %d for domain %d\n", tdf, d->id); + } if ( d->last_propagated_timestamp == full_tsc_irq ) return 0; + + /* we don't need the lock for these assignments */ + u32 dilated_cpu_freq = cpu_freq; + u32 dilated_wc_sec = wc_sec/tdf; + u32 dilated_wc_usec = wc_usec/tdf; + u64 dilated_tsc_timestamp = full_tsc_irq; + u64 dilated_system_time = stime_irq; + if(tdf > 1) + do_div(dilated_system_time, tdf); read_lock_irqsave(&time_lock, flags); @@ -290,12 +307,18 @@ si->time_version1++; wmb(); - - si->cpu_freq = cpu_freq; - si->tsc_timestamp = full_tsc_irq; - si->system_time = stime_irq; - si->wc_sec = wc_sec; - si->wc_usec = wc_usec; + + si->cpu_freq = dilated_cpu_freq; + si->tsc_timestamp = dilated_tsc_timestamp; + si->system_time = dilated_system_time; + si->wc_sec = dilated_wc_sec; + si->wc_usec = dilated_wc_usec; + + /*si->cpu_freq = cpu_freq;*/ + /*si->tsc_timestamp = full_tsc_irq;*/ + /*si->system_time = stime_irq;*/ + /*si->wc_sec = wc_sec;*/ + /*si->wc_usec = wc_usec;*/ wmb(); si->time_version2++; diff -aru ../xen-2.0.7-orig/xen/common/dom0_ops.c xen/common/dom0_ops.c --- ../xen-2.0.7-orig/xen/common/dom0_ops.c 2005-08-03 16:57:58.000000000 -0700 +++ xen/common/dom0_ops.c 2005-09-22 18:18:47.000000000 -0700 @@ -209,6 +209,11 @@ break; } + /* DG: setup tdf */ + printk("Creating domain %d with TDF %d\n", d->id, op->u.createdomain.tdf); + /* copied to shared_info inside final_guestsetup */ + d->time_dilation_factor = op->u.createdomain.tdf; + ret = 0; op->u.createdomain.domain = d->id; diff -aru ../xen-2.0.7-orig/xen/common/domain.c xen/common/domain.c --- ../xen-2.0.7-orig/xen/common/domain.c 2005-08-03 16:57:58.000000000 -0700 +++ xen/common/domain.c 2005-09-22 18:18:47.000000000 -0700 @@ -278,6 +278,9 @@ if ( (rc = arch_final_setup_guestos(p,c)) != 0 ) goto out; + /* DG: setup tdf in shared_info */ + p->shared_info->time_dilation_factor = p->time_dilation_factor; + set_bit(DF_CONSTRUCTED, &p->flags); out: diff -aru ../xen-2.0.7-orig/xen/common/schedule.c xen/common/schedule.c --- ../xen-2.0.7-orig/xen/common/schedule.c 2005-08-03 16:57:58.000000000 -0700 +++ xen/common/schedule.c 2005-09-22 18:18:47.000000000 -0700 @@ -429,15 +429,29 @@ static void t_timer_fn(unsigned long unused) { struct domain *d = current; - + int delay; + TRACE_0D(TRC_SCHED_T_TIMER_FN); + /* DG: originally Xen had a fixed timer interrupt frequency. HZ interrupts + * every 1s that is one interrupt every 1000/HZ ms, which is 10 for HZ = 100 + * For HZ = 1000, this becomes 1 */ + if(d->id == 0 || is_idle_task(d)) + { + delay = 1; + } + else + { + delay = d->shared_info->time_dilation_factor * 1; + } + if ( !is_idle_task(d) && update_dom_time(d) ) send_guest_virq(d, VIRQ_TIMER); page_scrub_schedule_work(); - t_timer[d->processor].expires = NOW() + MILLISECS(10); + /*t_timer[d->processor].expires = NOW() + MILLISECS(10);*/ + t_timer[d->processor].expires = NOW() + MILLISECS(delay); add_ac_timer(&t_timer[d->processor]); } diff -aru ../xen-2.0.7-orig/xen/include/asm-x86/config.h xen/include/asm-x86/config.h --- ../xen-2.0.7-orig/xen/include/asm-x86/config.h 2005-08-03 16:57:58.000000000 -0700 +++ xen/include/asm-x86/config.h 2005-09-22 18:18:47.000000000 -0700 @@ -46,7 +46,8 @@ #define CONFIG_XEN_ATTENTION_KEY 1 -#define HZ 100 +/* DG: originally Xen used HZ = 100 */ +#define HZ 1000 /* * Just to keep compiler happy. diff -aru ../xen-2.0.7-orig/xen/include/public/dom0_ops.h xen/include/public/dom0_ops.h --- ../xen-2.0.7-orig/xen/include/public/dom0_ops.h 2005-08-03 16:57:58.000000000 -0700 +++ xen/include/public/dom0_ops.h 2005-09-22 18:19:53.000000000 -0700 @@ -53,6 +53,9 @@ MEMORY_PADDING; u32 cpu; /* 8 */ u32 __pad0; /* 12 */ + /* DG: tdf */ + u32 tdf; + u32 __pad2; /* IN/OUT parameters. */ /* If 0, domain is allocated. If non-zero use it unless in use. */ domid_t domain; /* 16 */ diff -aru ../xen-2.0.7-orig/xen/include/public/xen.h xen/include/public/xen.h --- ../xen-2.0.7-orig/xen/include/public/xen.h 2005-08-03 16:57:58.000000000 -0700 +++ xen/include/public/xen.h 2005-09-22 18:19:53.000000000 -0700 @@ -368,6 +368,10 @@ u64 wall_timeout; /* 312 */ u64 domain_timeout; /* 320 */ + /* DG: this is needed because each guest needs to somehow know + * its own time dilation factor */ + u32 time_dilation_factor; /* 328 */ + arch_shared_info_t arch; } PACKED shared_info_t; diff -aru ../xen-2.0.7-orig/xen/include/xen/sched.h xen/include/xen/sched.h --- ../xen-2.0.7-orig/xen/include/xen/sched.h 2005-08-03 16:57:58.000000000 -0700 +++ xen/include/xen/sched.h 2005-09-22 18:18:47.000000000 -0700 @@ -64,6 +64,9 @@ domid_t id; s_time_t create_time; + /* DG: tdf */ + u32 time_dilation_factor; + spinlock_t page_alloc_lock; /* protects all the following fields */ struct list_head page_list; /* linked list, of size tot_pages */ struct list_head xenpage_list; /* linked list, of size xenheap_pages */