[xen-unstable] x86: i8254 device model is shared between PV and HVM guests, so must

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen-unstable] x86: i8254 device model is shared between PV and HVM guests, so must

Xen patchbot-unstable
# HG changeset patch
# User Keir Fraser <[hidden email]>
# Date 1212172278 -3600
# Node ID 6e688d5a936bb22c7938c38cb26c8592544e97eb
# Parent  487dc63f95ff433eabb132253c5ff31cc178c00a
x86: i8254 device model is shared between PV and HVM guests, so must
take care not to run hvm_get_guest_time() on a PV VCPU. The spinlock
is not initialised and spin_lock() can thus spin forever.
Signed-off-by: Keir Fraser <[hidden email]>
---
 xen/arch/x86/hvm/i8254.c |   15 +++++++++------
 xen/arch/x86/hvm/vpt.c   |    3 +++
 2 files changed, 12 insertions(+), 6 deletions(-)

diff -r 487dc63f95ff -r 6e688d5a936b xen/arch/x86/hvm/i8254.c
--- a/xen/arch/x86/hvm/i8254.c Fri May 30 16:44:13 2008 +0100
+++ b/xen/arch/x86/hvm/i8254.c Fri May 30 19:31:18 2008 +0100
@@ -54,6 +54,9 @@ static int handle_speaker_io(
 static int handle_speaker_io(
     int dir, uint32_t port, uint32_t bytes, uint32_t *val);
 
+#define get_guest_time(v) \
+   (is_hvm_vcpu(v) ? hvm_get_guest_time(v) : (u64)get_s_time())
+
 /* Compute with 96 bit intermediate result: (a*b)/c */
 static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
@@ -87,7 +90,7 @@ static int pit_get_count(PITState *pit,
 
     ASSERT(spin_is_locked(&pit->lock));
 
-    d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel],
+    d = muldiv64(get_guest_time(v) - pit->count_load_time[channel],
                  PIT_FREQ, SYSTEM_TIME_HZ);
 
     switch ( c->mode )
@@ -118,7 +121,7 @@ static int pit_get_out(PITState *pit, in
 
     ASSERT(spin_is_locked(&pit->lock));
 
-    d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel],
+    d = muldiv64(get_guest_time(v) - pit->count_load_time[channel],
                  PIT_FREQ, SYSTEM_TIME_HZ);
 
     switch ( s->mode )
@@ -165,7 +168,7 @@ static void pit_set_gate(PITState *pit,
     case 3:
         /* Restart counting on rising edge. */
         if ( s->gate < val )
-            pit->count_load_time[channel] = hvm_get_guest_time(v);
+            pit->count_load_time[channel] = get_guest_time(v);
         break;
     }
 
@@ -181,7 +184,7 @@ static void pit_time_fired(struct vcpu *
 static void pit_time_fired(struct vcpu *v, void *priv)
 {
     uint64_t *count_load_time = priv;
-    *count_load_time = hvm_get_guest_time(v);
+    *count_load_time = get_guest_time(v);
 }
 
 static void pit_load_count(PITState *pit, int channel, int val)
@@ -198,7 +201,7 @@ static void pit_load_count(PITState *pit
     if ( v == NULL )
         pit->count_load_time[channel] = 0;
     else
-        pit->count_load_time[channel] = hvm_get_guest_time(v);
+        pit->count_load_time[channel] = get_guest_time(v);
     s->count = val;
     period = DIV_ROUND(val * SYSTEM_TIME_HZ, PIT_FREQ);
 
@@ -436,7 +439,7 @@ static int pit_load(struct domain *d, hv
      * time jitter here, but the wall-clock will have jumped massively, so
      * we hope the guest can handle it.
      */
-    pit->pt0.last_plt_gtime = hvm_get_guest_time(d->vcpu[0]);
+    pit->pt0.last_plt_gtime = get_guest_time(d->vcpu[0]);
     for ( i = 0; i < 3; i++ )
         pit_load_count(pit, i, pit->hw.channels[i].count);
 
diff -r 487dc63f95ff -r 6e688d5a936b xen/arch/x86/hvm/vpt.c
--- a/xen/arch/x86/hvm/vpt.c Fri May 30 16:44:13 2008 +0100
+++ b/xen/arch/x86/hvm/vpt.c Fri May 30 19:31:18 2008 +0100
@@ -39,6 +39,9 @@ u64 hvm_get_guest_time(struct vcpu *v)
     struct pl_time *pl = &v->domain->arch.hvm_domain.pl_time;
     u64 now;
 
+    /* Called from device models shared with PV guests. Be careful. */
+    ASSERT(is_hvm_vcpu(v));
+
     spin_lock(&pl->pl_time_lock);
     now = get_s_time() + pl->stime_offset;
     if ( (int64_t)(now - pl->last_guest_time) >= 0 )

_______________________________________________
Xen-changelog mailing list
[hidden email]
http://lists.xensource.com/xen-changelog