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....@citrix.com> --- Cc: Jan Beulich <jbeul...@suse.com> Cc: Andrew Cooper <andrew.coop...@citrix.com> --- 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@lists.xen.org https://lists.xen.org/xen-devel