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] vtd: Dynamically allocate IRQ-tracking st

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] vtd: Dynamically allocate IRQ-tracking structures, only for those
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 02 Oct 2007 17:40:24 -0700
Delivery-date: Tue, 02 Oct 2007 18:27:18 -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 1191340747 -3600
# Node ID c2871913c5c2c09e54169ce86af73ec1314554d9
# Parent  e1b574bc36b5068baf0053da32f8ca11a907625a
vtd: Dynamically allocate IRQ-tracking structures, only for those
domains that actually have PCI-passthru devices. Greatly reduces size
of 'struct domain'.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/vmx/intr.c   |   21 ++++++----
 xen/arch/x86/hvm/vmx/vtd/io.c |   83 ++++++++++++++++++++++++++----------------
 xen/include/asm-x86/hvm/irq.h |   16 +++++---
 3 files changed, 74 insertions(+), 46 deletions(-)

diff -r e1b574bc36b5 -r c2871913c5c2 xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c       Tue Oct 02 16:28:58 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/intr.c       Tue Oct 02 16:59:07 2007 +0100
@@ -107,19 +107,23 @@ static void enable_intr_window(struct vc
     }
 }
 
-static void vmx_dirq_assist(struct domain *d)
+static void vmx_dirq_assist(struct vcpu *v)
 {
     unsigned int irq;
     uint32_t device, intx;
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct domain *d = v->domain;
+    struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
 
-    for ( irq = find_first_bit(hvm_irq->dirq_mask, NR_IRQS);
+    if ( !vtd_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
+        return;
+
+    for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, NR_IRQS);
           irq < NR_IRQS;
-          irq = find_next_bit(hvm_irq->dirq_mask, NR_IRQS, irq + 1) )
+          irq = find_next_bit(hvm_irq_dpci->dirq_mask, NR_IRQS, irq + 1) )
     {
-        test_and_clear_bit(irq, &hvm_irq->dirq_mask);
-        device = hvm_irq->mirq[irq].device;
-        intx = hvm_irq->mirq[irq].intx;
+        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);
     }
 }
@@ -134,8 +138,7 @@ asmlinkage void vmx_intr_assist(void)
     /* Crank the handle on interrupt state. */
     pt_update_irq(v);
 
-    if ( vtd_enabled && (v->vcpu_id == 0) )
-        vmx_dirq_assist(v->domain);
+    vmx_dirq_assist(v);
   
     hvm_set_callback_irq_level();
 
diff -r e1b574bc36b5 -r c2871913c5c2 xen/arch/x86/hvm/vmx/vtd/io.c
--- a/xen/arch/x86/hvm/vmx/vtd/io.c     Tue Oct 02 16:28:58 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vtd/io.c     Tue Oct 02 16:59:07 2007 +0100
@@ -46,27 +46,41 @@
 #include <public/domctl.h>
 
 int pt_irq_create_bind_vtd(
-    struct domain *d,
-    xen_domctl_bind_pt_irq_t * pt_irq_bind)
+    struct domain *d, xen_domctl_bind_pt_irq_t *pt_irq_bind)
 {
-    struct hvm_domain *hd = &d->arch.hvm_domain;
+    struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     uint32_t machine_gsi, guest_gsi;
     uint32_t device, intx;
+
+    if ( hvm_irq_dpci == NULL )
+    {
+        hvm_irq_dpci = xmalloc(struct hvm_irq_dpci);
+        if ( hvm_irq_dpci == NULL )
+            return -ENOMEM;
+
+        memset(hvm_irq_dpci, 0, sizeof(*hvm_irq_dpci));
+
+        if ( cmpxchg((unsigned long *)&d->arch.hvm_domain.irq.dpci,
+                     0, (unsigned long)hvm_irq_dpci) != 0 )
+            xfree(hvm_irq_dpci);
+
+        hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
+    }
 
     machine_gsi = pt_irq_bind->machine_irq;
     device = pt_irq_bind->u.pci.device;
     intx = pt_irq_bind->u.pci.intx;
     guest_gsi = hvm_pci_intx_gsi(device, intx);
 
-    hd->irq.mirq[machine_gsi].valid = 1;
-    hd->irq.mirq[machine_gsi].device = device;
-    hd->irq.mirq[machine_gsi].intx = intx;
-    hd->irq.mirq[machine_gsi].guest_gsi = guest_gsi;
+    hvm_irq_dpci->mirq[machine_gsi].valid = 1;
+    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;
 
-    hd->irq.girq[guest_gsi].valid = 1;
-    hd->irq.girq[guest_gsi].device = device;
-    hd->irq.girq[guest_gsi].intx = intx;
-    hd->irq.girq[guest_gsi].machine_gsi = machine_gsi;
+    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;
 
     /* Deal with gsi for legacy devices */
     pirq_guest_bind(d->vcpu[0], machine_gsi, BIND_PIRQ__WILL_SHARE);
@@ -76,31 +90,31 @@ int pt_irq_create_bind_vtd(
 
     return 0;
 }
+
 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;
+    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
 
-    if ( !vtd_enabled || (d == dom0) ||
-         !d->arch.hvm_domain.irq.mirq[mirq].valid )
+    if ( !vtd_enabled || (d == dom0) || (hvm_irq->dpci == NULL) ||
+         !hvm_irq->dpci->mirq[mirq].valid )
         return 0;
 
-    device = d->arch.hvm_domain.irq.mirq[mirq].device;
-    intx = d->arch.hvm_domain.irq.mirq[mirq].intx;
+    device = hvm_irq->dpci->mirq[mirq].device;
+    intx = hvm_irq->dpci->mirq[mirq].intx;
     link = hvm_pci_intx_link(device, intx);
-    hvm_irq = &d->arch.hvm_domain.irq;
     isa_irq = hvm_irq->pci_link.route[link];
 
-    if ( !d->arch.hvm_domain.irq.girq[isa_irq].valid )
+    if ( !hvm_irq->dpci->girq[isa_irq].valid )
     {
-        d->arch.hvm_domain.irq.girq[isa_irq].valid = 1;
-        d->arch.hvm_domain.irq.girq[isa_irq].device = device;
-        d->arch.hvm_domain.irq.girq[isa_irq].intx = intx;
-        d->arch.hvm_domain.irq.girq[isa_irq].machine_gsi = mirq;
+        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;
     }
 
-    if ( !test_and_set_bit(mirq, d->arch.hvm_domain.irq.dirq_mask) )
+    if ( !test_and_set_bit(mirq, hvm_irq->dpci->dirq_mask) )
     {
         vcpu_kick(d->vcpu[0]);
         return 1;
@@ -113,17 +127,19 @@ void hvm_dpci_eoi(unsigned int guest_gsi
 void hvm_dpci_eoi(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));
 
-    if ( !vtd_enabled || !d->arch.hvm_domain.irq.girq[guest_gsi].valid )
+    if ( !vtd_enabled || (hvm_irq_dpci == NULL) ||
+         !hvm_irq_dpci->girq[guest_gsi].valid )
         return;
 
-    device = d->arch.hvm_domain.irq.girq[guest_gsi].device;
-    intx = d->arch.hvm_domain.irq.girq[guest_gsi].intx;
-    machine_gsi = d->arch.hvm_domain.irq.girq[guest_gsi].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);
@@ -136,15 +152,20 @@ void hvm_dpci_eoi(unsigned int guest_gsi
 
 void iommu_domain_destroy(struct domain *d)
 {
-    struct hvm_domain *hd = &d->arch.hvm_domain;
+    struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     uint32_t i;
 
     if ( !vtd_enabled )
         return;
 
-    for ( i = 0; i < NR_IRQS; i++ )
-        if ( hd->irq.mirq[i].valid )
-            pirq_guest_unbind(d, i);
+    if ( hvm_irq_dpci != NULL )
+    {
+        for ( i = 0; i < NR_IRQS; i++ )
+            if ( hvm_irq_dpci->mirq[i].valid )
+                pirq_guest_unbind(d, i);
+        d->arch.hvm_domain.irq.dpci = NULL;
+        xfree(hvm_irq_dpci);
+    }
 
     iommu_domain_teardown(d);
 }
diff -r e1b574bc36b5 -r c2871913c5c2 xen/include/asm-x86/hvm/irq.h
--- a/xen/include/asm-x86/hvm/irq.h     Tue Oct 02 16:28:58 2007 +0100
+++ b/xen/include/asm-x86/hvm/irq.h     Tue Oct 02 16:59:07 2007 +0100
@@ -29,7 +29,7 @@
 #include <asm/hvm/vioapic.h>
 #include <public/hvm/save.h>
 
-struct hvm_irq_mapping {
+struct hvm_irq_dpci_mapping {
     uint8_t valid;
     uint8_t device;
     uint8_t intx;
@@ -37,6 +37,14 @@ struct hvm_irq_mapping {
         uint8_t guest_gsi;
         uint8_t machine_gsi;
     };
+};
+
+struct hvm_irq_dpci {
+    /* Machine IRQ to guest device/intx mapping. */
+    struct hvm_irq_dpci_mapping mirq[NR_IRQS];
+    /* Guest IRQ to guest device/intx mapping. */
+    struct hvm_irq_dpci_mapping girq[NR_IRQS];
+    DECLARE_BITMAP(dirq_mask, NR_IRQS);
 };
 
 struct hvm_irq {
@@ -99,11 +107,7 @@ struct hvm_irq {
     /* Last VCPU that was delivered a LowestPrio interrupt. */
     u8 round_robin_prev_vcpu;
 
-    /* machine irq to guest device/intx mapping */
-    struct hvm_irq_mapping mirq[NR_IRQS];
-    /* guest irq to guest device/intx mapping */
-    struct hvm_irq_mapping girq[NR_IRQS];
-    DECLARE_BITMAP(dirq_mask, NR_IRQS);
+    struct hvm_irq_dpci *dpci;
 };
 
 #define hvm_pci_intx_gsi(dev, intx)  \

_______________________________________________
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] vtd: Dynamically allocate IRQ-tracking structures, only for those, Xen patchbot-unstable <=