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

[Xen-changelog] [xen-unstable] x86 hvm: Allow delivery of legacy 8259 in

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86 hvm: Allow delivery of legacy 8259 interrupts to VCPUs != 0.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 02 Jul 2009 08:50:36 -0700
Delivery-date: Thu, 02 Jul 2009 08:52:20 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1246476149 -3600
# Node ID 80839a223746adfb3d7b7688085a84017fe3cf39
# Parent  479f1fa084d6af8611b0973be0fb6d642db1f9f9
x86 hvm: Allow delivery of legacy 8259 interrupts to VCPUs != 0.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 tools/firmware/hvmloader/hvmloader.c |   12 ++++++---
 tools/firmware/hvmloader/mp_tables.c |   40 +++++++++++++++---------------
 xen/arch/x86/hvm/vioapic.c           |   17 +++++++-----
 xen/arch/x86/hvm/vlapic.c            |   46 ++++++++++++++++++++++++++++-------
 xen/arch/x86/hvm/vpic.c              |    8 ++----
 xen/include/asm-x86/hvm/domain.h     |    3 ++
 xen/include/asm-x86/hvm/vlapic.h     |    2 +
 7 files changed, 84 insertions(+), 44 deletions(-)

diff -r 479f1fa084d6 -r 80839a223746 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Wed Jul 01 14:58:31 2009 +0100
+++ b/tools/firmware/hvmloader/hvmloader.c      Wed Jul 01 20:22:29 2009 +0100
@@ -141,13 +141,17 @@ static void init_hypercalls(void)
 
 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 479f1fa084d6 -r 80839a223746 tools/firmware/hvmloader/mp_tables.c
--- a/tools/firmware/hvmloader/mp_tables.c      Wed Jul 01 14:58:31 2009 +0100
+++ b/tools/firmware/hvmloader/mp_tables.c      Wed Jul 01 20:22:29 2009 +0100
@@ -233,21 +233,6 @@ static void fill_mp_ioapic_entry(struct 
 }
 
 
-/* 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 create_mp_tables(void)
     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 @@ void create_mp_tables(void)
     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 479f1fa084d6 -r 80839a223746 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Wed Jul 01 14:58:31 2009 +0100
+++ b/xen/arch/x86/hvm/vioapic.c        Wed Jul 01 20:22:29 2009 +0100
@@ -146,10 +146,14 @@ static void vioapic_write_redirent(
 
     *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_redirent(
 }
 
 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 @@ static int vioapic_write(
         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 479f1fa084d6 -r 80839a223746 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Wed Jul 01 14:58:31 2009 +0100
+++ b/xen/arch/x86/hvm/vlapic.c Wed Jul 01 20:22:29 2009 +0100
@@ -697,6 +697,8 @@ static int vlapic_write(struct vcpu *v, 
             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,43 @@ void vlapic_msr_set(struct vlapic *vlapi
                 "apic base msr is 0x%016"PRIx64, vlapic->hw.apic_base_msr);
 }
 
-int vlapic_accept_pic_intr(struct vcpu *v)
-{
+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);
-
-    /*
-     * 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) ||
+    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)
+{
+    return ((v == v->domain->arch.hvm_domain.i8259_target) &&
+            __vlapic_accept_pic_intr(v));
+}
+
+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:
+    d->arch.hvm_domain.i8259_target = v;
 }
 
 int vlapic_has_pending_irq(struct vcpu *v)
@@ -946,6 +973,7 @@ static int lapic_load_regs(struct domain
     if ( hvm_load_entry(LAPIC_REGS, h, s->regs) != 0 ) 
         return -EINVAL;
 
+    vlapic_adjust_i8259_target(d);
     lapic_rearm(s);
     return 0;
 }
diff -r 479f1fa084d6 -r 80839a223746 xen/arch/x86/hvm/vpic.c
--- a/xen/arch/x86/hvm/vpic.c   Wed Jul 01 14:58:31 2009 +0100
+++ b/xen/arch/x86/hvm/vpic.c   Wed Jul 01 20:22:29 2009 +0100
@@ -109,11 +109,9 @@ static void vpic_update_int_output(struc
     {
         if ( vpic->is_master )
         {
-            /* Master INT line is connected to VCPU0's VLAPIC LVT0. */
-            struct vcpu *v = vpic_domain(vpic)->vcpu ?
-                vpic_domain(vpic)->vcpu[0] : NULL;
-
-            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 479f1fa084d6 -r 80839a223746 xen/include/asm-x86/hvm/domain.h
--- a/xen/include/asm-x86/hvm/domain.h  Wed Jul 01 14:58:31 2009 +0100
+++ b/xen/include/asm-x86/hvm/domain.h  Wed Jul 01 20:22:29 2009 +0100
@@ -57,6 +57,9 @@ struct hvm_domain {
     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 479f1fa084d6 -r 80839a223746 xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h  Wed Jul 01 14:58:31 2009 +0100
+++ b/xen/include/asm-x86/hvm/vlapic.h  Wed Jul 01 20:22:29 2009 +0100
@@ -93,6 +93,8 @@ void vlapic_msr_set(struct vlapic *vlapi
 
 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);

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86 hvm: Allow delivery of legacy 8259 interrupts to VCPUs != 0., Xen patchbot-unstable <=