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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull x86 fix from Thomas Gleixner:
"A single fix, which addresses boot failures on machines which do not
report EBDA correctly, which can place the trampoline into reserved
memory regions. Validating against E820 prevents that"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/boot/compressed/64: Validate trampoline placement against E820

+55 -18
+55 -18
arch/x86/boot/compressed/pgtable_64.c
··· 1 + #include <asm/e820/types.h> 1 2 #include <asm/processor.h> 2 3 #include "pgtable.h" 3 4 #include "../string.h" ··· 35 34 extern struct boot_params *boot_params; 36 35 int cmdline_find_option_bool(const char *option); 37 36 37 + static unsigned long find_trampoline_placement(void) 38 + { 39 + unsigned long bios_start, ebda_start; 40 + unsigned long trampoline_start; 41 + struct boot_e820_entry *entry; 42 + int i; 43 + 44 + /* 45 + * Find a suitable spot for the trampoline. 46 + * This code is based on reserve_bios_regions(). 47 + */ 48 + 49 + ebda_start = *(unsigned short *)0x40e << 4; 50 + bios_start = *(unsigned short *)0x413 << 10; 51 + 52 + if (bios_start < BIOS_START_MIN || bios_start > BIOS_START_MAX) 53 + bios_start = BIOS_START_MAX; 54 + 55 + if (ebda_start > BIOS_START_MIN && ebda_start < bios_start) 56 + bios_start = ebda_start; 57 + 58 + bios_start = round_down(bios_start, PAGE_SIZE); 59 + 60 + /* Find the first usable memory region under bios_start. */ 61 + for (i = boot_params->e820_entries - 1; i >= 0; i--) { 62 + entry = &boot_params->e820_table[i]; 63 + 64 + /* Skip all entries above bios_start. */ 65 + if (bios_start <= entry->addr) 66 + continue; 67 + 68 + /* Skip non-RAM entries. */ 69 + if (entry->type != E820_TYPE_RAM) 70 + continue; 71 + 72 + /* Adjust bios_start to the end of the entry if needed. */ 73 + if (bios_start > entry->addr + entry->size) 74 + bios_start = entry->addr + entry->size; 75 + 76 + /* Keep bios_start page-aligned. */ 77 + bios_start = round_down(bios_start, PAGE_SIZE); 78 + 79 + /* Skip the entry if it's too small. */ 80 + if (bios_start - TRAMPOLINE_32BIT_SIZE < entry->addr) 81 + continue; 82 + 83 + break; 84 + } 85 + 86 + /* Place the trampoline just below the end of low memory */ 87 + return bios_start - TRAMPOLINE_32BIT_SIZE; 88 + } 89 + 38 90 struct paging_config paging_prepare(void *rmode) 39 91 { 40 92 struct paging_config paging_config = {}; 41 - unsigned long bios_start, ebda_start; 42 93 43 94 /* Initialize boot_params. Required for cmdline_find_option_bool(). */ 44 95 boot_params = rmode; ··· 114 61 paging_config.l5_required = 1; 115 62 } 116 63 117 - /* 118 - * Find a suitable spot for the trampoline. 119 - * This code is based on reserve_bios_regions(). 120 - */ 121 - 122 - ebda_start = *(unsigned short *)0x40e << 4; 123 - bios_start = *(unsigned short *)0x413 << 10; 124 - 125 - if (bios_start < BIOS_START_MIN || bios_start > BIOS_START_MAX) 126 - bios_start = BIOS_START_MAX; 127 - 128 - if (ebda_start > BIOS_START_MIN && ebda_start < bios_start) 129 - bios_start = ebda_start; 130 - 131 - /* Place the trampoline just below the end of low memory, aligned to 4k */ 132 - paging_config.trampoline_start = bios_start - TRAMPOLINE_32BIT_SIZE; 133 - paging_config.trampoline_start = round_down(paging_config.trampoline_start, PAGE_SIZE); 64 + paging_config.trampoline_start = find_trampoline_placement(); 134 65 135 66 trampoline_32bit = (unsigned long *)paging_config.trampoline_start; 136 67