aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/i8254.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-10-22 12:04:32 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-10-22 12:04:32 +0100
commitbfd5a3fec25a6dd88425dff7c908127ef4b1dada (patch)
treeab0ea83f81ac7dbd523c8af817cda23b8035cf2b /xen/arch/x86/hvm/i8254.c
parentc916f30553fc9df0959932324b056d316e603b3f (diff)
downloadxen-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.c4
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: