diff options
-rw-r--r-- | xen/arch/x86/hvm/hpet.c | 2 | ||||
-rw-r--r-- | xen/arch/x86/hvm/i8254.c | 2 | ||||
-rw-r--r-- | xen/arch/x86/hvm/rtc.c | 2 | ||||
-rw-r--r-- | xen/arch/x86/hvm/vlapic.c | 3 | ||||
-rw-r--r-- | xen/arch/x86/hvm/vpt.c | 50 | ||||
-rw-r--r-- | xen/include/asm-x86/hvm/vpt.h | 4 |
6 files changed, 60 insertions, 3 deletions
diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c index 1330a6f634..89af0b61ee 100644 --- a/xen/arch/x86/hvm/hpet.c +++ b/xen/arch/x86/hvm/hpet.c @@ -28,7 +28,7 @@ #define vcpu_vhpet(vcpu) (domain_vhpet((vcpu)->domain)) #define vhpet_domain(hpet) (container_of((hpet), struct domain, \ arch.hvm_domain.pl_time.vhpet)) -#define vhpet_vcpu(hpet) (vhpet_domain(hpet)->vcpu[0]) +#define vhpet_vcpu(hpet) (pt_global_vcpu_target(vhpet_domain(hpet))) #define HPET_BASE_ADDRESS 0xfed00000ULL #define HPET_MMAP_SIZE 1024 diff --git a/xen/arch/x86/hvm/i8254.c b/xen/arch/x86/hvm/i8254.c index a87ddecc58..5394679a8e 100644 --- a/xen/arch/x86/hvm/i8254.c +++ b/xen/arch/x86/hvm/i8254.c @@ -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) (pt_global_vcpu_target(vpit_domain(pit))) #define RW_STATE_LSB 1 #define RW_STATE_MSB 2 diff --git a/xen/arch/x86/hvm/rtc.c b/xen/arch/x86/hvm/rtc.c index 9ab69033b0..0128d02419 100644 --- a/xen/arch/x86/hvm/rtc.c +++ b/xen/arch/x86/hvm/rtc.c @@ -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) (pt_global_vcpu_target(vrtc_domain(rtc))) static void rtc_periodic_cb(struct vcpu *v, void *opaque) { diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index cfa6ecf95e..1f42a60591 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -814,7 +814,10 @@ void vlapic_adjust_i8259_target(struct domain *d) v = d->vcpu ? d->vcpu[0] : NULL; found: + if ( d->arch.hvm_domain.i8259_target == v ) + return; d->arch.hvm_domain.i8259_target = v; + pt_adjust_global_vcpu_target(v); } int vlapic_has_pending_irq(struct vcpu *v) diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c index 6a12d37a21..a949d918ba 100644 --- a/xen/arch/x86/hvm/vpt.c +++ b/xen/arch/x86/hvm/vpt.c @@ -437,3 +437,53 @@ void destroy_periodic_time(struct periodic_time *pt) */ kill_timer(&pt->timer); } + +static void pt_adjust_vcpu(struct periodic_time *pt, struct vcpu *v) +{ + int on_list; + + ASSERT(pt->source == PTSRC_isa); + + if ( pt->vcpu == NULL ) + return; + + pt_lock(pt); + on_list = pt->on_list; + if ( pt->on_list ) + list_del(&pt->list); + pt->on_list = 0; + pt_unlock(pt); + + spin_lock(&v->arch.hvm_vcpu.tm_lock); + pt->vcpu = v; + if ( on_list ) + { + 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_global_vcpu_target(struct vcpu *v) +{ + struct pl_time *pl_time = &v->domain->arch.hvm_domain.pl_time; + int i; + + if ( v == NULL ) + return; + + 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); + for ( i = 0; i < HPET_TIMER_NUM; i++ ) + pt_adjust_vcpu(&pl_time->vhpet.pt[i], v); + spin_unlock(&pl_time->vhpet.lock); +} diff --git a/xen/include/asm-x86/hvm/vpt.h b/xen/include/asm-x86/hvm/vpt.h index 12ce3e4826..2d572d5376 100644 --- a/xen/include/asm-x86/hvm/vpt.h +++ b/xen/include/asm-x86/hvm/vpt.h @@ -142,6 +142,10 @@ 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_global_vcpu_target(struct vcpu *v); +#define pt_global_vcpu_target(d) \ + ((d)->arch.hvm_domain.i8259_target ? : (d)->vcpu ? (d)->vcpu[0] : NULL) + /* Is given periodic timer active? */ #define pt_active(pt) ((pt)->on_list) |