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-devel

Re: [Xen-devel] [PATCH] MP interrupt delivery fix for xen-3.4

To: IWAMOTO Toshihiro <iwamoto@xxxxxxxxxxxxx>, <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: Re: [Xen-devel] [PATCH] MP interrupt delivery fix for xen-3.4
From: Keir Fraser <keir@xxxxxxx>
Date: Thu, 13 Jan 2011 12:33:13 +0000
Cc:
Delivery-date: Thu, 13 Jan 2011 04:34:21 -0800
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:sender:user-agent:date:subject:from:to :message-id:thread-topic:thread-index:in-reply-to:x-priority :mime-version:content-type:content-transfer-encoding; bh=z/cXJkC4+TRL5+u0qcLRS7Wn1evR9Io9cPW3m4TgoQA=; b=SmOf648Mj7e5pzmEjGraK9JOEWieMkvau5k3qoYN2LeP73hBM+hV6OYvVhoypoijzS AZSYoI6YsFLNv9aMbeP+X9woIt1ndFcJzDuMLWswVT3GWI+l4vc2s11uv7IBktWtR43k cyauUwYZ2gtkQoz7x02tcJUvYwMonGEA+jqY0=
Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:user-agent:date:subject:from:to:message-id:thread-topic :thread-index:in-reply-to:x-priority:mime-version:content-type :content-transfer-encoding; b=uS9BYSWKNkUvu65jo8C5gQ9TjusbSbrH2pYFMUK98DPT0j+Mg2eeesJmhZSCUBBV52 xROuPqS6Zyh0fyaCojhIXGO0sMtcLTn8LWBCv1I0kLXdrXPCp1VxccOkfCRd3jmkpo+o pAnoITBoCUqUXO0GXWCDiAVZENhxo6Pa5tWmk=
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <20110113051947.4721987430@xxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: AcuzHgtKtuJrKwnNMEW3yQOR6mCaDQ==
Thread-topic: [Xen-devel] [PATCH] MP interrupt delivery fix for xen-3.4
User-agent: Microsoft-Entourage/12.28.0.101117
On 13/01/2011 05:19, "IWAMOTO Toshihiro" <iwamoto@xxxxxxxxxxxxx> wrote:

> Please backport the following xen-4.0-testing.hg changesets to
> xen-3.4.  They are necessary for kexec/kdump to work on MP guests.
> Backporting is mostly obvious but the changeset  19691:c4b2a3c9a61a,
> which is slightly different from 19912:721c14d7f60b, will cause a
> conflict.

I no longer maintain 3.4 and I'm not accepting patches to it.

 -- Keir

> A combined diff which is ready to be applyed on xen-3.4-testing.hg is
> also attached.
> 
> changeset:   19877:80839a223746
> user:        Keir Fraser <keir.fraser@xxxxxxxxxx>
> date:        Wed Jul 01 20:22:29 2009 +0100
> files:       tools/firmware/hvmloader/hvmloader.c
> tools/firmware/hvmloader/mp_tables.c xen/arch/x86/hvm/vioapic.c
> xen/arch/x86/hvm/vlapic.c xen/arch/x86/hvm/vpic.c
> xen/include/asm-x86/hvm/domain.h xen/include/asm-x86/hvm/vlapic.h
> description:
> x86 hvm: Allow delivery of legacy 8259 interrupts to VCPUs != 0.
> 
> changeset:   19906:2fadef1b008f
> user:        Keir Fraser <keir.fraser@xxxxxxxxxx>
> date:        Tue Jul 07 14:08:47 2009 +0100
> files:       xen/arch/x86/hvm/hpet.c xen/include/asm-x86/hvm/vpt.h
> description:
> x86,hvm: cleanup hpet.c vcpu handling same as i8254.c/rtc.c
> 
> - introduce macros: domain_vhpet, vcpu_vhpet, vhpet_domain, vhpet_vcpu
> - remove *vcpu field from struct HPETState
> - modify guest_time_hpet() takes *vhpet instead of *vcpu as 1st
> - argument
> 
> changeset:   19907:a29bb4efff00
> user:        Keir Fraser <keir.fraser@xxxxxxxxxx>
> date:        Tue Jul 07 14:21:16 2009 +0100
> files:       xen/arch/x86/hvm/hpet.c xen/arch/x86/hvm/i8254.c
> xen/arch/x86/hvm/rtc.c xen/arch/x86/hvm/vlapic.c
> xen/arch/x86/hvm/vpt.c xen/include/asm-x86/hvm/vpt.h
> description:
> x86,hvm: Allow delivery of timer interrupts to VCPUs != 0
> 
> This patch is needed for kexec/kdump since VCPU#0 is halted.
> 
> changeset:   19912:721c14d7f60b
> user:        Keir Fraser <keir.fraser@xxxxxxxxxx>
> date:        Wed Jul 08 14:22:00 2009 +0100
> files:       xen/arch/x86/hvm/hpet.c xen/arch/x86/hvm/i8254.c
> xen/arch/x86/hvm/rtc.c xen/arch/x86/hvm/vlapic.c
> xen/include/asm-x86/hvm/vlapic.h
> description:
> x86 hvm: Use 'x' as parameter name for macros converting between
> {vcpu,domain} and {vlapic,vpic,vrtc,hpet}. Completely avoids
> accidental aliasing.
> 
> 
> 
> diff -r 14709d196e43 tools/firmware/hvmloader/hvmloader.c
> --- a/tools/firmware/hvmloader/hvmloader.c Wed Jun 30 18:26:13 2010 +0100
> +++ b/tools/firmware/hvmloader/hvmloader.c Thu Jan 13 14:17:37 2011 +0900
> @@ -141,13 +141,17 @@
>  
>  static void apic_setup(void)
>  {
> -    /* Set the IOAPIC ID to tha static value used in the MP/ACPI tables. */
> +    /* Set the IOAPIC ID to the static value used in the MP/ACPI tables. */
>      ioapic_write(0x00, IOAPIC_ID);
>  
> -    /* Set up Virtual Wire mode. */
> +    /* NMIs are delivered direct to the BSP. */
>      lapic_write(APIC_SPIV, APIC_SPIV_APIC_ENABLED | 0xFF);
> -    lapic_write(APIC_LVT0, APIC_MODE_EXTINT << 8);
> -    lapic_write(APIC_LVT1, APIC_MODE_NMI    << 8);
> +    lapic_write(APIC_LVT0, (APIC_MODE_EXTINT << 8) | APIC_LVT_MASKED);
> +    lapic_write(APIC_LVT1, APIC_MODE_NMI << 8);
> +
> +    /* 8259A ExtInts are delivered through IOAPIC pin 0 (Virtual Wire Mode).
> */
> +    ioapic_write(0x10, APIC_DM_EXTINT);
> +    ioapic_write(0x11, SET_APIC_ID(LAPIC_ID(0)));
>  }
>  
>  static void pci_setup(void)
> diff -r 14709d196e43 tools/firmware/hvmloader/mp_tables.c
> --- a/tools/firmware/hvmloader/mp_tables.c Wed Jun 30 18:26:13 2010 +0100
> +++ b/tools/firmware/hvmloader/mp_tables.c Thu Jan 13 14:17:37 2011 +0900
> @@ -233,21 +233,6 @@
>  }
>  
>  
> -/* fills in an IO interrupt entry for IOAPIC 'ioapic_id' */
> -static void fill_mp_io_intr_entry(
> -    struct mp_io_intr_entry *mpiie,
> -    int src_bus_id, int src_bus_irq, int ioapic_id, int dst_ioapic_intin)
> -{
> -    mpiie->type = ENTRY_TYPE_IO_INTR;
> -    mpiie->intr_type = INTR_TYPE_INT;
> -    mpiie->io_intr_flags = (PCI_ISA_IRQ_MASK & (1U<<src_bus_irq)) ? 0xf :
> 0x0;
> -    mpiie->src_bus_id = src_bus_id;
> -    mpiie->src_bus_irq = src_bus_irq;
> -    mpiie->dst_ioapic_id = ioapic_id;
> -    mpiie->dst_ioapic_intin = dst_ioapic_intin;
> -}
> -
> -
>  /* fill in the mp floating processor structure */
>  static void fill_mpfps(struct mp_floating_pointer_struct *mpfps, uint32_t
> mpct)
>  {
> @@ -316,6 +301,7 @@
>      void *mp_table_base;
>      char *p;
>      int vcpu_nr, i, length;
> +    struct mp_io_intr_entry *mpiie;
>  
>      vcpu_nr = hvm_info->nr_vcpus;
>  
> @@ -343,12 +329,28 @@
>      fill_mp_ioapic_entry((struct mp_ioapic_entry *)p);
>      p += sizeof(struct mp_ioapic_entry);
>  
> +    /* I/O interrupt assignment: IOAPIC pin 0 is connected to 8259 ExtInt. */
> +    mpiie = (struct mp_io_intr_entry *)p;
> +    memset(mpiie, 0, sizeof(*mpiie));
> +    mpiie->type = ENTRY_TYPE_IO_INTR;
> +    mpiie->intr_type = INTR_TYPE_EXTINT;
> +    mpiie->dst_ioapic_id = IOAPIC_ID;
> +    p += sizeof(*mpiie);
> +
> +    /* I/O interrupt assignment for every legacy 8259 interrupt source. */
>      for ( i = 0; i < 16; i++ )
>      {
> -        if ( i == 2 ) continue; /* skip the slave PIC connection */
> -        fill_mp_io_intr_entry((struct mp_io_intr_entry *)p,
> -                              BUS_ID_ISA, i, IOAPIC_ID, (i == 0) ? 2 : i);
> -        p += sizeof(struct mp_io_intr_entry);
> +        if ( i == 2 )
> +            continue; /* skip the slave PIC connection */
> +        mpiie = (struct mp_io_intr_entry *)p;
> +        mpiie->type = ENTRY_TYPE_IO_INTR;
> +        mpiie->intr_type = INTR_TYPE_EXTINT;
> +        mpiie->io_intr_flags = (PCI_ISA_IRQ_MASK & (1U << i)) ? 0xf : 0x0;
> +        mpiie->src_bus_id = BUS_ID_ISA;
> +        mpiie->src_bus_irq = i;
> +        mpiie->dst_ioapic_id = IOAPIC_ID;
> +        mpiie->dst_ioapic_intin = (i == 0) ? 2 : i;
> +        p += sizeof(*mpiie);
>      }
>  
>      length = p - (char *)mp_table_base;
> diff -r 14709d196e43 xen/arch/x86/hvm/hpet.c
> --- a/xen/arch/x86/hvm/hpet.c Wed Jun 30 18:26:13 2010 +0100
> +++ b/xen/arch/x86/hvm/hpet.c Thu Jan 13 14:17:37 2011 +0900
> @@ -24,6 +24,12 @@
>  #include <xen/sched.h>
>  #include <xen/event.h>
>  
> +#define domain_vhpet(x) (&(x)->arch.hvm_domain.pl_time.vhpet)
> +#define vcpu_vhpet(x)   (domain_vhpet((x)->domain))
> +#define vhpet_domain(x) (container_of((x), struct domain, \
> +                                      arch.hvm_domain.pl_time.vhpet))
> +#define vhpet_vcpu(x)   (pt_global_vcpu_target(vhpet_domain(x)))
> +
>  #define HPET_BASE_ADDRESS   0xfed00000ULL
>  #define HPET_MMAP_SIZE      1024
>  #define S_TO_NS  1000000000ULL           /* 1s  = 10^9  ns */
> @@ -31,7 +37,8 @@
>  
>  /* Frequency_of_Xen_systeme_time / frequency_of_HPET = 16 */
>  #define STIME_PER_HPET_TICK 16
> -#define guest_time_hpet(v) (hvm_get_guest_time(v) / STIME_PER_HPET_TICK)
> +#define guest_time_hpet(hpet) \
> +    (hvm_get_guest_time(vhpet_vcpu(hpet)) / STIME_PER_HPET_TICK)
>  
>  #define HPET_ID         0x000
>  #define HPET_PERIOD     0x004
> @@ -94,7 +101,7 @@
>      ASSERT(spin_is_locked(&h->lock));
>  
>      if ( hpet_enabled(h) )
> -        return guest_time_hpet(h->vcpu) + h->mc_offset;
> +        return guest_time_hpet(h) + h->mc_offset;
>      else 
>          return h->hpet.mc64;
>  }
> @@ -176,7 +183,7 @@
>      struct vcpu *v, unsigned long addr, unsigned long length,
>      unsigned long *pval)
>  {
> -    HPETState *h = &v->domain->arch.hvm_domain.pl_time.vhpet;
> +    HPETState *h = vcpu_vhpet(v);
>      unsigned long result;
>      uint64_t val;
>  
> @@ -230,7 +237,7 @@
>      {
>          /* HPET specification requires PIT shouldn't generate
>           * interrupts if LegacyReplacementRoute is set for timer0 */
> -        PITState *pit = &h->vcpu->domain->arch.hvm_domain.pl_time.vpit;
> +        PITState *pit = &vhpet_domain(h)->arch.hvm_domain.pl_time.vpit;
>          pit_stop_channel0_irq(pit);
>      }
>  
> @@ -272,7 +279,7 @@
>       * being enabled (now).
>       */
>      oneshot = !timer_is_periodic(h, tn);
> -    create_periodic_time(h->vcpu, &h->pt[tn],
> +    create_periodic_time(vhpet_vcpu(h), &h->pt[tn],
>                           hpet_tick_to_ns(h, diff),
>                           oneshot ? 0 : hpet_tick_to_ns(h,
> h->hpet.period[tn]),
>                           irq, NULL, NULL);
> @@ -290,7 +297,7 @@
>      struct vcpu *v, unsigned long addr,
>      unsigned long length, unsigned long val)
>  {
> -    HPETState *h = &v->domain->arch.hvm_domain.pl_time.vhpet;
> +    HPETState *h = vcpu_vhpet(v);
>      uint64_t old_val, new_val;
>      int tn, i;
>  
> @@ -323,7 +330,7 @@
>          if ( !(old_val & HPET_CFG_ENABLE) && (new_val & HPET_CFG_ENABLE) )
>          {
>              /* Enable main counter and interrupt generation. */
> -            h->mc_offset = h->hpet.mc64 - guest_time_hpet(h->vcpu);
> +            h->mc_offset = h->hpet.mc64 - guest_time_hpet(h);
>              for ( i = 0; i < HPET_TIMER_NUM; i++ )
>              {
>                  h->hpet.comparator64[i] =
> @@ -337,7 +344,7 @@
>          else if ( (old_val & HPET_CFG_ENABLE) && !(new_val & HPET_CFG_ENABLE)
> )
>          {
>              /* Halt main counter and disable interrupt generation. */
> -            h->hpet.mc64 = h->mc_offset + guest_time_hpet(h->vcpu);
> +            h->hpet.mc64 = h->mc_offset + guest_time_hpet(h);
>              for ( i = 0; i < HPET_TIMER_NUM; i++ )
>                  if ( timer_enabled(h, i) )
>                      set_stop_timer(i);
> @@ -487,13 +494,13 @@
>  
>  static int hpet_save(struct domain *d, hvm_domain_context_t *h)
>  {
> -    HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet;
> +    HPETState *hp = domain_vhpet(d);
>      int rc;
>  
>      spin_lock(&hp->lock);
>  
>      /* Write the proper value into the main counter */
> -    hp->hpet.mc64 = hp->mc_offset + guest_time_hpet(hp->vcpu);
> +    hp->hpet.mc64 = hp->mc_offset + guest_time_hpet(hp);
>  
>      /* Save the HPET registers */
>      rc = _hvm_init_entry(h, HVM_SAVE_CODE(HPET), 0, HVM_SAVE_LENGTH(HPET));
> @@ -531,7 +538,7 @@
>  
>  static int hpet_load(struct domain *d, hvm_domain_context_t *h)
>  {
> -    HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet;
> +    HPETState *hp = domain_vhpet(d);
>      struct hvm_hw_hpet *rec;
>      uint64_t cmp;
>      int i;
> @@ -572,7 +579,7 @@
>  #undef C
>      
>      /* Recalculate the offset between the main counter and guest time */
> -    hp->mc_offset = hp->hpet.mc64 - guest_time_hpet(hp->vcpu);
> +    hp->mc_offset = hp->hpet.mc64 - guest_time_hpet(hp);
>  
>      /* restart all timers */
>  
> @@ -590,14 +597,13 @@
>  
>  void hpet_init(struct vcpu *v)
>  {
> -    HPETState *h = &v->domain->arch.hvm_domain.pl_time.vhpet;
> +    HPETState *h = vcpu_vhpet(v);
>      int i;
>  
>      memset(h, 0, sizeof(HPETState));
>  
>      spin_lock_init(&h->lock);
>  
> -    h->vcpu = v;
>      h->stime_freq = S_TO_NS;
>  
>      h->hpet_to_ns_scale = ((S_TO_NS * STIME_PER_HPET_TICK) << 10) /
> h->stime_freq;
> @@ -622,7 +628,7 @@
>  void hpet_deinit(struct domain *d)
>  {
>      int i;
> -    HPETState *h = &d->arch.hvm_domain.pl_time.vhpet;
> +    HPETState *h = domain_vhpet(d);
>  
>      spin_lock(&h->lock);
>  
> diff -r 14709d196e43 xen/arch/x86/hvm/i8254.c
> --- a/xen/arch/x86/hvm/i8254.c Wed Jun 30 18:26:13 2010 +0100
> +++ b/xen/arch/x86/hvm/i8254.c Thu Jan 13 14:17:37 2011 +0900
> @@ -42,7 +42,7 @@
>  #define vcpu_vpit(x)   (domain_vpit((x)->domain))
>  #define vpit_domain(x) (container_of((x), struct domain, \
>                                       arch.hvm_domain.pl_time.vpit))
> -#define vpit_vcpu(x)   (vpit_domain(x)->vcpu[0])
> +#define vpit_vcpu(x)   (pt_global_vcpu_target(vpit_domain(x)))
>  
>  #define RW_STATE_LSB 1
>  #define RW_STATE_MSB 2
> diff -r 14709d196e43 xen/arch/x86/hvm/rtc.c
> --- a/xen/arch/x86/hvm/rtc.c Wed Jun 30 18:26:13 2010 +0100
> +++ b/xen/arch/x86/hvm/rtc.c Thu Jan 13 14:17:37 2011 +0900
> @@ -32,7 +32,7 @@
>  #define vcpu_vrtc(x)   (domain_vrtc((x)->domain))
>  #define vrtc_domain(x) (container_of((x), struct domain, \
>                                       arch.hvm_domain.pl_time.vrtc))
> -#define vrtc_vcpu(x)   (vrtc_domain(x)->vcpu[0])
> +#define vrtc_vcpu(x)   (pt_global_vcpu_target(vrtc_domain(x)))
>  
>  static void rtc_periodic_cb(struct vcpu *v, void *opaque)
>  {
> diff -r 14709d196e43 xen/arch/x86/hvm/vioapic.c
> --- a/xen/arch/x86/hvm/vioapic.c Wed Jun 30 18:26:13 2010 +0100
> +++ b/xen/arch/x86/hvm/vioapic.c Thu Jan 13 14:17:37 2011 +0900
> @@ -146,10 +146,14 @@
>  
>      *pent = ent;
>  
> -    if ( (ent.fields.trig_mode == VIOAPIC_LEVEL_TRIG) &&
> -         !ent.fields.mask &&
> -         !ent.fields.remote_irr &&
> -         hvm_irq->gsi_assert_count[idx] )
> +    if ( idx == 0 )
> +    {
> +        vlapic_adjust_i8259_target(d);
> +    }
> +    else if ( (ent.fields.trig_mode == VIOAPIC_LEVEL_TRIG) &&
> +              !ent.fields.mask &&
> +              !ent.fields.remote_irr &&
> +              hvm_irq->gsi_assert_count[idx] )
>      {
>          pent->fields.remote_irr = 1;
>          vioapic_deliver(vioapic, idx);
> @@ -159,8 +163,7 @@
>  }
>  
>  static void vioapic_write_indirect(
> -    struct hvm_hw_vioapic *vioapic, unsigned long addr,
> -    unsigned long length, unsigned long val)
> +    struct hvm_hw_vioapic *vioapic, unsigned long length, unsigned long val)
>  {
>      switch ( vioapic->ioregsel )
>      {
> @@ -213,7 +216,7 @@
>          break;
>  
>      case VIOAPIC_REG_WINDOW:
> -        vioapic_write_indirect(vioapic, addr, length, val);
> +        vioapic_write_indirect(vioapic, length, val);
>          break;
>  
>  #if VIOAPIC_IS_IOSAPIC
> diff -r 14709d196e43 xen/arch/x86/hvm/vlapic.c
> --- a/xen/arch/x86/hvm/vlapic.c Wed Jun 30 18:26:13 2010 +0100
> +++ b/xen/arch/x86/hvm/vlapic.c Thu Jan 13 14:17:37 2011 +0900
> @@ -697,6 +697,8 @@
>              val |= APIC_LVT_MASKED;
>          val &= vlapic_lvt_mask[(offset - APIC_LVTT) >> 4];
>          vlapic_set_reg(vlapic, offset, val);
> +        if ( offset == APIC_LVT0 )
> +            vlapic_adjust_i8259_target(v->domain);
>          break;
>  
>      case APIC_TMICT:
> @@ -776,18 +778,46 @@
>                  "apic base msr is 0x%016"PRIx64, vlapic->hw.apic_base_msr);
>  }
>  
> +static int __vlapic_accept_pic_intr(struct vcpu *v)
> +{
> +    struct domain *d = v->domain;
> +    struct vlapic *vlapic = vcpu_vlapic(v);
> +    uint32_t lvt0 = vlapic_get_reg(vlapic, APIC_LVT0);
> +    union vioapic_redir_entry redir0 = domain_vioapic(d)->redirtbl[0];
> +
> +    /* We deliver 8259 interrupts to the appropriate CPU as follows. */
> +    return ((/* IOAPIC pin0 is unmasked and routing to this LAPIC? */
> +             ((redir0.fields.delivery_mode == dest_ExtINT) &&
> +              !redir0.fields.mask &&
> +              redir0.fields.dest_id == VLAPIC_ID(vlapic) &&
> +              !vlapic_disabled(vlapic)) ||
> +             /* LAPIC has LVT0 unmasked for ExtInts? */
> +             ((lvt0 & (APIC_MODE_MASK|APIC_LVT_MASKED)) == APIC_DM_EXTINT) ||
> +             /* LAPIC is fully disabled? */
> +             vlapic_hw_disabled(vlapic)));
> +}
> +
>  int vlapic_accept_pic_intr(struct vcpu *v)
>  {
> -    struct vlapic *vlapic = vcpu_vlapic(v);
> -    uint32_t lvt0 = vlapic_get_reg(vlapic, APIC_LVT0);
> +    return ((v == v->domain->arch.hvm_domain.i8259_target) &&
> +            __vlapic_accept_pic_intr(v));
> +}
>  
> -    /*
> -     * Only CPU0 is wired to the 8259A. INTA cycles occur if LINT0 is set up
> -     * accept ExtInts, or if the LAPIC is disabled (so LINT0 behaves as
> INTR).
> -     */
> -    return ((v->vcpu_id == 0) &&
> -            (((lvt0 & (APIC_MODE_MASK|APIC_LVT_MASKED)) == APIC_DM_EXTINT) ||
> -             vlapic_hw_disabled(vlapic)));
> +void vlapic_adjust_i8259_target(struct domain *d)
> +{
> +    struct vcpu *v;
> +
> +    for_each_vcpu ( d, v )
> +        if ( __vlapic_accept_pic_intr(v) )
> +            goto found;
> +
> +    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)
> @@ -946,6 +976,7 @@
>      if ( hvm_load_entry(LAPIC_REGS, h, s->regs) != 0 )
>          return -EINVAL;
>  
> +    vlapic_adjust_i8259_target(d);
>      lapic_rearm(s);
>      return 0;
>  }
> diff -r 14709d196e43 xen/arch/x86/hvm/vpic.c
> --- a/xen/arch/x86/hvm/vpic.c Wed Jun 30 18:26:13 2010 +0100
> +++ b/xen/arch/x86/hvm/vpic.c Thu Jan 13 14:17:37 2011 +0900
> @@ -109,9 +109,9 @@
>      {
>          if ( vpic->is_master )
>          {
> -            /* Master INT line is connected to VCPU0's VLAPIC LVT0. */
> -            struct vcpu *v = vpic_domain(vpic)->vcpu[0];
> -            if ( (v != NULL) && vlapic_accept_pic_intr(v) )
> +            /* Master INT line is connected in Virtual Wire Mode. */
> +            struct vcpu *v = vpic_domain(vpic)->arch.hvm_domain.i8259_target;
> +            if ( v != NULL )
>                  vcpu_kick(v);
>          }
>          else
> diff -r 14709d196e43 xen/arch/x86/hvm/vpt.c
> --- a/xen/arch/x86/hvm/vpt.c Wed Jun 30 18:26:13 2010 +0100
> +++ b/xen/arch/x86/hvm/vpt.c Thu Jan 13 14:17:37 2011 +0900
> @@ -434,3 +434,53 @@
>       */
>      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 -r 14709d196e43 xen/include/asm-x86/hvm/domain.h
> --- a/xen/include/asm-x86/hvm/domain.h Wed Jun 30 18:26:13 2010 +0100
> +++ b/xen/include/asm-x86/hvm/domain.h Thu Jan 13 14:17:37 2011 +0900
> @@ -56,6 +56,9 @@
>      struct hvm_vioapic    *vioapic;
>      struct hvm_hw_stdvga   stdvga;
>  
> +    /* VCPU which is current target for 8259 interrupts. */
> +    struct vcpu           *i8259_target;
> +
>      /* hvm_print_line() logging. */
>      char                   pbuf[80];
>      int                    pbuf_idx;
> diff -r 14709d196e43 xen/include/asm-x86/hvm/vlapic.h
> --- a/xen/include/asm-x86/hvm/vlapic.h Wed Jun 30 18:26:13 2010 +0100
> +++ b/xen/include/asm-x86/hvm/vlapic.h Thu Jan 13 14:17:37 2011 +0900
> @@ -92,6 +92,8 @@
>  
>  int vlapic_accept_pic_intr(struct vcpu *v);
>  
> +void vlapic_adjust_i8259_target(struct domain *d);
> +
>  struct vlapic *apic_lowest_prio(struct domain *d, uint32_t bitmap);
>  
>  int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda);
> diff -r 14709d196e43 xen/include/asm-x86/hvm/vpt.h
> --- a/xen/include/asm-x86/hvm/vpt.h Wed Jun 30 18:26:13 2010 +0100
> +++ b/xen/include/asm-x86/hvm/vpt.h Thu Jan 13 14:17:37 2011 +0900
> @@ -92,7 +92,6 @@
>  
>  typedef struct HPETState {
>      struct hpet_registers hpet;
> -    struct vcpu *vcpu;
>      uint64_t stime_freq;
>      uint64_t hpet_to_ns_scale; /* hpet ticks to ns (multiplied by 2^10) */
>      uint64_t hpet_to_ns_limit; /* max hpet ticks convertable to ns      */
> @@ -145,6 +144,10 @@
>  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)
>  
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxxxxxxxx
> http://lists.xensource.com/xen-devel



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