From: Jan Kiszka <[email protected]> The typical I/O interrupts in non-root cells are MSI-based. However, the platform UARTs do not support MSI. In order to run a non-root cell that shall be use one of them, we need to register the standard IOAPIC and set 1:1 routing for IRQ 3 and 4.
If an IOAPIC is not available, the boot loader clears standard_ioapic in the setup data, and we skip the registration. If we should not be allowed to use one of those pins, Jailhouse will simply ignore our accesses. Signed-off-by: Jan Kiszka <[email protected]> --- arch/x86/kernel/jailhouse.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index 0bcca175c35e..05459ea0ecc7 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -17,6 +17,7 @@ #include <asm/cpu.h> #include <asm/hypervisor.h> #include <asm/i8259.h> +#include <asm/irqdomain.h> #include <asm/reboot.h> #include <asm/setup.h> @@ -148,6 +149,14 @@ static unsigned int x2apic_get_apic_id(unsigned long id) static void __init jailhouse_init_platform(void) { + struct ioapic_domain_cfg ioapic_cfg = { + .type = IOAPIC_DOMAIN_STRICT, + .ops = &mp_ioapic_irqdomain_ops, + }; + struct mpc_intsrc mp_irq = { + .type = MP_INTSRC, + .irqtype = mp_INT, + }; u64 pa_data = boot_params.hdr.setup_data; struct jailhouse_setup_data *data; unsigned int cpu; @@ -189,6 +198,17 @@ static void __init jailhouse_init_platform(void) boot_cpu_apic_version); smp_found_config = 1; + if (data->standard_ioapic) { + mp_register_ioapic(0, 0xfec00000, gsi_top, &ioapic_cfg); + + /* Register 1:1 mapping for legacy UART IRQs 3 and 4 */ + mp_irq.srcbusirq = mp_irq.dstirq = 3; + mp_save_irq(&mp_irq); + + mp_irq.srcbusirq = mp_irq.dstirq = 4; + mp_save_irq(&mp_irq); + } + early_memunmap(data, sizeof(*data)); /* -- 2.12.3

