[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
On 30.05.2023 18:02, Roger Pau Monné wrote: > On Wed, Apr 05, 2023 at 12:15:26PM +0200, Jan Beulich wrote: >> 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. > > Hm, I find this very odd, why would we fiddle with the VGA (or the GOP > here) if we don't intend to use it for output? Because we also need to arrange for what Dom0 possibly wants to use. It has no way of setting the mode the low-level (BIOS or EFI) way. >>> 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. > > Given this is executed without a page-fault handler in place I thought > it was best to be safe rather than sorry, and avoid any pointer > dereferences. Hmm, I see. We don't do so elsewhere, though, I think. >>> @@ -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.) > > I was originally checking for more characters here and didn't switch > when removing those. I will add \t. > >> 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). > > Hm, I see, thanks for spotting. So I would need to do: > > s > (strpbrk(opt, " ") ?: s) > > So that we don't compare against NULL. > > Also the original code was wrong AFAICT, as strpbrk() returning NULL > should result in vga=true (as it would imply console= is the last > option on the command line). I'm afraid I'm in trouble what "original code" you're referring to here. Iirc you really only add code to the function. And boot/cmdline.c has no use of strpbrk() afaics. >>> + 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. > > But if we then describe this behavior in the documentation people > could rely on it. Right now this is just an implementation detail (or > a bug I would say), and that would justify fixing boot/cmdline.c to > also respect the last instance only. Yes, fixing the non-EFI code is certainly an option (and then describing the hopefully consistent result in the doc). Jan >> 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). > > Hm, I don't have a strong opinion, the expected behavior I have of > command line options is that the last one is the one that takes > effect, but it would simplify the change if we only cared about the > first one, albeit that's an odd behavior. > > My preference would be to leave the code here respecting the last > instance only, and attempt to fix boot/cmdline.c so it does the same. > > Thanks, Roger.
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |