[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 14/16] x86/boot: implement early command line parser in C
On Wed, May 25, 2016 at 04:33:54AM -0600, Jan Beulich wrote: > >>> On 15.04.16 at 14:33, <daniel.kiper@xxxxxxxxxx> wrote: > > --- a/xen/arch/x86/boot/build32.lds > > +++ b/xen/arch/x86/boot/build32.lds > > @@ -25,6 +25,7 @@ SECTIONS > > *(.text) > > *(.text.*) > > *(.rodata) > > + *(.rodata.*) > > } > > Interesting - didn't you say you don't want this for now? Yep, however, I also said that we should add "*(.rodata.*)" if it is needed. And it is needed here. > > --- /dev/null > > +++ b/xen/arch/x86/boot/cmdline.c > > @@ -0,0 +1,357 @@ > > +/* > > + * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights > > reserved. > > + * Daniel Kiper <daniel.kiper@xxxxxxxxxx> > > + * > > + * This program is free software; you can redistribute it and/or modify > > + * it under the terms of the GNU General Public License as published by > > + * the Free Software Foundation; either version 2 of the License, or > > + * (at your option) any later version. > > + * > > + * This program is distributed in the hope that it will be useful, > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > > + * GNU General Public License for more details. > > + * > > + * You should have received a copy of the GNU General Public License along > > + * with this program. If not, see <http://www.gnu.org/licenses/>. > > + * > > + * strlen(), strncmp(), strspn() and strcspn() were copied from > > + * Linux kernel source (linux/lib/string.c). > > Any reason you can't just #include ".../common/string.c" here? I am confused. Sometimes you request to reduce number of such strange includes and sometimes you ask me to do something contrary? So, what is the rule behind these requests? Additionally, there is a chance that final xen ELF file will be unnecessary larger because it will contain unused functions. Wait, maybe there is a linker option which allows us to remove unreferenced objects from final output. > > +/* > > + * Space and TAB are obvious delimiters. However, I am > > + * adding "\n" and "\r" here too. Just in case when > > + * crazy bootloader/user put them somewhere. > > + */ > > +#define DELIM_CHARS " \n\r\t" > > +#define DELIM_CHARS_COMMA DELIM_CHARS "," > > static const char[] variables (or really just one, with the comma put > first and the non-comma variant indexing into that variable by 1)? OK. > > +#define __packed __attribute__((__packed__)) > > No way to include compiler.h here? Ditto. > > +/* > > + * Compiler is not able to optimize regular strlen() > > + * if argument is well known string during build. > > + * Hence, introduce optimized strlen_opt(). > > + */ > > +#define strlen_opt(s) (sizeof(s) - 1) > > Do we really care in this code? Not to strongly but why not? > > +/* Keep in sync with trampoline.S:early_boot_opts label! */ > > +typedef struct __packed { > > + u8 skip_realmode; > > + u8 opt_edd; > > + u8 opt_edid; > > + u16 boot_vid_mode; > > + u16 vesa_width; > > + u16 vesa_height; > > + u16 vesa_depth; > > +} early_boot_opts_t; > > This "keeping in sync" should be automated in some way, e.g. via > a new header and suitable macroization. OK. > > +static int strtoi(const char *s, const char *stop, const char **next) > > +{ > > + int base = 10, i, ores = 0, res = 0; > > You don't even handle a '-' on the numbers here, so all the variables Yep, however, ... > and the function return type should be unsigned int afaict. And the > function name perhaps be strtoui(). ... we return -1 in case of error. > > + if ( *s == '0' ) > > + base = (tolower(*++s) == 'x') ? (++s, 16) : 8; > > + > > + for ( ; *s != '\0'; ++s ) > > + { > > + for ( i = 0; stop && stop[i] != '\0'; ++i ) > > + if ( *s == stop[i] ) > > + goto out; > > strchr()? Could be. > > + if ( *s < '0' || (*s > '7' && base == 8) ) > > + { > > + res = -1; > > + goto out; > > + } > > + > > + if ( *s > '9' && (base != 16 || tolower(*s) < 'a' || tolower(*s) > > > 'f') ) > > + { > > + res = -1; > > + goto out; > > + } > > + > > + res *= base; > > + res += (tolower(*s) >= 'a') ? (tolower(*s) - 'a' + 10) : (*s - > > '0'); > > With the four instances, how about latching tolower(*s) into a local > variable? Make sense. > > +static u8 skip_realmode(const char *cmdline) > > +{ > > + return !!find_opt(cmdline, "no-real-mode", 0) || !!find_opt(cmdline, > > "tboot=", 1); > > The || makes the two !! pointless. > > Also please settle on which type you want to use for boolean > (find_opt()'s last parameter is "int", yet here you use "u8"), and Could be u8. > perhaps make yourself a bool_t. I do not think it make sense here. > > +static void vga_parse(const char *cmdline, early_boot_opts_t *ebo) > > +{ > > + const char *c; > > + int tmp; > > + > > + c = find_opt(cmdline, "vga=", 1); > > + > > + if ( !c ) > > + return; > > + > > + ebo->boot_vid_mode = ASK_VGA; > > + > > + if ( !strmaxcmp(c, "current", DELIM_CHARS_COMMA) ) > > + ebo->boot_vid_mode = VIDEO_CURRENT_MODE; > > + else if ( !strsubcmp(c, "text-80x") ) > > + { > > + c += strlen_opt("text-80x"); > > + ebo->boot_vid_mode = rows2vmode(strtoi(c, DELIM_CHARS_COMMA, > > NULL)); > > + } > > + else if ( !strsubcmp(c, "gfx-") ) > > + { > > + tmp = strtoi(c + strlen_opt("gfx-"), "x", &c); > > + > > + if ( tmp < 0 || tmp > U16_MAX ) > > + return; > > + > > + ebo->vesa_width = tmp; > > + > > + /* > > + * Increment c outside of strtoi() because otherwise some > > + * compiler may complain with following message: > > + * warning: operation on ‘c’ may be undefined. > > + */ > > + ++c; > > + tmp = strtoi(c, "x", &c); > > The comment is pointless - the operation is firmly undefined if you > put it in the strtoi() invocation. In terms of C spec you are right. However, it is quite surprising that older GCC complains and newer ones do not. Should not we investigate this? > > + if ( tmp < 0 || tmp > U16_MAX ) > > + return; > > + > > + ebo->vesa_height = tmp; > > + > > + tmp = strtoi(++c, DELIM_CHARS_COMMA, NULL); > > + > > + if ( tmp < 0 || tmp > U16_MAX ) > > + return; > > + > > + ebo->vesa_depth = tmp; > > + > > + ebo->boot_vid_mode = VIDEO_VESA_BY_SIZE; > > I realize this is reflecting original behavior, but now that you do it in > C, please leverage that fact and defer storing width and height until > you know the entire option was good. OK. > > --- a/xen/arch/x86/boot/head.S > > +++ b/xen/arch/x86/boot/head.S > > @@ -436,8 +436,24 @@ trampoline_setup: > > cmp $sym_phys(__trampoline_seg_stop),%edi > > jb 1b > > > > + /* Do not parse command line on EFI platform here. */ > > + cmpb $1,sym_phys(skip_realmode) > > + je 1f > > Doesn't this belong in an earlier patch? It certainly doesn't get > moved here from cmdline.S. Potentially. > > + /* Bail if there is no command line to parse. */ > > + mov sym_phys(multiboot_ptr),%ebx > > + testl $MBI_CMDLINE,MB_flags(%ebx) > > + jz 1f > > + > > + cmpl $0,MB_cmdline(%ebx) > > + jz 1f > > Any reason not to leave at least this check to the C code? OK. > > + pushl $sym_phys(early_boot_opts) > > + pushl MB_cmdline(%ebx) > > call cmdline_parse_early > > + add $8,%esp /* Remove cmdline_parse_early() args > > from stack. */ > > I don't think such a comment is really useful (seems like I overlooked > a similar one in an earlier patch, on the reloc() invocation). This thing is quite obvious but I do not think that this comment hurts. Daniel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |