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

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


  • To: George Dunlap <George.Dunlap@xxxxxxxxxxxxx>
  • From: Keir Fraser <keir@xxxxxxx>
  • Date: Fri, 14 Jan 2011 12:24:20 +0000
  • Cc: xen-devel@xxxxxxxxxxxxxxxxxxx, IWAMOTO Toshihiro <iwamoto@xxxxxxxxxxxxx>
  • Delivery-date: Fri, 14 Jan 2011 04:25:39 -0800
  • Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:user-agent:date:subject:from:to:cc:message-id:thread-topic :thread-index:in-reply-to:mime-version:content-type :content-transfer-encoding; b=RcZcpQhlzPAtEP3n7vRbc7pMdO7gAkSzfrW935shp3HI22IPuAnwkY/C/JfiPMEJ/y +YQREsPs3Sgbi7Dyjzg9XdAJziPyG6E6qyakNdZQEgWf8pQI/+76kp4IOyM86nfTW7RV MT2TaLt35Q1KgfKeh4FjykvBtiM+6qaQ27uTw=
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>
  • Thread-index: Acuz5fgCE+ZtiElLc0yYGiReRoAK+w==
  • Thread-topic: [Xen-devel] [PATCH] MP interrupt delivery fix for xen-3.4

Sure, if someone we deem competent wants to step up, that'd be absolutely
fine.

 -- Keir

On 14/01/2011 12:13, "George Dunlap" <George.Dunlap@xxxxxxxxxxxxx> wrote:

> Would it be reasonable to ask if anyone is willing to step up as a
> "legacy/stable maintainer"?  Given that 3.4 is still in the
> just-released Citrix product, it's hardly at the end of its life yet.
> :-)
> 
>  -George
> 
> On Thu, Jan 13, 2011 at 12:33 PM, Keir Fraser <keir@xxxxxxx> wrote:
>> 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
>> 



_______________________________________________
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®.