On August 13, 2019 4:04:34 AM PDT, Jan Kiszka <jan.kis...@siemens.com> wrote:
>On 13.08.19 11:32, h...@zytor.com wrote:
>> On August 12, 2019 4:06:50 AM PDT, Ralf Ramsauer
><ralf.ramsa...@oth-regensburg.de> 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 <ralf.ramsa...@oth-regensburg.de>
>>> ---
>>> 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.
>> 
>
>At least by the time the boot process for Linux under Jailhouse was
>designed 
>(~2015), ACPI was not able to express the minimal hardware we are
>exposing. So 
>we went for "CONFIG_ACPI disabled", and that was rather simple.
>
>There are some new knobs now to get rid of legacy platform components.
>But, 
>e.g., is it ACPI-compliant to expose a PM_TMR block, but nothing else?
>How would 
>you communicate pre-calibrated TSC and APIC frequencies?
>
>Thanks,
>Jan

If ACPI cannot represent something important, I'd like to bring that to the 
attention of the ACPI committee so we can standardize whatever is missing.
-- 
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 jailhouse-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/3D1CA272-5511-4082-9548-050ED4A0543E%40zytor.com.

Reply via email to