WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] hvm: Simplify timer<->vcpu/domain convers

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] hvm: Simplify timer<->vcpu/domain conversion in RTC and PIT timer
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 15 Jun 2007 07:31:54 -0700
Delivery-date: Fri, 15 Jun 2007 07:30:37 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] hvm: Simplify timer<->vcpu/domain conversion in RTC and PIT timer, Xen patchbot-unstable <=