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

[Xen-devel] [PATCH] x86, hvm: Allow delivery of timer interrupts to VCPUs != 0.



This patch is needed for kexec/kdump since kdump may halt VCPU#0.

Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>

diff -r 80839a223746 xen/arch/x86/hvm/i8254.c
--- a/xen/arch/x86/hvm/i8254.c  Wed Jul 01 20:22:29 2009 +0100
+++ b/xen/arch/x86/hvm/i8254.c  Fri Jul 03 13:17:44 2009 +0900
@@ -42,7 +42,7 @@
 #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 vpit_vcpu(pit)   (pit->pt0.vcpu ? : pt_i8259_target(vpit_domain(pit)))
 
 #define RW_STATE_LSB 1
 #define RW_STATE_MSB 2
diff -r 80839a223746 xen/arch/x86/hvm/rtc.c
--- a/xen/arch/x86/hvm/rtc.c    Wed Jul 01 20:22:29 2009 +0100
+++ b/xen/arch/x86/hvm/rtc.c    Fri Jul 03 13:17:44 2009 +0900
@@ -32,7 +32,7 @@
 #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])
+#define vrtc_vcpu(rtc)   (rtc->pt.vcpu ? : pt_i8259_target(vrtc_domain(rtc)))
 
 static void rtc_periodic_cb(struct vcpu *v, void *opaque)
 {
diff -r 80839a223746 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Wed Jul 01 20:22:29 2009 +0100
+++ b/xen/arch/x86/hvm/vlapic.c Fri Jul 03 13:17:44 2009 +0900
@@ -809,7 +809,10 @@ void vlapic_adjust_i8259_target(struct d
 
     for_each_vcpu ( d, v )
         if ( __vlapic_accept_pic_intr(v) )
+        {
+            pt_adjust_i8259_target(v);
             goto found;
+        }
 
     v = d->vcpu ? d->vcpu[0] : NULL;
 
diff -r 80839a223746 xen/arch/x86/hvm/vpt.c
--- a/xen/arch/x86/hvm/vpt.c    Wed Jul 01 20:22:29 2009 +0100
+++ b/xen/arch/x86/hvm/vpt.c    Fri Jul 03 13:17:44 2009 +0900
@@ -419,13 +419,16 @@ void create_periodic_time(
     spin_unlock(&v->arch.hvm_vcpu.tm_lock);
 }
 
-void destroy_periodic_time(struct periodic_time *pt)
+int destroy_periodic_time(struct periodic_time *pt)
 {
+    int on_list;
+
     /* Was this structure previously initialised by create_periodic_time()? */
     if ( pt->vcpu == NULL )
-        return;
+        return 0;
 
     pt_lock(pt);
+    on_list = pt->on_list;
     if ( pt->on_list )
         list_del(&pt->list);
     pt->on_list = 0;
@@ -436,4 +439,53 @@ void destroy_periodic_time(struct period
      * outside pt_lock() otherwise we can deadlock with pt_timer_fn().
      */
     kill_timer(&pt->timer);
+    return on_list;
 }
+
+static void pt_adjust_vcpu(struct periodic_time *pt, struct vcpu *v)
+{
+    int on_list;
+
+    ASSERT(pt->source == PTSRC_isa);
+
+    if ( pt->vcpu == NULL || pt->vcpu == v )
+        return;
+
+    on_list = destroy_periodic_time(pt);
+
+    spin_lock(&v->arch.hvm_vcpu.tm_lock);
+    pt->vcpu = v;
+    if ( on_list )
+    {
+        pt->last_plt_gtime = hvm_get_guest_time(v);
+
+        pt->on_list = 1;
+        list_add(&pt->list, &v->arch.hvm_vcpu.tm_list);
+
+        migrate_timer(&pt->timer, v->processor);
+    }
+    spin_unlock(&v->arch.hvm_vcpu.tm_lock);
+}
+
+void pt_adjust_i8259_target(struct vcpu *v)
+{
+    struct pl_time *pl_time = &v->domain->arch.hvm_domain.pl_time;
+    int i;
+
+    spin_lock(&pl_time->vpit.lock);
+    pt_adjust_vcpu(&pl_time->vpit.pt0, v);
+    spin_unlock(&pl_time->vpit.lock);
+
+    spin_lock(&pl_time->vrtc.lock);
+    pt_adjust_vcpu(&pl_time->vrtc.pt, v);
+    spin_unlock(&pl_time->vrtc.lock);
+
+    spin_lock(&pl_time->vhpet.lock);
+    if ( pl_time->vhpet.vcpu != v )
+    {
+        pl_time->vhpet.vcpu = v;
+        for ( i = 0; i < HPET_TIMER_NUM; i++ )
+            pt_adjust_vcpu(&pl_time->vhpet.pt[i], v);
+    }
+    spin_unlock(&pl_time->vhpet.lock);
+}
diff -r 80839a223746 xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h     Wed Jul 01 20:22:29 2009 +0100
+++ b/xen/include/asm-x86/hvm/vpt.h     Fri Jul 03 13:17:44 2009 +0900
@@ -142,6 +142,10 @@ void pt_intr_post(struct vcpu *v, struct
 void pt_intr_post(struct vcpu *v, struct hvm_intack intack);
 void pt_reset(struct vcpu *v);
 void pt_migrate(struct vcpu *v);
+void pt_adjust_i8259_target(struct vcpu *v);
+
+#define pt_i8259_target(d) \
+    ((d)->arch.hvm_domain.i8259_target ? : (d)->vcpu[0])
 
 /* Is given periodic timer active? */
 #define pt_active(pt) ((pt)->on_list)
@@ -158,7 +162,7 @@ void create_periodic_time(
 void create_periodic_time(
     struct vcpu *v, struct periodic_time *pt, uint64_t delta,
     uint64_t period, uint8_t irq, time_cb *cb, void *data);
-void destroy_periodic_time(struct periodic_time *pt);
+int destroy_periodic_time(struct periodic_time *pt);
 
 int pv_pit_handler(int port, int data, int write);
 void pit_reset(struct domain *d);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

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