]> xenbits.xensource.com Git - xen.git/commitdiff
x86, vt-d: Move out isa irq mapping from hvm_do_IRQ_dpci()
authorKeir Fraser <keir@xensource.com>
Mon, 29 Oct 2007 09:16:59 +0000 (09:16 +0000)
committerKeir Fraser <keir@xensource.com>
Mon, 29 Oct 2007 09:16:59 +0000 (09:16 +0000)
Setting isa irq mapping in hvm_do_IRQ_dpci() costs time when each
interrupt occurs, and it doesn't update isa irq mapping when pci_link
is updated.

Signed-off-by: Weidong Han <weidong.han@intel.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/hvm/irq.c
xen/arch/x86/hvm/vmx/vtd/io.c

index c19d23724eac36d917f7f467c81104351e12fe59..9d1d2d7e492f8678d6d410dc2ff453f53bc98692 100644 (file)
@@ -191,6 +191,18 @@ void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq)
         goto out;
     hvm_irq->pci_link.route[link] = isa_irq;
 
+    /* PCI pass-through fixup. */
+    if ( hvm_irq->dpci && hvm_irq->dpci->girq[old_isa_irq].valid )
+    {
+        uint32_t device = hvm_irq->dpci->girq[old_isa_irq].device;
+        uint32_t intx = hvm_irq->dpci->girq[old_isa_irq].intx;
+        if ( link == hvm_pci_intx_link(device, intx) )
+        {
+            hvm_irq->dpci->girq[isa_irq] = hvm_irq->dpci->girq[old_isa_irq];
+            hvm_irq->dpci->girq[old_isa_irq].valid = 0;
+        }
+    }
+
     if ( hvm_irq->pci_link_assert_count[link] == 0 )
         goto out;
 
index 81cf1ae609fe80d3d341041ecb710a8446ea8353..a724bb7986869aadbb552fa62d2e92768ddaab7d 100644 (file)
@@ -63,6 +63,7 @@ int pt_irq_create_bind_vtd(
     struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     uint32_t machine_gsi, guest_gsi;
     uint32_t device, intx;
+    uint32_t link, isa_irq;
 
     if ( hvm_irq_dpci == NULL )
     {
@@ -83,6 +84,8 @@ int pt_irq_create_bind_vtd(
     device = pt_irq_bind->u.pci.device;
     intx = pt_irq_bind->u.pci.intx;
     guest_gsi = hvm_pci_intx_gsi(device, intx);
+    link = hvm_pci_intx_link(device, intx);
+    isa_irq = d->arch.hvm_domain.irq.pci_link.route[link];
 
     hvm_irq_dpci->mirq[machine_gsi].valid = 1;
     hvm_irq_dpci->mirq[machine_gsi].device = device;
@@ -96,6 +99,12 @@ int pt_irq_create_bind_vtd(
     hvm_irq_dpci->girq[guest_gsi].machine_gsi = machine_gsi;
     hvm_irq_dpci->girq[guest_gsi].dom = d;
 
+    hvm_irq_dpci->girq[isa_irq].valid = 1;
+    hvm_irq_dpci->girq[isa_irq].device = device;
+    hvm_irq_dpci->girq[isa_irq].intx = intx;
+    hvm_irq_dpci->girq[isa_irq].machine_gsi = machine_gsi;
+    hvm_irq_dpci->girq[isa_irq].dom = d;
+
     init_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(machine_gsi)],
                pt_irq_time_out, &hvm_irq_dpci->mirq[machine_gsi], 0);
 
@@ -110,27 +119,12 @@ int pt_irq_create_bind_vtd(
 
 int hvm_do_IRQ_dpci(struct domain *d, unsigned int mirq)
 {
-    uint32_t device, intx;
-    uint32_t link, isa_irq;
     struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
 
     if ( !vtd_enabled || (d == dom0) || (hvm_irq->dpci == NULL) ||
          !hvm_irq->dpci->mirq[mirq].valid )
         return 0;
 
-    device = hvm_irq->dpci->mirq[mirq].device;
-    intx = hvm_irq->dpci->mirq[mirq].intx;
-    link = hvm_pci_intx_link(device, intx);
-    isa_irq = hvm_irq->pci_link.route[link];
-
-    if ( !hvm_irq->dpci->girq[isa_irq].valid )
-    {
-        hvm_irq->dpci->girq[isa_irq].valid = 1;
-        hvm_irq->dpci->girq[isa_irq].device = device;
-        hvm_irq->dpci->girq[isa_irq].intx = intx;
-        hvm_irq->dpci->girq[isa_irq].machine_gsi = mirq;
-    }
-
     /*
      * 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