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] vt-d: Allow pass-through of shared interr

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] vt-d: Allow pass-through of shared interrupts.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 20 Oct 2007 05:50:19 -0700
Delivery-date: Sat, 20 Oct 2007 05:52:40 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
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/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/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@xxxxxxxxxxxxx>
# Date 1192789618 -3600
# Node ID e733e6b73d56e014c5b2eba04564e7ee439c2b59
# Parent  bc4afcd4c612afcee7f2fa2fc0ca400c26758876
vt-d: Allow pass-through of shared interrupts.
Signed-off-by: Xiaohui Xin <xiaohui.xin@xxxxxxxxx>
Signed-off-by: Kevin Tian <kevin.tian@xxxxxxxxx>
---
 xen/arch/x86/hvm/svm/amd_iommu/amd-iommu-map.c |    2 
 xen/arch/x86/hvm/vioapic.c                     |    2 
 xen/arch/x86/hvm/vmx/intr.c                    |   12 +++++
 xen/arch/x86/hvm/vmx/vtd/dmar.c                |    8 ---
 xen/arch/x86/hvm/vmx/vtd/io.c                  |   56 ++++++++++++++++---------
 xen/arch/x86/hvm/vpic.c                        |    3 -
 xen/include/asm-x86/hvm/io.h                   |    3 -
 xen/include/asm-x86/hvm/irq.h                  |    2 
 xen/include/asm-x86/iommu.h                    |    5 +-
 9 files changed, 62 insertions(+), 31 deletions(-)

diff -r bc4afcd4c612 -r e733e6b73d56 
xen/arch/x86/hvm/svm/amd_iommu/amd-iommu-map.c
--- a/xen/arch/x86/hvm/svm/amd_iommu/amd-iommu-map.c    Fri Oct 19 09:31:03 
2007 +0100
+++ b/xen/arch/x86/hvm/svm/amd_iommu/amd-iommu-map.c    Fri Oct 19 11:26:58 
2007 +0100
@@ -18,10 +18,10 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
+#include <xen/sched.h>
 #include <asm/hvm/iommu.h>
 #include <asm/amd-iommu.h>
 #include <asm/hvm/svm/amd-iommu-proto.h>
-#include <xen/sched.h>
 
 extern long amd_iommu_poll_comp_wait;
 
diff -r bc4afcd4c612 -r e733e6b73d56 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Fri Oct 19 09:31:03 2007 +0100
+++ b/xen/arch/x86/hvm/vioapic.c        Fri Oct 19 11:26:58 2007 +0100
@@ -459,7 +459,7 @@ void vioapic_update_EOI(struct domain *d
     ent->fields.remote_irr = 0;
 
     if ( vtd_enabled )
-        hvm_dpci_eoi(gsi, ent);
+        hvm_dpci_eoi(current->domain, gsi, ent);
 
     if ( (ent->fields.trig_mode == VIOAPIC_LEVEL_TRIG) &&
          !ent->fields.mask &&
diff -r bc4afcd4c612 -r e733e6b73d56 xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c       Fri Oct 19 09:31:03 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/intr.c       Fri Oct 19 11:26:58 2007 +0100
@@ -121,10 +121,22 @@ static void vmx_dirq_assist(struct vcpu 
           irq < NR_IRQS;
           irq = find_next_bit(hvm_irq_dpci->dirq_mask, NR_IRQS, irq + 1) )
     {
+        stop_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(irq)]);
+
         test_and_clear_bit(irq, &hvm_irq_dpci->dirq_mask);
         device = hvm_irq_dpci->mirq[irq].device;
         intx = hvm_irq_dpci->mirq[irq].intx;
         hvm_pci_intx_assert(d, device, intx);
+
+        /*
+         * Set a timer to see if the guest can finish the interrupt or not. For
+         * example, the guest OS may unmask the PIC during boot, before the
+         * guest driver is loaded. hvm_pci_intx_assert() may succeed, but the
+         * guest will never deal with the irq, then the physical interrupt line
+         * will never be deasserted.
+         */
+        set_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(irq)],
+                  NOW() + PT_IRQ_TIME_OUT);
     }
 }
 
diff -r bc4afcd4c612 -r e733e6b73d56 xen/arch/x86/hvm/vmx/vtd/dmar.c
--- a/xen/arch/x86/hvm/vmx/vtd/dmar.c   Fri Oct 19 09:31:03 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vtd/dmar.c   Fri Oct 19 11:26:58 2007 +0100
@@ -492,7 +492,6 @@ acpi_parse_dmar(unsigned long phys_addr,
 
 int acpi_dmar_init(void)
 {
-    extern int ioapic_ack_new;
     int rc;
 
     if (!vtd_enabled)
@@ -509,8 +508,5 @@ int acpi_dmar_init(void)
         return -ENODEV;
     }
 
-    /* Use fake-vector style of IOAPIC acknowledgement. */
-    ioapic_ack_new = 0;
-
-    return 0;
-}
+    return 0;
+}
diff -r bc4afcd4c612 -r e733e6b73d56 xen/arch/x86/hvm/vmx/vtd/io.c
--- a/xen/arch/x86/hvm/vmx/vtd/io.c     Fri Oct 19 09:31:03 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vtd/io.c     Fri Oct 19 11:26:58 2007 +0100
@@ -45,6 +45,18 @@
 #include <public/hvm/ioreq.h>
 #include <public/domctl.h>
 
+static void pt_irq_time_out(void *data)
+{
+    struct hvm_irq_dpci_mapping *irq_map = data;
+    unsigned int guest_gsi, machine_gsi;
+    struct domain *d = irq_map->dom;
+
+    guest_gsi = irq_map->guest_gsi;
+    machine_gsi = d->arch.hvm_domain.irq.dpci->girq[guest_gsi].machine_gsi;
+    clear_bit(machine_gsi, d->arch.hvm_domain.irq.dpci->dirq_mask);
+    hvm_dpci_eoi(irq_map->dom, guest_gsi, NULL);
+}
+
 int pt_irq_create_bind_vtd(
     struct domain *d, xen_domctl_bind_pt_irq_t *pt_irq_bind)
 {
@@ -76,17 +88,22 @@ int pt_irq_create_bind_vtd(
     hvm_irq_dpci->mirq[machine_gsi].device = device;
     hvm_irq_dpci->mirq[machine_gsi].intx = intx;
     hvm_irq_dpci->mirq[machine_gsi].guest_gsi = guest_gsi;
+    hvm_irq_dpci->mirq[machine_gsi].dom = d;
 
     hvm_irq_dpci->girq[guest_gsi].valid = 1;
     hvm_irq_dpci->girq[guest_gsi].device = device;
     hvm_irq_dpci->girq[guest_gsi].intx = intx;
     hvm_irq_dpci->girq[guest_gsi].machine_gsi = machine_gsi;
+    hvm_irq_dpci->girq[guest_gsi].dom = d;
 
-    /* Deal with gsi for legacy devices */
+    init_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(machine_gsi)],
+               pt_irq_time_out, &hvm_irq_dpci->mirq[machine_gsi], 0);
+
+    /* Deal with GSI for legacy devices. */
     pirq_guest_bind(d->vcpu[0], machine_gsi, BIND_PIRQ__WILL_SHARE);
     gdprintk(XENLOG_ERR,
-        "XEN_DOMCTL_irq_mapping: m_irq = %x device = %x intx = %x\n",
-        machine_gsi, device, intx);
+             "XEN_DOMCTL_irq_mapping: m_irq = %x device = %x intx = %x\n",
+             machine_gsi, device, intx);
 
     return 0;
 }
@@ -114,22 +131,25 @@ int hvm_do_IRQ_dpci(struct domain *d, un
         hvm_irq->dpci->girq[isa_irq].machine_gsi = mirq;
     }
 
-    if ( !test_and_set_bit(mirq, hvm_irq->dpci->dirq_mask) )
-    {
-        vcpu_kick(d->vcpu[0]);
-        return 1;
-    }
+    /*
+     * Set a timer here to avoid situations where the IRQ line is shared, and
+     * the device belonging to the pass-through guest is not yet active. In
+     * this case the guest may not pick up the interrupt (e.g., masked at the
+     * PIC) and we need to detect that.
+     */
+    set_bit(mirq, hvm_irq->dpci->dirq_mask);
+    set_timer(&hvm_irq->dpci->hvm_timer[irq_to_vector(mirq)],
+              NOW() + PT_IRQ_TIME_OUT);
+    vcpu_kick(d->vcpu[0]);
 
-    dprintk(XENLOG_INFO, "mirq already pending\n");
-    return 0;
+    return 1;
 }
 
-void hvm_dpci_eoi(unsigned int guest_gsi, union vioapic_redir_entry *ent)
+void hvm_dpci_eoi(struct domain *d, unsigned int guest_gsi,
+                  union vioapic_redir_entry *ent)
 {
-    struct domain *d = current->domain;
     struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     uint32_t device, intx, machine_gsi;
-    irq_desc_t *desc;
 
     ASSERT(spin_is_locked(&d->arch.hvm_domain.irq_lock));
 
@@ -137,17 +157,15 @@ void hvm_dpci_eoi(unsigned int guest_gsi
          !hvm_irq_dpci->girq[guest_gsi].valid )
         return;
 
+    machine_gsi = hvm_irq_dpci->girq[guest_gsi].machine_gsi;
+    stop_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(machine_gsi)]);
     device = hvm_irq_dpci->girq[guest_gsi].device;
     intx = hvm_irq_dpci->girq[guest_gsi].intx;
-    machine_gsi = hvm_irq_dpci->girq[guest_gsi].machine_gsi;
     gdprintk(XENLOG_INFO, "hvm_dpci_eoi:: device %x intx %x\n",
              device, intx);
     __hvm_pci_intx_deassert(d, device, intx);
-    if ( (ent == NULL) || (ent->fields.mask == 0) )
-    {
-        desc = &irq_desc[irq_to_vector(machine_gsi)];
-        desc->handler->end(irq_to_vector(machine_gsi));
-    }
+    if ( (ent == NULL) || !ent->fields.mask )
+        pirq_guest_eoi(d, machine_gsi);
 }
 
 void iommu_domain_destroy(struct domain *d)
diff -r bc4afcd4c612 -r e733e6b73d56 xen/arch/x86/hvm/vpic.c
--- a/xen/arch/x86/hvm/vpic.c   Fri Oct 19 09:31:03 2007 +0100
+++ b/xen/arch/x86/hvm/vpic.c   Fri Oct 19 11:26:58 2007 +0100
@@ -252,7 +252,8 @@ static void vpic_ioport_write(
                 if ( vtd_enabled )
                 {
                     irq |= ((addr & 0xa0) == 0xa0) ? 8 : 0;
-                    hvm_dpci_eoi(hvm_isa_irq_to_gsi(irq), NULL);
+                    hvm_dpci_eoi(current->domain,
+                                 hvm_isa_irq_to_gsi(irq), NULL);
                 }
                 break;
             case 6: /* Set Priority                */
diff -r bc4afcd4c612 -r e733e6b73d56 xen/include/asm-x86/hvm/io.h
--- a/xen/include/asm-x86/hvm/io.h      Fri Oct 19 09:31:03 2007 +0100
+++ b/xen/include/asm-x86/hvm/io.h      Fri Oct 19 11:26:58 2007 +0100
@@ -151,7 +151,8 @@ extern void handle_mmio(unsigned long gp
 extern void handle_mmio(unsigned long gpa);
 extern void hvm_interrupt_post(struct vcpu *v, int vector, int type);
 extern void hvm_io_assist(void);
-extern void hvm_dpci_eoi(unsigned int guest_irq, union vioapic_redir_entry 
*ent);
+extern void hvm_dpci_eoi(struct domain *d, unsigned int guest_irq,
+                         union vioapic_redir_entry *ent);
 
 #endif /* __ASM_X86_HVM_IO_H__ */
 
diff -r bc4afcd4c612 -r e733e6b73d56 xen/include/asm-x86/hvm/irq.h
--- a/xen/include/asm-x86/hvm/irq.h     Fri Oct 19 09:31:03 2007 +0100
+++ b/xen/include/asm-x86/hvm/irq.h     Fri Oct 19 11:26:58 2007 +0100
@@ -33,6 +33,7 @@ struct hvm_irq_dpci_mapping {
     uint8_t valid;
     uint8_t device;
     uint8_t intx;
+    struct domain *dom;
     union {
         uint8_t guest_gsi;
         uint8_t machine_gsi;
@@ -45,6 +46,7 @@ struct hvm_irq_dpci {
     /* Guest IRQ to guest device/intx mapping. */
     struct hvm_irq_dpci_mapping girq[NR_IRQS];
     DECLARE_BITMAP(dirq_mask, NR_IRQS);
+    struct timer hvm_timer[NR_IRQS];
 };
 
 struct hvm_irq {
diff -r bc4afcd4c612 -r e733e6b73d56 xen/include/asm-x86/iommu.h
--- a/xen/include/asm-x86/iommu.h       Fri Oct 19 09:31:03 2007 +0100
+++ b/xen/include/asm-x86/iommu.h       Fri Oct 19 11:26:58 2007 +0100
@@ -79,7 +79,8 @@ int hvm_do_IRQ_dpci(struct domain *d, un
 int hvm_do_IRQ_dpci(struct domain *d, unsigned int irq);
 int dpci_ioport_intercept(ioreq_t *p);
 int pt_irq_create_bind_vtd(struct domain *d,
-    xen_domctl_bind_pt_irq_t * pt_irq_bind);
+                           xen_domctl_bind_pt_irq_t *pt_irq_bind);
 
+#define PT_IRQ_TIME_OUT MILLISECS(8)
 
-#endif // _IOMMU_H_
+#endif /* _IOMMU_H_ */

_______________________________________________
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] vt-d: Allow pass-through of shared interrupts., Xen patchbot-unstable <=