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

[Xen-changelog] [xen master] x86/hvm: convert gsi_assert_count into a variable size array



commit 6cbc358a1416025d057fd1866b8e37d907cc0662
Author:     Roger Pau Monné <roger.pau@xxxxxxxxxx>
AuthorDate: Tue Apr 4 12:46:14 2017 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Apr 4 12:46:14 2017 +0200

    x86/hvm: convert gsi_assert_count into a variable size array
    
    Rearrange the fields of hvm_irq so that gsi_assert_count can be converted 
into
    a variable size array and add a new field to account the number of GSIs.
    
    Due to this changes the irq member in the hvm_domain struct also needs to
    become a pointer set at runtime.
    
    Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c           | 14 +++++++++++++-
 xen/arch/x86/hvm/irq.c           | 27 ++++++++++++++++++++++-----
 xen/include/asm-x86/domain.h     |  2 +-
 xen/include/asm-x86/hvm/domain.h |  2 +-
 xen/include/asm-x86/hvm/irq.h    | 28 +++++++++++++++-------------
 5 files changed, 52 insertions(+), 21 deletions(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 47a0d32..2e76c23 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -619,11 +619,19 @@ int hvm_domain_initialise(struct domain *d)
     d->arch.hvm_domain.params = xzalloc_array(uint64_t, HVM_NR_PARAMS);
     d->arch.hvm_domain.io_handler = xzalloc_array(struct hvm_io_handler,
                                                   NR_IO_HANDLERS);
+    d->arch.hvm_domain.irq = xzalloc_bytes(hvm_irq_size(NR_HVM_DOMU_IRQS));
+
     rc = -ENOMEM;
-    if ( !d->arch.hvm_domain.pl_time ||
+    if ( !d->arch.hvm_domain.pl_time || !d->arch.hvm_domain.irq ||
          !d->arch.hvm_domain.params  || !d->arch.hvm_domain.io_handler )
         goto fail1;
 
+    /* Set the default number of GSIs */
+    hvm_domain_irq(d)->nr_gsis = NR_HVM_DOMU_IRQS;
+
+    BUILD_BUG_ON(NR_HVM_DOMU_IRQS < NR_ISAIRQS);
+    ASSERT(hvm_domain_irq(d)->nr_gsis >= NR_ISAIRQS);
+
     /* need link to containing domain */
     d->arch.hvm_domain.pl_time->domain = d;
 
@@ -680,6 +688,7 @@ int hvm_domain_initialise(struct domain *d)
     xfree(d->arch.hvm_domain.io_handler);
     xfree(d->arch.hvm_domain.params);
     xfree(d->arch.hvm_domain.pl_time);
+    xfree(d->arch.hvm_domain.irq);
  fail0:
     hvm_destroy_cacheattr_region_list(d);
     return rc;
@@ -722,6 +731,9 @@ void hvm_domain_destroy(struct domain *d)
 
     xfree(d->arch.hvm_domain.pl_time);
     d->arch.hvm_domain.pl_time = NULL;
+
+    xfree(d->arch.hvm_domain.irq);
+    d->arch.hvm_domain.irq = NULL;
 }
 
 static int hvm_save_tsc_adjust(struct domain *d, hvm_domain_context_t *h)
diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c
index c2951cc..8625584 100644
--- a/xen/arch/x86/hvm/irq.c
+++ b/xen/arch/x86/hvm/irq.c
@@ -69,6 +69,11 @@ static void __hvm_pci_intx_assert(
         return;
 
     gsi = hvm_pci_intx_gsi(device, intx);
+    if ( gsi >= hvm_irq->nr_gsis )
+    {
+        ASSERT_UNREACHABLE();
+        return;
+    }
     if ( hvm_irq->gsi_assert_count[gsi]++ == 0 )
         assert_gsi(d, gsi);
 
@@ -99,6 +104,11 @@ static void __hvm_pci_intx_deassert(
         return;
 
     gsi = hvm_pci_intx_gsi(device, intx);
+    if ( gsi >= hvm_irq->nr_gsis )
+    {
+        ASSERT_UNREACHABLE();
+        return;
+    }
     --hvm_irq->gsi_assert_count[gsi];
 
     link    = hvm_pci_intx_link(device, intx);
@@ -363,7 +373,7 @@ void hvm_set_callback_via(struct domain *d, uint64_t via)
     {
     case HVMIRQ_callback_gsi:
         gsi = hvm_irq->callback_via.gsi = (uint8_t)via;
-        if ( (gsi == 0) || (gsi >= ARRAY_SIZE(hvm_irq->gsi_assert_count)) )
+        if ( (gsi == 0) || (gsi >= hvm_irq->nr_gsis) )
             hvm_irq->callback_via_type = HVMIRQ_callback_none;
         else if ( hvm_irq->callback_via_asserted &&
                   (hvm_irq->gsi_assert_count[gsi]++ == 0) )
@@ -419,9 +429,9 @@ struct hvm_intack hvm_vcpu_has_pending_irq(struct vcpu *v)
     if ( unlikely(v->mce_pending) )
         return hvm_intack_mce;
 
-    if ( (plat->irq.callback_via_type == HVMIRQ_callback_vector)
+    if ( (plat->irq->callback_via_type == HVMIRQ_callback_vector)
          && vcpu_info(v, evtchn_upcall_pending) )
-        return hvm_intack_vector(plat->irq.callback_via.vector);
+        return hvm_intack_vector(plat->irq->callback_via.vector);
 
     if ( vlapic_accept_pic_intr(v) && plat->vpic[0].int_output )
         return hvm_intack_pic(0);
@@ -495,7 +505,7 @@ static void irq_dump(struct domain *d)
            (uint32_t) hvm_irq->isa_irq.pad[0], 
            hvm_irq->pci_link.route[0], hvm_irq->pci_link.route[1],
            hvm_irq->pci_link.route[2], hvm_irq->pci_link.route[3]);
-    for ( i = 0 ; i < VIOAPIC_NUM_PINS; i += 8 )
+    for ( i = 0; i < hvm_irq->nr_gsis && i + 8 <= hvm_irq->nr_gsis; i += 8 )
         printk("GSI [%x - %x] %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8
                " %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8"\n",
                i, i+7,
@@ -507,6 +517,13 @@ static void irq_dump(struct domain *d)
                hvm_irq->gsi_assert_count[i+5],
                hvm_irq->gsi_assert_count[i+6],
                hvm_irq->gsi_assert_count[i+7]);
+    if ( i != hvm_irq->nr_gsis )
+    {
+        printk("GSI [%x - %x]", i, hvm_irq->nr_gsis - 1);
+        for ( ; i < hvm_irq->nr_gsis; i++)
+            printk(" %2"PRIu8, hvm_irq->gsi_assert_count[i]);
+        printk("\n");
+    }
     printk("Link %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8"\n",
            hvm_irq->pci_link_assert_count[0],
            hvm_irq->pci_link_assert_count[1],
@@ -601,7 +618,7 @@ static int irq_load_pci(struct domain *d, 
hvm_domain_context_t *h)
         hvm_irq->pci_link_assert_count[link] = 0;
     
     /* Clear the GSI link assert counts */
-    for ( gsi = 0; gsi < VIOAPIC_NUM_PINS; gsi++ )
+    for ( gsi = 0; gsi < hvm_irq->nr_gsis; gsi++ )
         hvm_irq->gsi_assert_count[gsi] = 0;
 
     /* Recalculate the counts from the IRQ line state */
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index ec14cce..6420ca2 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -17,7 +17,7 @@
 #define is_pv_32bit_vcpu(v)    (is_pv_32bit_domain((v)->domain))
 
 #define is_hvm_pv_evtchn_domain(d) (is_hvm_domain(d) && \
-        d->arch.hvm_domain.irq.callback_via_type == HVMIRQ_callback_vector)
+        (d)->arch.hvm_domain.irq->callback_via_type == HVMIRQ_callback_vector)
 #define is_hvm_pv_evtchn_vcpu(v) (is_hvm_pv_evtchn_domain(v->domain))
 #define is_domain_direct_mapped(d) ((void)(d), 0)
 
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index 420cbdc..c3cca94 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -125,7 +125,7 @@ struct hvm_domain {
 
     /* Lock protects access to irq, vpic and vioapic. */
     spinlock_t             irq_lock;
-    struct hvm_irq         irq;
+    struct hvm_irq        *irq;
     struct hvm_hw_vpic     vpic[2]; /* 0=master; 1=slave */
     struct hvm_vioapic    *vioapic;
     struct hvm_hw_stdvga   stdvga;
diff --git a/xen/include/asm-x86/hvm/irq.h b/xen/include/asm-x86/hvm/irq.h
index 17a957d..7d45293 100644
--- a/xen/include/asm-x86/hvm/irq.h
+++ b/xen/include/asm-x86/hvm/irq.h
@@ -67,18 +67,6 @@ struct hvm_irq {
     u8 pci_link_assert_count[4];
 
     /*
-     * Number of wires asserting each GSI.
-     * 
-     * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space
-     * except ISA IRQ 0, which is connected to GSI 2.
-     * PCI links map into this space via the PCI-ISA bridge.
-     * 
-     * GSIs 16+ are used only be PCI devices. The mapping from PCI device to
-     * GSI is as follows: ((device*4 + device/8 + INTx#) & 31) + 16
-     */
-    u8 gsi_assert_count[VIOAPIC_NUM_PINS];
-
-    /*
      * GSIs map onto PIC/IO-APIC in the usual way:
      *  0-7:  Master 8259 PIC, IO-APIC pins 0-7
      *  8-15: Slave  8259 PIC, IO-APIC pins 8-15
@@ -89,13 +77,27 @@ struct hvm_irq {
     u8 round_robin_prev_vcpu;
 
     struct hvm_irq_dpci *dpci;
+
+    /*
+     * Number of wires asserting each GSI.
+     *
+     * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space
+     * except ISA IRQ 0, which is connected to GSI 2.
+     * PCI links map into this space via the PCI-ISA bridge.
+     *
+     * GSIs 16+ are used only be PCI devices. The mapping from PCI device to
+     * GSI is as follows: ((device*4 + device/8 + INTx#) & 31) + 16
+     */
+    unsigned int nr_gsis;
+    u8 gsi_assert_count[];
 };
 
 #define hvm_pci_intx_gsi(dev, intx)  \
     (((((dev)<<2) + ((dev)>>3) + (intx)) & 31) + 16)
 #define hvm_pci_intx_link(dev, intx) \
     (((dev) + (intx)) & 3)
-#define hvm_domain_irq(d) (&(d)->arch.hvm_domain.irq)
+#define hvm_domain_irq(d) ((d)->arch.hvm_domain.irq)
+#define hvm_irq_size(cnt) offsetof(struct hvm_irq, gsi_assert_count[cnt])
 
 #define hvm_isa_irq_to_gsi(isa_irq) ((isa_irq) ? : 2)
 
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.