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

[Xen-devel] [PATCH 5/5] x86/vioapic: allow PVHv2 Dom0 to have more than one IO APIC



The base address, id and number of pins of the vIO APICs exposed to PVHv2 Dom0
is the same as the values found on bare metal.

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
Cc: Jan Beulich <jbeulich@xxxxxxxx>
Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/domain_build.c | 33 +++++++++++------------------
 xen/arch/x86/hvm/vioapic.c  | 51 ++++++++++++++++++++++++++++++++++-----------
 2 files changed, 51 insertions(+), 33 deletions(-)

diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c
index dad3b4e..b9062ee 100644
--- a/xen/arch/x86/domain_build.c
+++ b/xen/arch/x86/domain_build.c
@@ -2271,12 +2271,7 @@ static int __init pvh_setup_acpi_madt(struct domain *d, 
paddr_t *addr)
     max_vcpus = dom0_max_vcpus();
     /* Calculate the size of the crafted MADT. */
     size = sizeof(*madt);
-    /*
-     * FIXME: the current vIO-APIC code just supports one IO-APIC instance
-     * per domain. This must be fixed in order to provide the same amount of
-     * IO APICs as available on bare metal.
-     */
-    size += sizeof(*io_apic);
+    size += sizeof(*io_apic) * nr_ioapics;
     size += sizeof(*intsrcovr) * acpi_intr_overrides;
     size += sizeof(*nmisrc) * acpi_nmi_sources;
     size += sizeof(*x2apic) * max_vcpus;
@@ -2304,23 +2299,19 @@ static int __init pvh_setup_acpi_madt(struct domain *d, 
paddr_t *addr)
      */
     madt->header.revision = min_t(unsigned char, table->revision, 4);
 
-    /*
-     * Setup the IO APIC entry.
-     * FIXME: the current vIO-APIC code just supports one IO-APIC instance
-     * per domain. This must be fixed in order to provide the same amount of
-     * IO APICs as available on bare metal, and with the same IDs as found in
-     * the native IO APIC MADT entries.
-     */
-    if ( nr_ioapics > 1 )
-        printk("WARNING: found %d IO APICs, Dom0 will only have access to 1 
emulated IO APIC\n",
-               nr_ioapics);
+    /* Setup the IO APIC entries. */
     io_apic = (void *)(madt + 1);
-    io_apic->header.type = ACPI_MADT_TYPE_IO_APIC;
-    io_apic->header.length = sizeof(*io_apic);
-    io_apic->id = domain_vioapic(d, 0)->id;
-    io_apic->address = VIOAPIC_DEFAULT_BASE_ADDRESS;
+    for ( i = 0; i < nr_ioapics; i++ )
+    {
+        io_apic->header.type = ACPI_MADT_TYPE_IO_APIC;
+        io_apic->header.length = sizeof(*io_apic);
+        io_apic->id = domain_vioapic(d, i)->id;
+        io_apic->address = domain_vioapic(d, i)->base_address;
+        io_apic->global_irq_base = apic_gsi_base(i);
+        io_apic++;
+    }
 
-    x2apic = (void *)(io_apic + 1);
+    x2apic = (void *)io_apic;
     for ( i = 0; i < max_vcpus; i++ )
     {
         x2apic->header.type = ACPI_MADT_TYPE_LOCAL_X2APIC;
diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index 6421971..1467b25 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -629,15 +629,25 @@ void vioapic_reset(struct domain *d)
                sizeof(*vioapic->redirtbl) * vioapic->nr_pins);
         for ( j = 0; j < vioapic->nr_pins; j++ )
             vioapic->redirtbl[j].fields.mask = 1;
-        vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS +
-                                VIOAPIC_MEM_LENGTH * i;
-        vioapic->id = i;
+        if ( !is_hardware_domain(d) )
+        {
+            vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS +
+                                    VIOAPIC_MEM_LENGTH * i;
+            vioapic->id = i;
+        }
+        else
+        {
+            vioapic->base_address = mp_ioapics[i].mpc_apicaddr;
+            vioapic->id = mp_ioapics[i].mpc_apicid;
+        }
         vioapic->ioregsel = 0;
     }
 }
 
 int vioapic_init(struct domain *d)
 {
+    unsigned int i, nr_vioapics = is_hardware_domain(d) ? nr_ioapics : 1;
+
     if ( !has_vioapic(d) )
     {
         d->arch.hvm_domain.nr_vioapics = 0;
@@ -646,24 +656,41 @@ int vioapic_init(struct domain *d)
 
     if ( (d->arch.hvm_domain.vioapic == NULL) &&
          ((d->arch.hvm_domain.vioapic =
-           xmalloc(struct hvm_hw_vioapic)) == NULL) )
+           xzalloc_array(struct hvm_hw_vioapic, nr_vioapics)) == NULL) )
         return -ENOMEM;
 
-    domain_vioapic(d, 0)->redirtbl = xmalloc_array(union vioapic_redir_entry,
-                                                   VIOAPIC_NUM_PINS);
-    if ( !domain_vioapic(d, 0)->redirtbl )
+    if ( !is_hardware_domain(d) )
     {
-        xfree(d->arch.hvm_domain.vioapic);
-        return -ENOMEM;
+        ASSERT(nr_vioapics == 1);
+        domain_vioapic(d, 0)->redirtbl =
+            xmalloc_array(union vioapic_redir_entry, VIOAPIC_NUM_PINS);
+        if ( !domain_vioapic(d, 0)->redirtbl )
+            goto error;
+        domain_vioapic(d, 0)->nr_pins = VIOAPIC_NUM_PINS;
+    }
+    else
+    {
+        for ( i = 0; i < nr_vioapics; i++ )
+        {
+            domain_vioapic(d, i)->redirtbl =
+                xmalloc_array(union vioapic_redir_entry, nr_ioapic_entries[i]);
+            if ( !domain_vioapic(d, i)->redirtbl )
+                goto error;
+            domain_vioapic(d, i)->nr_pins = nr_ioapic_entries[i];
+        }
     }
 
-    domain_vioapic(d, 0)->nr_pins = VIOAPIC_NUM_PINS;
-    d->arch.hvm_domain.nr_vioapics = 1;
+    d->arch.hvm_domain.nr_vioapics = nr_vioapics;
     vioapic_reset(d);
-
     register_mmio_handler(d, &vioapic_mmio_ops);
 
     return 0;
+
+ error:
+    for ( i = 0; i < nr_vioapics; i++ )
+        xfree(domain_vioapic(d, i)->redirtbl);
+    xfree(d->arch.hvm_domain.vioapic);
+    return -ENOMEM;
 }
 
 void vioapic_deinit(struct domain *d)
-- 
2.10.1 (Apple Git-78)


_______________________________________________
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®.