diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-10-22 12:04:32 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-10-22 12:04:32 +0100 |
commit | bfd5a3fec25a6dd88425dff7c908127ef4b1dada (patch) | |
tree | ab0ea83f81ac7dbd523c8af817cda23b8035cf2b /xen/arch/x86/hvm/i8254.c | |
parent | c916f30553fc9df0959932324b056d316e603b3f (diff) | |
download | xen-bfd5a3fec25a6dd88425dff7c908127ef4b1dada.tar.gz xen-bfd5a3fec25a6dd88425dff7c908127ef4b1dada.tar.bz2 xen-bfd5a3fec25a6dd88425dff7c908127ef4b1dada.zip |
Port HPET device model to vpt timer subsystem
The current hpet implementation runs a one-shot xen timer for each
hpet timer whenever the main counter is enabled regardless of whether
or not the individual hpet timers are enabled. When the timer fires,
if it is enabled the interrupt is routed to the guest. If the hpet
timer is periodic, a new one-shot timer is set, for NOW()+period.
There are a number of problems with this the most significant is guest
time drift. Windows does not read the hardware clock to verify time,
it depends on timer interrupts firing at the expected interval. The
existing implementation queues a new one-shot timer each time it fires
and does not allow for a difference between NOW() and the time the
timer was expected to fire, causing drift. Also there is
no allowance for lost ticks. This modification changes HPET to use the
Virtual Platform Timer (VPT) and, for periodic timers, to use periodic
timers. The VPT ensures an interrupt is delivered to the guest for
each period that elapses, plus, its use of xen periodic timers ensures
no drift.
Signed-off-by: Peter Johnston <peter.johnston@citrix.com>
Diffstat (limited to 'xen/arch/x86/hvm/i8254.c')
-rw-r--r-- | xen/arch/x86/hvm/i8254.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/xen/arch/x86/hvm/i8254.c b/xen/arch/x86/hvm/i8254.c index 6fa955cad6..2babc2e93d 100644 --- a/xen/arch/x86/hvm/i8254.c +++ b/xen/arch/x86/hvm/i8254.c @@ -213,13 +213,13 @@ static void pit_load_count(PITState *pit, int channel, int val) case 2: case 3: /* Periodic timer. */ - create_periodic_time(v, &pit->pt0, period, 0, 0, pit_time_fired, + create_periodic_time(v, &pit->pt0, period, period, 0, pit_time_fired, &pit->count_load_time[channel]); break; case 1: case 4: /* One-shot timer. */ - create_periodic_time(v, &pit->pt0, period, 0, 1, pit_time_fired, + create_periodic_time(v, &pit->pt0, period, 0, 0, pit_time_fired, &pit->count_load_time[channel]); break; default: |