Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 boot updates from Ingo Molnar:
"Early command line options parsing enhancements from Dave Hansen, plus
minor cleanups and enhancements"

* 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/boot: Remove unused 'is_big_kernel' variable
x86/boot: Use proper array element type in memset() size calculation
x86/boot: Pass in size to early cmdline parsing
x86/boot: Simplify early command line parsing
x86/boot: Fix early command-line parsing when partial word matches
x86/boot: Fix early command-line parsing when matching at end
x86/boot: Simplify kernel load address alignment check
x86/boot: Micro-optimize reset_early_page_tables()

+47 -32
-1
arch/x86/boot/tools/build.c
··· 49 49 50 50 /* This must be large enough to hold the entire setup */ 51 51 u8 buf[SETUP_SECT_MAX*512]; 52 - int is_big_kernel; 53 52 54 53 #define PECOFF_RELOC_RESERVE 0x20 55 54
+3 -11
arch/x86/kernel/head64.c
··· 40 40 /* Wipe all early page tables except for the kernel symbol map */ 41 41 static void __init reset_early_page_tables(void) 42 42 { 43 - unsigned long i; 44 - 45 - for (i = 0; i < PTRS_PER_PGD-1; i++) 46 - early_level4_pgt[i].pgd = 0; 47 - 43 + memset(early_level4_pgt, 0, sizeof(pgd_t)*(PTRS_PER_PGD-1)); 48 44 next_early_pgt = 0; 49 - 50 45 write_cr3(__pa_nodebug(early_level4_pgt)); 51 46 } 52 47 ··· 49 54 int __init early_make_pgtable(unsigned long address) 50 55 { 51 56 unsigned long physaddr = address - __PAGE_OFFSET; 52 - unsigned long i; 53 57 pgdval_t pgd, *pgd_p; 54 58 pudval_t pud, *pud_p; 55 59 pmdval_t pmd, *pmd_p; ··· 75 81 } 76 82 77 83 pud_p = (pudval_t *)early_dynamic_pgts[next_early_pgt++]; 78 - for (i = 0; i < PTRS_PER_PUD; i++) 79 - pud_p[i] = 0; 84 + memset(pud_p, 0, sizeof(*pud_p) * PTRS_PER_PUD); 80 85 *pgd_p = (pgdval_t)pud_p - __START_KERNEL_map + phys_base + _KERNPG_TABLE; 81 86 } 82 87 pud_p += pud_index(address); ··· 90 97 } 91 98 92 99 pmd_p = (pmdval_t *)early_dynamic_pgts[next_early_pgt++]; 93 - for (i = 0; i < PTRS_PER_PMD; i++) 94 - pmd_p[i] = 0; 100 + memset(pmd_p, 0, sizeof(*pmd_p) * PTRS_PER_PMD); 95 101 *pud_p = (pudval_t)pmd_p - __START_KERNEL_map + phys_base + _KERNPG_TABLE; 96 102 } 97 103 pmd = (physaddr & PMD_MASK) + early_pmd_flags;
+1 -3
arch/x86/kernel/head_64.S
··· 75 75 subq $_text - __START_KERNEL_map, %rbp 76 76 77 77 /* Is the address not 2M aligned? */ 78 - movq %rbp, %rax 79 - andl $~PMD_PAGE_MASK, %eax 80 - testl %eax, %eax 78 + testl $~PMD_PAGE_MASK, %ebp 81 79 jnz bad_address 82 80 83 81 /*
+43 -17
arch/x86/lib/cmdline.c
··· 21 21 * @option: option string to look for 22 22 * 23 23 * Returns the position of that @option (starts counting with 1) 24 - * or 0 on not found. 24 + * or 0 on not found. @option will only be found if it is found 25 + * as an entire word in @cmdline. For instance, if @option="car" 26 + * then a cmdline which contains "cart" will not match. 25 27 */ 26 - int cmdline_find_option_bool(const char *cmdline, const char *option) 28 + static int 29 + __cmdline_find_option_bool(const char *cmdline, int max_cmdline_size, 30 + const char *option) 27 31 { 28 32 char c; 29 - int len, pos = 0, wstart = 0; 33 + int pos = 0, wstart = 0; 30 34 const char *opptr = NULL; 31 35 enum { 32 36 st_wordstart = 0, /* Start of word/after whitespace */ ··· 41 37 if (!cmdline) 42 38 return -1; /* No command line */ 43 39 44 - len = min_t(int, strlen(cmdline), COMMAND_LINE_SIZE); 45 - if (!len) 46 - return 0; 47 - 48 - while (len--) { 40 + /* 41 + * This 'pos' check ensures we do not overrun 42 + * a non-NULL-terminated 'cmdline' 43 + */ 44 + while (pos < max_cmdline_size) { 49 45 c = *(char *)cmdline++; 50 46 pos++; 51 47 ··· 62 58 /* fall through */ 63 59 64 60 case st_wordcmp: 65 - if (!*opptr) 61 + if (!*opptr) { 62 + /* 63 + * We matched all the way to the end of the 64 + * option we were looking for. If the 65 + * command-line has a space _or_ ends, then 66 + * we matched! 67 + */ 66 68 if (!c || myisspace(c)) 67 69 return wstart; 68 - else 69 - state = st_wordskip; 70 - else if (!c) 70 + /* 71 + * We hit the end of the option, but _not_ 72 + * the end of a word on the cmdline. Not 73 + * a match. 74 + */ 75 + } else if (!c) { 76 + /* 77 + * Hit the NULL terminator on the end of 78 + * cmdline. 79 + */ 71 80 return 0; 72 - else if (c != *opptr++) 73 - state = st_wordskip; 74 - else if (!len) /* last word and is matching */ 75 - return wstart; 76 - break; 81 + } else if (c == *opptr++) { 82 + /* 83 + * We are currently matching, so continue 84 + * to the next character on the cmdline. 85 + */ 86 + break; 87 + } 88 + state = st_wordskip; 89 + /* fall through */ 77 90 78 91 case st_wordskip: 79 92 if (!c) ··· 102 81 } 103 82 104 83 return 0; /* Buffer overrun */ 84 + } 85 + 86 + int cmdline_find_option_bool(const char *cmdline, const char *option) 87 + { 88 + return __cmdline_find_option_bool(cmdline, COMMAND_LINE_SIZE, option); 105 89 }