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

[Xen-devel] [PATCH v2 3/3] x86/vioapic: bind interrupts to PVH Dom0



Add the glue in order to bind the PVH Dom0 GSI from bare metal. This is done
when Dom0 unmasks the vIO APIC pins, by fetching the current pin settings and
setting up the PIRQ, which will then be bound to Dom0.

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
Cc: Jan Beulich <jbeulich@xxxxxxxx>
Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
Changes since v1:
 - Mask the pin on error (instead of panicking).
 - Factor out the Dom0 specific code into a function.
 - Use the newly introduced allocate_and_map_gsi_pirq instead of
   physdev_map_pirq.
---
 xen/arch/x86/hvm/vioapic.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index abcc473c88..4544e11abe 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -158,6 +158,62 @@ static int vioapic_read(
     return X86EMUL_OKAY;
 }
 
+static int vioapic_dom0_map_gsi(unsigned int gsi, unsigned int trig,
+                                unsigned int pol)
+{
+    struct domain *d = current->domain;
+    xen_domctl_bind_pt_irq_t pt_irq_bind = {
+        .irq_type = PT_IRQ_TYPE_PCI,
+        .machine_irq = gsi,
+        .hvm_domid = DOMID_SELF,
+    };
+    int ret, pirq = gsi;
+
+    ASSERT(is_hardware_domain(d));
+
+    /* Interrupt has been unmasked, bind it now. */
+    ret = mp_register_gsi(gsi, trig, pol);
+    if ( ret && ret != -EEXIST )
+    {
+        gdprintk(XENLOG_WARNING, "vioapic: error registering GSI %u: %d\n",
+                 gsi, ret);
+        goto error;
+    }
+    else if ( ret )
+        /* Already in use. */
+        return 0;
+
+    ret = allocate_and_map_gsi_pirq(d, &pirq, &pirq);
+    if ( ret )
+    {
+        gdprintk(XENLOG_WARNING, "vioapic: error mapping GSI %u: %d\n",
+                 gsi, ret);
+        goto error;
+    }
+
+    pcidevs_lock();
+    ret = pt_irq_create_bind(d, &pt_irq_bind);
+    pcidevs_unlock();
+    if ( ret )
+    {
+        gdprintk(XENLOG_WARNING, "vioapic: error binding GSI %u: %d\n",
+                 gsi, ret);
+        goto error_unmap;
+    }
+
+    return 0;
+
+ error_unmap:
+    pcidevs_lock();
+    spin_lock(&d->event_lock);
+    unmap_domain_pirq(d, pirq);
+    spin_unlock(&d->event_lock);
+    pcidevs_unlock();
+ error:
+    ASSERT(ret);
+    return ret;
+}
+
 static void vioapic_write_redirent(
     struct hvm_vioapic *vioapic, unsigned int idx,
     int top_word, uint32_t val)
@@ -188,6 +244,20 @@ static void vioapic_write_redirent(
         unmasked = unmasked && !ent.fields.mask;
     }
 
+    if ( is_hardware_domain(d) && unmasked )
+    {
+        int ret;
+
+        ret = vioapic_dom0_map_gsi(gsi, ent.fields.trig_mode,
+                                   ent.fields.polarity);
+        if ( ret )
+        {
+            /* Mask the entry again. */
+            ent.fields.mask = 1;
+            unmasked = 0;
+        }
+    }
+
     *pent = ent;
 
     if ( gsi == 0 )
-- 
2.11.0 (Apple Git-81)


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

 


Rackspace

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