[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |