On August 12, 2019 4:06:50 AM PDT, Ralf Ramsauer <[email protected]> wrote: >ACPI tables aren't available if Linux runs as guest of the hypervisor >Jailhouse. This makes the 8250 driver probe for all platform UARTs as >it assumes that all platform are present in case of !ACPI. Jailhouse >will stop execution of Linux guest due to port access violation. > >So far, these access violations could be solved by tuning the >8250.nr_uarts parameter but it has limitations: We can, e.g., only map >consecutive platform UARTs to Linux, and only in the sequence 0x3f8, >0x2f8, 0x3e8, 0x2e8. > >Beginning from setup_data version 2, Jailhouse will place information >of >available platform UARTs in setup_data. This allows for selective >activation of platform UARTs. > >This patch queries the setup_data version and activates only available >UARTS. It comes with backward compatibility, and will still support >older setup_data versions. In this case, Linux falls back to the old >behaviour. > >Signed-off-by: Ralf Ramsauer <[email protected]> >--- > arch/x86/include/uapi/asm/bootparam.h | 3 ++ > arch/x86/kernel/jailhouse.c | 75 ++++++++++++++++++++++++--- > 2 files changed, 72 insertions(+), 6 deletions(-) > >diff --git a/arch/x86/include/uapi/asm/bootparam.h >b/arch/x86/include/uapi/asm/bootparam.h >index 6163b1afa7b3..2244c493c3c5 100644 >--- a/arch/x86/include/uapi/asm/bootparam.h >+++ b/arch/x86/include/uapi/asm/bootparam.h >@@ -150,6 +150,9 @@ struct jailhouse_setup_data { > __u8 standard_ioapic; > __u8 cpu_ids[255]; > } __attribute__((packed)) v1; >+ struct { >+ __u32 flags; >+ } __attribute__((packed)) v2; > } __attribute__((packed)); > > /* The so-called "zeropage" */ >diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c >index e5ac35efc4b3..1c75de1496f3 100644 >--- a/arch/x86/kernel/jailhouse.c >+++ b/arch/x86/kernel/jailhouse.c >@@ -11,6 +11,7 @@ > #include <linux/acpi_pmtmr.h> > #include <linux/kernel.h> > #include <linux/reboot.h> >+#include <linux/serial_8250.h> > #include <asm/apic.h> > #include <asm/cpu.h> > #include <asm/hypervisor.h> >@@ -20,8 +21,13 @@ > #include <asm/reboot.h> > #include <asm/setup.h> > >+#define SETUP_DATA_FLAGS_PERMIT_PCUART(n) (1 << (n)) >+#define SETUP_DATA_FLAGS_HAS_PCUART(flags, n) \ >+ !!(flags & SETUP_DATA_FLAGS_PERMIT_PCUART(n)) >+ > static __initdata struct jailhouse_setup_data setup_data; >#define SETUP_DATA_V1_LEN (sizeof(setup_data.hdr) + >sizeof(setup_data.v1)) >+#define SETUP_DATA_V2_LEN (SETUP_DATA_V1_LEN + sizeof(setup_data.v2)) > > static unsigned int precalibrated_tsc_khz; > >@@ -78,11 +84,13 @@ static void __init >jailhouse_get_smp_config(unsigned int early) > .type = IOAPIC_DOMAIN_STRICT, > .ops = &mp_ioapic_irqdomain_ops, > }; >+#ifdef CONFIG_SERIAL_8250 > struct mpc_intsrc mp_irq = { > .type = MP_INTSRC, > .irqtype = mp_INT, > .irqflag = MP_IRQPOL_ACTIVE_HIGH | MP_IRQTRIG_EDGE, > }; >+#endif > unsigned int cpu; > > jailhouse_x2apic_init(); >@@ -99,12 +107,16 @@ static void __init >jailhouse_get_smp_config(unsigned int early) > if (setup_data.v1.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); >+#ifdef CONFIG_SERIAL_8250 >+ if (setup_data.hdr.version < 2) { >+ /* 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); >+ mp_irq.srcbusirq = mp_irq.dstirq = 4; >+ mp_save_irq(&mp_irq); >+ } >+#endif > } > } > >@@ -137,6 +149,42 @@ static int __init jailhouse_pci_arch_init(void) > return 0; > } > >+#ifdef CONFIG_SERIAL_8250 >+static const u16 pcuart_base[] = { >+ 0x3f8, >+ 0x2f8, >+ 0x3e8, >+ 0x2e8, >+}; >+ >+static void jailhouse_serial_fixup(int port, struct uart_port *up, >+ u32 *capabilites) >+{ >+ struct mpc_intsrc mp_irq = { >+ .type = MP_INTSRC, >+ .irqtype = mp_INT, >+ .irqflag = MP_IRQPOL_ACTIVE_HIGH | MP_IRQTRIG_EDGE, >+ }; >+ unsigned int n; >+ >+ for (n = 0; n < ARRAY_SIZE(pcuart_base); n++) { >+ if (pcuart_base[n] != up->iobase) >+ continue; >+ >+ if (SETUP_DATA_FLAGS_HAS_PCUART(setup_data.v2.flags, n)) { >+ pr_info("Enabling UART%u (port 0x%lx)\n", n, >+ up->iobase); >+ mp_irq.srcbusirq = mp_irq.dstirq = up->irq; >+ mp_save_irq(&mp_irq); >+ } else { >+ /* Deactivate UART if access isn't allowed */ >+ up->iobase = 0; >+ } >+ break; >+ } >+} >+#endif >+ > static void __init jailhouse_init_platform(void) > { > u64 pa_data = boot_params.hdr.setup_data; >@@ -186,7 +234,8 @@ static void __init jailhouse_init_platform(void) > if (setup_data.hdr.version == 0 || > setup_data.hdr.compatible_version != > JAILHOUSE_SETUP_REQUIRED_VERSION || >- (setup_data.hdr.version >= 1 && header.len < SETUP_DATA_V1_LEN)) >+ (setup_data.hdr.version == 1 && header.len < SETUP_DATA_V1_LEN) >|| >+ (setup_data.hdr.version >= 2 && header.len < SETUP_DATA_V2_LEN)) > goto unsupported; > > pmtmr_ioport = setup_data.v1.pm_timer_address; >@@ -202,6 +251,20 @@ static void __init jailhouse_init_platform(void) > * are none in a non-root cell. > */ > disable_acpi(); >+ >+#ifdef CONFIG_SERIAL_8250 >+ /* >+ * There are flags inside setup_data that indicate availability of >+ * platform UARTs since setup data version 2. >+ * >+ * In case of version 1, we don't know which UARTs belong Linux. In >+ * this case, unconditionally register 1:1 mapping for legacy UART >IRQs >+ * 3 and 4. >+ */ >+ if (setup_data.hdr.version > 1) >+ serial8250_set_isa_configurator(jailhouse_serial_fixup); >+#endif >+ > return; > > unsupported:
Or you could, you know, pass a data structure that already does this... it's called DSDT. -- Sent from my Android device with K-9 Mail. Please excuse my brevity. -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/jailhouse-dev/D0A95275-25B7-4206-82D8-50B2C250F275%40zytor.com.
