[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 2/3] multiboot2: parse console= and vga= options when setting GOP mode


  • To: Roger Pau Monne <roger.pau@xxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Wed, 5 Apr 2023 12:15:26 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ia8dCuqc76h37XZyZZCOtQqagUqNbWQ4NOC/+flu5jM=; b=U3UDWhnesnxZ/llDrraQPi3wr6D0Nl/0WQUn+7Yrh0+/VXncI5C88VJKpLhJuBRjOic15Ib2Eu8rQ2LxY8nsqLHCrDtHRPA2uU5xRWpze/NonLb0gAMV5In5b13AFy8EqyN0L2rdKZ0xjo64Iyua+CGIS5gJsjJsHYS+ldPckHtT9Gj8AHXq+0zkLS1k1kI1MXyTtIdA8lk6OXG/+JGpNb/dE5fOMG/F5fW+ionaVZXSO8gmqWrv3m3UYU4x8COQsrj86SV/47vMxUgcHXYfs9KdJAXbjVCjIAJuNJ7qkOpPTp15vOWyeEhXfceBpd2NdNPVcOYukXJ/Q6pNHc9XQA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Qy/7cb2mDISNV3/gwl2/8YwPzZfAY8CfbZ7+9ylJjvXoRBgM35AxFNuf1yu4CiS/wkm5GxSH8QgTDEWQslWM56XvC+l71GYx1aAbs0Us4NCpv8ZMMsal/FoOz5SwAEgCugNl3VN+VN4EsEMQWYvu5G7ZMqL6OnLIISv0v/RvjNmwa1K3x1q6MsFD6/5YisNVC23CoUK8Ny48wX4WErng96QDDALVAyg0iBjQwxnkfXnC20c9YnkpYcQi3ZsnOyKEZvyC6m4kax0E4Ru0FvjOsfJOXRd8+BI0gqgQscrS2fuZFXxBAMjow0drIXRYnXt3ApZCyKSeSlbHRyWbQaLBZw==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Wed, 05 Apr 2023 10:15:52 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 31.03.2023 11:59, Roger Pau Monne wrote:
> Only set the GOP mode if vga is selected in the console option,

This particular aspect of the behavior is inconsistent with legacy
boot behavior: There "vga=" isn't qualified by what "console=" has.

> otherwise just fetch the information from the current mode in order to
> make it available to dom0.
> 
> Introduce support for passing the command line to the efi_multiboot2()
> helper, and parse the console= and vga= options if present.
> 
> Add support for the 'gfx' and 'current' vga options, ignore the 'keep'
> option, and print a warning message about other options not being
> currently implemented.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
>[...] 
> --- a/xen/arch/x86/efi/efi-boot.h
> +++ b/xen/arch/x86/efi/efi-boot.h
> @@ -786,7 +786,30 @@ static bool __init 
> efi_arch_use_config_file(EFI_SYSTEM_TABLE *SystemTable)
>  
>  static void __init efi_arch_flush_dcache_area(const void *vaddr, UINTN size) 
> { }
>  
> -void __init efi_multiboot2(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE 
> *SystemTable)
> +/* Return the next occurrence of opt in cmd. */
> +static const char __init *get_option(const char *cmd, const char *opt)
> +{
> +    const char *s = cmd, *o = NULL;
> +
> +    if ( !cmd || !opt )

I can see why you need to check "cmd", but there's no need to check "opt"
I would say.

> @@ -807,7 +830,60 @@ void __init efi_multiboot2(EFI_HANDLE ImageHandle, 
> EFI_SYSTEM_TABLE *SystemTable
>  
>      if ( gop )
>      {
> -        gop_mode = efi_find_gop_mode(gop, 0, 0, 0);
> +        const char *opt = NULL, *last = cmdline;
> +        /* Default console selection is "com1,vga". */
> +        bool vga = true;
> +
> +        /* For the console option the last occurrence is the enforced one. */
> +        while ( (last = get_option(last, "console=")) != NULL )
> +            opt = last;
> +
> +        if ( opt )
> +        {
> +            const char *s = strstr(opt, "vga");
> +
> +            if ( !s || s > strpbrk(opt, " ") )

Why strpbrk() and not the simpler strchr()? Or did you mean to also look
for tabs, but then didn't include \t here (and in get_option())? (Legacy
boot code also takes \r and \n as separators, btw, but I'm unconvinced
of the need.)

Also aiui this is UB when the function returns NULL, as relational operators
(excluding equality ones) may only be applied when both addresses refer to
the same object (or to the end of an involved array).

> +                vga = false;
> +        }
> +
> +        if ( vga )
> +        {
> +            unsigned int width = 0, height = 0, depth = 0;
> +            bool keep_current = false;
> +
> +            last = cmdline;
> +            while ( (last = get_option(last, "vga=")) != NULL )

It's yet different for "vga=", I'm afraid: Early boot code (boot/cmdline.c)
finds the first instance only. Normal command line handling respects the
last instance only. So while "vga=gfx-... vga=keep" will have the expected
effect, "vga=keep vga=gfx-..." won't (I think). It is certainly fine to be
less inflexible here, but I think this then wants accompanying by an update
to the command line doc, no matter that presently it doesn't really
describe these peculiarities. Otoh it would end up being slightly cheaper
to only look for the first instance here as well. In particular ...

> +            {
> +                if ( !strncmp(last, "gfx-", 4) )
> +                {
> +                    width = simple_strtoul(last + 4, &last, 10);
> +                    if ( *last == 'x' )
> +                        height = simple_strtoul(last + 1, &last, 10);
> +                    if ( *last == 'x' )
> +                        depth = simple_strtoul(last + 1, &last, 10);
> +                    /* Allow depth to be 0 or unset. */
> +                    if ( !width || !height )
> +                        width = height = depth = 0;
> +                    keep_current = false;
> +                }
> +                else if ( !strncmp(last, "current", 7) )
> +                    keep_current = true;
> +                else if ( !strncmp(last, "keep", 4) )
> +                {
> +                    /* Ignore. */
> +                }
> +                else
> +                {
> +                    /* Fallback to defaults if unimplemented. */
> +                    width = height = depth = 0;
> +                    keep_current = false;

... this zapping of what was successfully parsed before would then not be
needed in any event (else I would question why this is necessary).

Jan



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.