[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] hvm: Simplify timer<->vcpu/domain conversion in RTC and PIT timer



# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1181900191 -3600
# Node ID ba61ec7df6321221450dbe512019c43468891a02
# Parent  9a915873be8c5672bf56fd71117a9eb9e7c69fe6
hvm: Simplify timer<->vcpu/domain conversion in RTC and PIT timer
models. These timers are always bound to vcpu0, where a specific vcpu
matters.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/i8254.c |  123 +++++++++++++++++++++--------------------------
 xen/arch/x86/hvm/rtc.c   |   74 +++++++++++++++-------------
 2 files changed, 96 insertions(+), 101 deletions(-)

diff -r 9a915873be8c -r ba61ec7df632 xen/arch/x86/hvm/i8254.c
--- a/xen/arch/x86/hvm/i8254.c  Fri Jun 15 10:01:32 2007 +0100
+++ b/xen/arch/x86/hvm/i8254.c  Fri Jun 15 10:36:31 2007 +0100
@@ -37,6 +37,12 @@
 #include <asm/hvm/vpt.h>
 #include <asm/current.h>
 
+#define domain_vpit(d)   (&(d)->arch.hvm_domain.pl_time.vpit)
+#define vcpu_vpit(vcpu)  (domain_vpit((vcpu)->domain))
+#define vpit_domain(pit) (container_of((pit), struct domain, \
+                                       arch.hvm_domain.pl_time.vpit))
+#define vpit_vcpu(pit)   (vpit_domain(pit)->vcpu[0])
+
 #define RW_STATE_LSB 1
 #define RW_STATE_MSB 2
 #define RW_STATE_WORD0 3
@@ -45,8 +51,8 @@ static int handle_pit_io(ioreq_t *p);
 static int handle_pit_io(ioreq_t *p);
 static int handle_speaker_io(ioreq_t *p);
 
-/* compute with 96 bit intermediate result: (a*b)/c */
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
+/* Compute with 96 bit intermediate result: (a*b)/c */
+static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
 {
     union {
         uint64_t ll;
@@ -69,15 +75,16 @@ uint64_t muldiv64(uint64_t a, uint32_t b
     return res.ll;
 }
 
-static int pit_get_count(PITState *s, int channel)
+static int pit_get_count(PITState *pit, int channel)
 {
     uint64_t d;
     int  counter;
-    struct hvm_hw_pit_channel *c = &s->hw.channels[channel];
-    struct periodic_time *pt = &s->pt[channel];
-
-    d = muldiv64(hvm_get_guest_time(pt->vcpu) - s->count_load_time[channel],
-                 PIT_FREQ, ticks_per_sec(pt->vcpu));
+    struct hvm_hw_pit_channel *c = &pit->hw.channels[channel];
+    struct vcpu *v = vpit_vcpu(pit);
+
+    d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel],
+                 PIT_FREQ, ticks_per_sec(v));
+
     switch ( c->mode )
     {
     case 0:
@@ -97,15 +104,15 @@ static int pit_get_count(PITState *s, in
     return counter;
 }
 
-int pit_get_out(PITState *pit, int channel)
+static int pit_get_out(PITState *pit, int channel)
 {
     struct hvm_hw_pit_channel *s = &pit->hw.channels[channel];
-    uint64_t d, current_time;
+    uint64_t d;
     int out;
-
-    current_time = hvm_get_guest_time(pit->pt[channel].vcpu);
-    d = muldiv64(current_time - pit->count_load_time[channel], 
-                 PIT_FREQ, ticks_per_sec(pit->pt[channel].vcpu));
+    struct vcpu *v = vpit_vcpu(pit);
+
+    d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel], 
+                 PIT_FREQ, ticks_per_sec(v));
 
     switch ( s->mode )
     {
@@ -131,11 +138,10 @@ int pit_get_out(PITState *pit, int chann
     return out;
 }
 
-/* val must be 0 or 1 */
-void pit_set_gate(PITState *pit, int channel, int val)
+static void pit_set_gate(PITState *pit, int channel, int val)
 {
     struct hvm_hw_pit_channel *s = &pit->hw.channels[channel];
-    struct periodic_time *pt = &pit->pt[channel];
+    struct vcpu *v = vpit_vcpu(pit);
 
     switch ( s->mode )
     {
@@ -150,7 +156,7 @@ void pit_set_gate(PITState *pit, int cha
     case 3:
         /* Restart counting on rising edge. */
         if ( s->gate < val )
-            pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu);
+            pit->count_load_time[channel] = hvm_get_guest_time(v);
         break;
     }
 
@@ -162,7 +168,7 @@ int pit_get_gate(PITState *pit, int chan
     return pit->hw.channels[channel].gate;
 }
 
-void pit_time_fired(struct vcpu *v, void *priv)
+static void pit_time_fired(struct vcpu *v, void *priv)
 {
     uint64_t *count_load_time = priv;
     *count_load_time = hvm_get_guest_time(v);
@@ -173,9 +179,7 @@ static void pit_load_count(PITState *pit
     u32 period;
     struct hvm_hw_pit_channel *s = &pit->hw.channels[channel];
     struct periodic_time *pt = &pit->pt[channel];
-    struct domain *d = container_of(pit, struct domain,
-                                    arch.hvm_domain.pl_time.vpit);
-    struct vcpu *v;
+    struct vcpu *v = vpit_vcpu(pit);
 
     if ( val == 0 )
         val = 0x10000;
@@ -184,14 +188,8 @@ static void pit_load_count(PITState *pit
     s->count = val;
     period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ);
 
-    if ( !is_hvm_domain(d) || (channel != 0) )
+    if ( (v == NULL) || !is_hvm_vcpu(v) || (channel != 0) )
         return;
-
-    /* Choose a vcpu to set the timer on: current if appropriate else vcpu 0 */
-    if ( pit == &current->domain->arch.hvm_domain.pl_time.vpit )
-        v = current;
-    else 
-        v = d->vcpu[0];
 
     switch ( s->mode )
     {
@@ -235,9 +233,8 @@ static void pit_latch_status(PITState *s
     }
 }
 
-static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
-    PITState *pit = opaque;
+static void pit_ioport_write(struct PITState *pit, uint32_t addr, uint32_t val)
+{
     int channel, access;
     struct hvm_hw_pit_channel *s;
 
@@ -309,9 +306,8 @@ static void pit_ioport_write(void *opaqu
     }
 }
 
-static uint32_t pit_ioport_read(void *opaque, uint32_t addr)
-{
-    PITState *pit = opaque;
+static uint32_t pit_ioport_read(struct PITState *pit, uint32_t addr)
+{
     int ret, count;
     struct hvm_hw_pit_channel *s;
     
@@ -371,7 +367,7 @@ static uint32_t pit_ioport_read(void *op
     return ret;
 }
 
-void pit_stop_channel0_irq(PITState * pit)
+void pit_stop_channel0_irq(PITState *pit)
 {
     destroy_periodic_time(&pit->pt[0]);
 }
@@ -425,7 +421,7 @@ static void pit_info(PITState *pit)
 
 static int pit_save(struct domain *d, hvm_domain_context_t *h)
 {
-    PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
+    PITState *pit = domain_vpit(d);
     
     pit_info(pit);
 
@@ -435,7 +431,7 @@ static int pit_save(struct domain *d, hv
 
 static int pit_load(struct domain *d, hvm_domain_context_t *h)
 {
-    PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
+    PITState *pit = domain_vpit(d);
     int i;
 
     /* Restore the PIT hardware state */
@@ -457,26 +453,12 @@ static int pit_load(struct domain *d, hv
 
 HVM_REGISTER_SAVE_RESTORE(PIT, pit_save, pit_load, 1, HVMSR_PER_DOM);
 
-static void pit_reset(void *opaque)
-{
-    PITState *pit = opaque;
+void pit_init(struct vcpu *v, unsigned long cpu_khz)
+{
+    PITState *pit = vcpu_vpit(v);
+    struct periodic_time *pt;
     struct hvm_hw_pit_channel *s;
     int i;
-
-    for ( i = 0; i < 3; i++ )
-    {
-        s = &pit->hw.channels[i];
-        destroy_periodic_time(&pit->pt[i]);
-        s->mode = 0xff; /* the init mode */
-        s->gate = (i != 2);
-        pit_load_count(pit, i, 0);
-    }
-}
-
-void pit_init(struct vcpu *v, unsigned long cpu_khz)
-{
-    PITState *pit = &v->domain->arch.hvm_domain.pl_time.vpit;
-    struct periodic_time *pt;
 
     pt = &pit->pt[0];  
     pt[0].vcpu = v;
@@ -487,20 +469,26 @@ void pit_init(struct vcpu *v, unsigned l
     /* register the speaker port */
     register_portio_handler(v->domain, 0x61, 1, handle_speaker_io);
     ticks_per_sec(v) = cpu_khz * (int64_t)1000;
-    pit_reset(pit);
+
+    for ( i = 0; i < 3; i++ )
+    {
+        s = &pit->hw.channels[i];
+        s->mode = 0xff; /* the init mode */
+        s->gate = (i != 2);
+        pit_load_count(pit, i, 0);
+    }
 }
 
 void pit_deinit(struct domain *d)
 {
-    PITState *pit = &d->arch.hvm_domain.pl_time.vpit;
+    PITState *pit = domain_vpit(d);
     destroy_periodic_time(&pit->pt[0]);
 }
 
 /* the intercept action for PIT DM retval:0--not handled; 1--handled */  
 static int handle_pit_io(ioreq_t *p)
 {
-    struct vcpu *v = current;
-    struct PITState *vpit = &(v->domain->arch.hvm_domain.pl_time.vpit);
+    struct PITState *vpit = vcpu_vpit(current);
 
     if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) )
     {
@@ -523,16 +511,16 @@ static int handle_pit_io(ioreq_t *p)
     return 1;
 }
 
-static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-{
-    PITState *pit = opaque;
+static void speaker_ioport_write(
+    struct PITState *pit, uint32_t addr, uint32_t val)
+{
     pit->hw.speaker_data_on = (val >> 1) & 1;
     pit_set_gate(pit, 2, val & 1);
 }
 
-static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
-{
-    PITState *pit = opaque;
+static uint32_t speaker_ioport_read(
+    struct PITState *pit, uint32_t addr)
+{
     /* Refresh clock toggles at about 15us. We approximate as 2^14ns. */
     unsigned int refresh_clock = ((unsigned int)NOW() >> 14) & 1;
     return ((pit->hw.speaker_data_on << 1) | pit_get_gate(pit, 2) |
@@ -541,8 +529,7 @@ static uint32_t speaker_ioport_read(void
 
 static int handle_speaker_io(ioreq_t *p)
 {
-    struct vcpu *v = current;
-    struct PITState *vpit = &(v->domain->arch.hvm_domain.pl_time.vpit);
+    struct PITState *vpit = vcpu_vpit(current);
 
     if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) )
     {
diff -r 9a915873be8c -r ba61ec7df632 xen/arch/x86/hvm/rtc.c
--- a/xen/arch/x86/hvm/rtc.c    Fri Jun 15 10:01:32 2007 +0100
+++ b/xen/arch/x86/hvm/rtc.c    Fri Jun 15 10:36:31 2007 +0100
@@ -28,6 +28,12 @@
 #include <asm/hvm/support.h>
 #include <asm/current.h>
 
+#define domain_vrtc(d)   (&(d)->arch.hvm_domain.pl_time.vrtc)
+#define vcpu_vrtc(vcpu)  (domain_vrtc((vcpu)->domain))
+#define vrtc_domain(rtc) (container_of((rtc), struct domain, \
+                                       arch.hvm_domain.pl_time.vrtc))
+#define vrtc_vcpu(rtc)   (vrtc_domain(rtc)->vcpu[0])
+
 void rtc_periodic_cb(struct vcpu *v, void *opaque)
 {
     RTCState *s = opaque;
@@ -39,15 +45,15 @@ int is_rtc_periodic_irq(void *opaque)
     RTCState *s = opaque;
 
     return !(s->hw.cmos_data[RTC_REG_C] & RTC_AF || 
-           s->hw.cmos_data[RTC_REG_C] & RTC_UF);
+             s->hw.cmos_data[RTC_REG_C] & RTC_UF);
 }
 
 /* Enable/configure/disable the periodic timer based on the RTC_PIE and
  * RTC_RATE_SELECT settings */
-static void rtc_timer_update(RTCState *s, struct vcpu *v)
-{
-    int period_code; 
-    int period;
+static void rtc_timer_update(RTCState *s)
+{
+    int period_code, period;
+    struct vcpu *v = vrtc_vcpu(s);
 
     period_code = s->hw.cmos_data[RTC_REG_A] & RTC_RATE_SELECT;
     if ( (period_code != 0) && (s->hw.cmos_data[RTC_REG_B] & RTC_PIE) )
@@ -104,7 +110,7 @@ static int rtc_ioport_write(void *opaque
         /* UIP bit is read only */
         s->hw.cmos_data[RTC_REG_A] = (data & ~RTC_UIP) |
             (s->hw.cmos_data[RTC_REG_A] & RTC_UIP);
-        rtc_timer_update(s, current);
+        rtc_timer_update(s);
         break;
     case RTC_REG_B:
         if ( data & RTC_SET )
@@ -120,7 +126,7 @@ static int rtc_ioport_write(void *opaque
                 rtc_set_time(s);
         }
         s->hw.cmos_data[RTC_REG_B] = data;
-        rtc_timer_update(s, current);
+        rtc_timer_update(s);
         break;
     case RTC_REG_C:
     case RTC_REG_D:
@@ -174,11 +180,12 @@ static void rtc_copy_date(RTCState *s)
 static void rtc_copy_date(RTCState *s)
 {
     const struct tm *tm = &s->current_tm;
-
-    if ( s->time_offset_seconds != s->pt.vcpu->domain->time_offset_seconds )
-    {
-        s->current_tm = gmtime(get_localtime(s->pt.vcpu->domain));
-        s->time_offset_seconds = s->pt.vcpu->domain->time_offset_seconds;
+    struct domain *d = vrtc_domain(s);
+
+    if ( s->time_offset_seconds != d->time_offset_seconds )
+    {
+        s->current_tm = gmtime(get_localtime(d));
+        s->time_offset_seconds = d->time_offset_seconds;
     }
 
     s->hw.cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
@@ -222,11 +229,12 @@ static void rtc_next_second(RTCState *s)
 {
     struct tm *tm = &s->current_tm;
     int days_in_month;
-
-    if ( s->time_offset_seconds != s->pt.vcpu->domain->time_offset_seconds )
-    {
-        s->current_tm = gmtime(get_localtime(s->pt.vcpu->domain));
-        s->time_offset_seconds = s->pt.vcpu->domain->time_offset_seconds;
+    struct domain *d = vrtc_domain(s);
+
+    if ( s->time_offset_seconds != d->time_offset_seconds )
+    {
+        s->current_tm = gmtime(get_localtime(d));
+        s->time_offset_seconds = d->time_offset_seconds;
     }
 
     tm->tm_sec++;
@@ -292,6 +300,7 @@ static void rtc_update_second2(void *opa
 static void rtc_update_second2(void *opaque)
 {
     RTCState *s = opaque;
+    struct domain *d = vrtc_domain(s);
 
     if ( !(s->hw.cmos_data[RTC_REG_B] & RTC_SET) )
         rtc_copy_date(s);
@@ -310,8 +319,8 @@ static void rtc_update_second2(void *opa
               s->current_tm.tm_hour) )
         {
             s->hw.cmos_data[RTC_REG_C] |= 0xa0; 
-            hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ);
-            hvm_isa_irq_assert(s->pt.vcpu->domain, RTC_IRQ);
+            hvm_isa_irq_deassert(d, RTC_IRQ);
+            hvm_isa_irq_assert(d, RTC_IRQ);
         }
     }
 
@@ -319,8 +328,8 @@ static void rtc_update_second2(void *opa
     if ( s->hw.cmos_data[RTC_REG_B] & RTC_UIE )
     {
         s->hw.cmos_data[RTC_REG_C] |= 0x90; 
-        hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ);
-        hvm_isa_irq_assert(s->pt.vcpu->domain, RTC_IRQ);
+        hvm_isa_irq_deassert(d, RTC_IRQ);
+        hvm_isa_irq_assert(d, RTC_IRQ);
     }
 
     /* clear update in progress bit */
@@ -354,8 +363,8 @@ static uint32_t rtc_ioport_read(void *op
         break;
     case RTC_REG_C:
         ret = s->hw.cmos_data[s->hw.cmos_index];
-        hvm_isa_irq_deassert(s->pt.vcpu->domain, RTC_IRQ);
-        s->hw.cmos_data[RTC_REG_C] = 0x00; 
+        hvm_isa_irq_deassert(vrtc_domain(s), RTC_IRQ);
+        s->hw.cmos_data[RTC_REG_C] = 0x00;
         break;
     default:
         ret = s->hw.cmos_data[s->hw.cmos_index];
@@ -367,8 +376,7 @@ static uint32_t rtc_ioport_read(void *op
 
 static int handle_rtc_io(ioreq_t *p)
 {
-    struct vcpu *v = current;
-    struct RTCState *vrtc = &v->domain->arch.hvm_domain.pl_time.vrtc;
+    struct RTCState *vrtc = vcpu_vrtc(current);
 
     if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) )
     {
@@ -392,7 +400,7 @@ static int handle_rtc_io(ioreq_t *p)
 
 void rtc_migrate_timers(struct vcpu *v)
 {
-    RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc;
+    RTCState *s = vcpu_vrtc(v);
 
     if ( v->vcpu_id == 0 )
     {
@@ -404,13 +412,14 @@ void rtc_migrate_timers(struct vcpu *v)
 /* Save RTC hardware state */
 static int rtc_save(struct domain *d, hvm_domain_context_t *h)
 {
-    return hvm_save_entry(RTC, 0, h, &d->arch.hvm_domain.pl_time.vrtc.hw);
+    RTCState *s = domain_vrtc(d);
+    return hvm_save_entry(RTC, 0, h, &s->hw);
 }
 
 /* Reload the hardware state from a saved domain */
 static int rtc_load(struct domain *d, hvm_domain_context_t *h)
 {
-    RTCState *s = &d->arch.hvm_domain.pl_time.vrtc;    
+    RTCState *s = domain_vrtc(d);
 
     /* Restore the registers */
     if ( hvm_load_entry(RTC, h, &s->hw) != 0 )
@@ -425,7 +434,7 @@ static int rtc_load(struct domain *d, hv
     set_timer(&s->second_timer2, s->next_second_time);
 
     /* Reset the periodic interrupt timer based on the registers */
-    rtc_timer_update(s, d->vcpu[0]);
+    rtc_timer_update(s);
 
     return 0;
 }
@@ -435,9 +444,8 @@ HVM_REGISTER_SAVE_RESTORE(RTC, rtc_save,
 
 void rtc_init(struct vcpu *v, int base)
 {
-    RTCState *s = &v->domain->arch.hvm_domain.pl_time.vrtc;
-
-    s->pt.vcpu = v;
+    RTCState *s = vcpu_vrtc(v);
+
     s->hw.cmos_data[RTC_REG_A] = RTC_REF_CLCK_32KHZ | 6; /* ~1kHz */
     s->hw.cmos_data[RTC_REG_B] = RTC_24H;
     s->hw.cmos_data[RTC_REG_C] = 0;
@@ -457,7 +465,7 @@ void rtc_init(struct vcpu *v, int base)
 
 void rtc_deinit(struct domain *d)
 {
-    RTCState *s = &d->arch.hvm_domain.pl_time.vrtc;
+    RTCState *s = domain_vrtc(d);
 
     destroy_periodic_time(&s->pt);
     kill_timer(&s->second_timer);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.