[PATCH 09/10] x86: jailhouse: Wire up IOAPIC for legacy UART ports

From: Jan Kiszka
Date: Thu Nov 16 2017 - 02:48:29 EST


From: Jan Kiszka <jan.kiszka@xxxxxxxxxxx>

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 <jan.kiszka@xxxxxxxxxxx>
---
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