mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 01:10:04 +00:00
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()
This commit is contained in:
commit
42576bee6e
4 changed files with 47 additions and 32 deletions
|
@ -49,7 +49,6 @@ typedef unsigned int u32;
|
|||
|
||||
/* This must be large enough to hold the entire setup */
|
||||
u8 buf[SETUP_SECT_MAX*512];
|
||||
int is_big_kernel;
|
||||
|
||||
#define PECOFF_RELOC_RESERVE 0x20
|
||||
|
||||
|
|
|
@ -40,13 +40,8 @@ pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | _PAGE_NX);
|
|||
/* Wipe all early page tables except for the kernel symbol map */
|
||||
static void __init reset_early_page_tables(void)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
for (i = 0; i < PTRS_PER_PGD-1; i++)
|
||||
early_level4_pgt[i].pgd = 0;
|
||||
|
||||
memset(early_level4_pgt, 0, sizeof(pgd_t)*(PTRS_PER_PGD-1));
|
||||
next_early_pgt = 0;
|
||||
|
||||
write_cr3(__pa_nodebug(early_level4_pgt));
|
||||
}
|
||||
|
||||
|
@ -54,7 +49,6 @@ static void __init reset_early_page_tables(void)
|
|||
int __init early_make_pgtable(unsigned long address)
|
||||
{
|
||||
unsigned long physaddr = address - __PAGE_OFFSET;
|
||||
unsigned long i;
|
||||
pgdval_t pgd, *pgd_p;
|
||||
pudval_t pud, *pud_p;
|
||||
pmdval_t pmd, *pmd_p;
|
||||
|
@ -81,8 +75,7 @@ int __init early_make_pgtable(unsigned long address)
|
|||
}
|
||||
|
||||
pud_p = (pudval_t *)early_dynamic_pgts[next_early_pgt++];
|
||||
for (i = 0; i < PTRS_PER_PUD; i++)
|
||||
pud_p[i] = 0;
|
||||
memset(pud_p, 0, sizeof(*pud_p) * PTRS_PER_PUD);
|
||||
*pgd_p = (pgdval_t)pud_p - __START_KERNEL_map + phys_base + _KERNPG_TABLE;
|
||||
}
|
||||
pud_p += pud_index(address);
|
||||
|
@ -97,8 +90,7 @@ int __init early_make_pgtable(unsigned long address)
|
|||
}
|
||||
|
||||
pmd_p = (pmdval_t *)early_dynamic_pgts[next_early_pgt++];
|
||||
for (i = 0; i < PTRS_PER_PMD; i++)
|
||||
pmd_p[i] = 0;
|
||||
memset(pmd_p, 0, sizeof(*pmd_p) * PTRS_PER_PMD);
|
||||
*pud_p = (pudval_t)pmd_p - __START_KERNEL_map + phys_base + _KERNPG_TABLE;
|
||||
}
|
||||
pmd = (physaddr & PMD_MASK) + early_pmd_flags;
|
||||
|
|
|
@ -75,9 +75,7 @@ startup_64:
|
|||
subq $_text - __START_KERNEL_map, %rbp
|
||||
|
||||
/* Is the address not 2M aligned? */
|
||||
movq %rbp, %rax
|
||||
andl $~PMD_PAGE_MASK, %eax
|
||||
testl %eax, %eax
|
||||
testl $~PMD_PAGE_MASK, %ebp
|
||||
jnz bad_address
|
||||
|
||||
/*
|
||||
|
|
|
@ -21,12 +21,16 @@ static inline int myisspace(u8 c)
|
|||
* @option: option string to look for
|
||||
*
|
||||
* Returns the position of that @option (starts counting with 1)
|
||||
* or 0 on not found.
|
||||
* or 0 on not found. @option will only be found if it is found
|
||||
* as an entire word in @cmdline. For instance, if @option="car"
|
||||
* then a cmdline which contains "cart" will not match.
|
||||
*/
|
||||
int cmdline_find_option_bool(const char *cmdline, const char *option)
|
||||
static int
|
||||
__cmdline_find_option_bool(const char *cmdline, int max_cmdline_size,
|
||||
const char *option)
|
||||
{
|
||||
char c;
|
||||
int len, pos = 0, wstart = 0;
|
||||
int pos = 0, wstart = 0;
|
||||
const char *opptr = NULL;
|
||||
enum {
|
||||
st_wordstart = 0, /* Start of word/after whitespace */
|
||||
|
@ -37,11 +41,11 @@ int cmdline_find_option_bool(const char *cmdline, const char *option)
|
|||
if (!cmdline)
|
||||
return -1; /* No command line */
|
||||
|
||||
len = min_t(int, strlen(cmdline), COMMAND_LINE_SIZE);
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
while (len--) {
|
||||
/*
|
||||
* This 'pos' check ensures we do not overrun
|
||||
* a non-NULL-terminated 'cmdline'
|
||||
*/
|
||||
while (pos < max_cmdline_size) {
|
||||
c = *(char *)cmdline++;
|
||||
pos++;
|
||||
|
||||
|
@ -58,18 +62,35 @@ int cmdline_find_option_bool(const char *cmdline, const char *option)
|
|||
/* fall through */
|
||||
|
||||
case st_wordcmp:
|
||||
if (!*opptr)
|
||||
if (!*opptr) {
|
||||
/*
|
||||
* We matched all the way to the end of the
|
||||
* option we were looking for. If the
|
||||
* command-line has a space _or_ ends, then
|
||||
* we matched!
|
||||
*/
|
||||
if (!c || myisspace(c))
|
||||
return wstart;
|
||||
else
|
||||
state = st_wordskip;
|
||||
else if (!c)
|
||||
/*
|
||||
* We hit the end of the option, but _not_
|
||||
* the end of a word on the cmdline. Not
|
||||
* a match.
|
||||
*/
|
||||
} else if (!c) {
|
||||
/*
|
||||
* Hit the NULL terminator on the end of
|
||||
* cmdline.
|
||||
*/
|
||||
return 0;
|
||||
else if (c != *opptr++)
|
||||
state = st_wordskip;
|
||||
else if (!len) /* last word and is matching */
|
||||
return wstart;
|
||||
break;
|
||||
} else if (c == *opptr++) {
|
||||
/*
|
||||
* We are currently matching, so continue
|
||||
* to the next character on the cmdline.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
state = st_wordskip;
|
||||
/* fall through */
|
||||
|
||||
case st_wordskip:
|
||||
if (!c)
|
||||
|
@ -82,3 +103,8 @@ int cmdline_find_option_bool(const char *cmdline, const char *option)
|
|||
|
||||
return 0; /* Buffer overrun */
|
||||
}
|
||||
|
||||
int cmdline_find_option_bool(const char *cmdline, const char *option)
|
||||
{
|
||||
return __cmdline_find_option_bool(cmdline, COMMAND_LINE_SIZE, option);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue