diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-25 20:32:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-07-25 20:32:28 -0400 |
commit | 77cd3d0c43b7e6c0bb49ca641cf936891f6e1766 (patch) | |
tree | 44885bb7ec9def5a34b8e9f2073a166f78bddcf9 /arch/x86/kernel | |
parent | 0f657262d5f99ad86b9a63fb5dcd29036c2ed916 (diff) | |
parent | 6a79296cb15d947bcb4558011fe066e5d8252b35 (diff) |
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:
"The main changes:
- add initial commits to randomize kernel memory section virtual
addresses, enabled via a new kernel option: RANDOMIZE_MEMORY
(Thomas Garnier, Kees Cook, Baoquan He, Yinghai Lu)
- enhance KASLR (RANDOMIZE_BASE) physical memory randomization (Kees
Cook)
- EBDA/BIOS region boot quirk cleanups (Andy Lutomirski, Ingo Molnar)
- misc cleanups/fixes"
* 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/boot: Simplify EBDA-vs-BIOS reservation logic
x86/boot: Clarify what x86_legacy_features.reserve_bios_regions does
x86/boot: Reorganize and clean up the BIOS area reservation code
x86/mm: Do not reference phys addr beyond kernel
x86/mm: Add memory hotplug support for KASLR memory randomization
x86/mm: Enable KASLR for vmalloc memory regions
x86/mm: Enable KASLR for physical mapping memory regions
x86/mm: Implement ASLR for kernel memory regions
x86/mm: Separate variable for trampoline PGD
x86/mm: Add PUD VA support for physical mapping
x86/mm: Update physical mapping variable names
x86/mm: Refactor KASLR entropy functions
x86/KASLR: Fix boot crash with certain memory configurations
x86/boot/64: Add forgotten end of function marker
x86/KASLR: Allow randomization below the load address
x86/KASLR: Extend kernel image physical address randomization to addresses larger than 4G
x86/KASLR: Randomize virtual address separately
x86/KASLR: Clarify identity map interface
x86/boot: Refuse to build with data relocations
x86/KASLR, x86/power: Remove x86 hibernation restrictions
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/ebda.c | 114 | ||||
-rw-r--r-- | arch/x86/kernel/head32.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/head64.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/head_64.S | 3 | ||||
-rw-r--r-- | arch/x86/kernel/platform-quirks.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 3 |
6 files changed, 79 insertions, 49 deletions
diff --git a/arch/x86/kernel/ebda.c b/arch/x86/kernel/ebda.c index afe65dffee80..4312f8ae71b7 100644 --- a/arch/x86/kernel/ebda.c +++ b/arch/x86/kernel/ebda.c | |||
@@ -6,66 +6,92 @@ | |||
6 | #include <asm/bios_ebda.h> | 6 | #include <asm/bios_ebda.h> |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * This function reserves all conventional PC system BIOS related | ||
10 | * firmware memory areas (some of which are data, some of which | ||
11 | * are code), that must not be used by the kernel as available | ||
12 | * RAM. | ||
13 | * | ||
9 | * The BIOS places the EBDA/XBDA at the top of conventional | 14 | * The BIOS places the EBDA/XBDA at the top of conventional |
10 | * memory, and usually decreases the reported amount of | 15 | * memory, and usually decreases the reported amount of |
11 | * conventional memory (int 0x12) too. This also contains a | 16 | * conventional memory (int 0x12) too. |
12 | * workaround for Dell systems that neglect to reserve EBDA. | 17 | * |
13 | * The same workaround also avoids a problem with the AMD768MPX | 18 | * This means that as a first approximation on most systems we can |
14 | * chipset: reserve a page before VGA to prevent PCI prefetch | 19 | * guess the reserved BIOS area by looking at the low BIOS RAM size |
15 | * into it (errata #56). Usually the page is reserved anyways, | 20 | * value and assume that everything above that value (up to 1MB) is |
16 | * unless you have no PS/2 mouse plugged in. | 21 | * reserved. |
22 | * | ||
23 | * But life in firmware country is not that simple: | ||
24 | * | ||
25 | * - This code also contains a quirk for Dell systems that neglect | ||
26 | * to reserve the EBDA area in the 'RAM size' value ... | ||
27 | * | ||
28 | * - The same quirk also avoids a problem with the AMD768MPX | ||
29 | * chipset: reserve a page before VGA to prevent PCI prefetch | ||
30 | * into it (errata #56). (Usually the page is reserved anyways, | ||
31 | * unless you have no PS/2 mouse plugged in.) | ||
32 | * | ||
33 | * - Plus paravirt systems don't have a reliable value in the | ||
34 | * 'BIOS RAM size' pointer we can rely on, so we must quirk | ||
35 | * them too. | ||
36 | * | ||
37 | * Due to those various problems this function is deliberately | ||
38 | * very conservative and tries to err on the side of reserving | ||
39 | * too much, to not risk reserving too little. | ||
40 | * | ||
41 | * Losing a small amount of memory in the bottom megabyte is | ||
42 | * rarely a problem, as long as we have enough memory to install | ||
43 | * the SMP bootup trampoline which *must* be in this area. | ||
17 | * | 44 | * |
18 | * This functions is deliberately very conservative. Losing | 45 | * Using memory that is in use by the BIOS or by some DMA device |
19 | * memory in the bottom megabyte is rarely a problem, as long | 46 | * the BIOS didn't shut down *is* a big problem to the kernel, |
20 | * as we have enough memory to install the trampoline. Using | 47 | * obviously. |
21 | * memory that is in use by the BIOS or by some DMA device | ||
22 | * the BIOS didn't shut down *is* a big problem. | ||
23 | */ | 48 | */ |
24 | 49 | ||
25 | #define BIOS_LOWMEM_KILOBYTES 0x413 | 50 | #define BIOS_RAM_SIZE_KB_PTR 0x413 |
26 | #define LOWMEM_CAP 0x9f000U /* Absolute maximum */ | ||
27 | #define INSANE_CUTOFF 0x20000U /* Less than this = insane */ | ||
28 | 51 | ||
29 | void __init reserve_ebda_region(void) | 52 | #define BIOS_START_MIN 0x20000U /* 128K, less than this is insane */ |
53 | #define BIOS_START_MAX 0x9f000U /* 640K, absolute maximum */ | ||
54 | |||
55 | void __init reserve_bios_regions(void) | ||
30 | { | 56 | { |
31 | unsigned int lowmem, ebda_addr; | 57 | unsigned int bios_start, ebda_start; |
32 | 58 | ||
33 | /* | 59 | /* |
34 | * To determine the position of the EBDA and the | 60 | * NOTE: In a paravirtual environment the BIOS reserved |
35 | * end of conventional memory, we need to look at | 61 | * area is absent. We'll just have to assume that the |
36 | * the BIOS data area. In a paravirtual environment | 62 | * paravirt case can handle memory setup correctly, |
37 | * that area is absent. We'll just have to assume | 63 | * without our help. |
38 | * that the paravirt case can handle memory setup | ||
39 | * correctly, without our help. | ||
40 | */ | 64 | */ |
41 | if (!x86_platform.legacy.ebda_search) | 65 | if (!x86_platform.legacy.reserve_bios_regions) |
42 | return; | 66 | return; |
43 | 67 | ||
44 | /* end of low (conventional) memory */ | ||
45 | lowmem = *(unsigned short *)__va(BIOS_LOWMEM_KILOBYTES); | ||
46 | lowmem <<= 10; | ||
47 | |||
48 | /* start of EBDA area */ | ||
49 | ebda_addr = get_bios_ebda(); | ||
50 | |||
51 | /* | 68 | /* |
52 | * Note: some old Dells seem to need 4k EBDA without | 69 | * BIOS RAM size is encoded in kilobytes, convert it |
53 | * reporting so, so just consider the memory above 0x9f000 | 70 | * to bytes to get a first guess at where the BIOS |
54 | * to be off limits (bugzilla 2990). | 71 | * firmware area starts: |
55 | */ | 72 | */ |
73 | bios_start = *(unsigned short *)__va(BIOS_RAM_SIZE_KB_PTR); | ||
74 | bios_start <<= 10; | ||
56 | 75 | ||
57 | /* If the EBDA address is below 128K, assume it is bogus */ | 76 | /* |
58 | if (ebda_addr < INSANE_CUTOFF) | 77 | * If bios_start is less than 128K, assume it is bogus |
59 | ebda_addr = LOWMEM_CAP; | 78 | * and bump it up to 640K. Similarly, if bios_start is above 640K, |
79 | * don't trust it. | ||
80 | */ | ||
81 | if (bios_start < BIOS_START_MIN || bios_start > BIOS_START_MAX) | ||
82 | bios_start = BIOS_START_MAX; | ||
60 | 83 | ||
61 | /* If lowmem is less than 128K, assume it is bogus */ | 84 | /* Get the start address of the EBDA page: */ |
62 | if (lowmem < INSANE_CUTOFF) | 85 | ebda_start = get_bios_ebda(); |
63 | lowmem = LOWMEM_CAP; | ||
64 | 86 | ||
65 | /* Use the lower of the lowmem and EBDA markers as the cutoff */ | 87 | /* |
66 | lowmem = min(lowmem, ebda_addr); | 88 | * If the EBDA start address is sane and is below the BIOS region, |
67 | lowmem = min(lowmem, LOWMEM_CAP); /* Absolute cap */ | 89 | * then also reserve everything from the EBDA start address up to |
90 | * the BIOS region. | ||
91 | */ | ||
92 | if (ebda_start >= BIOS_START_MIN && ebda_start < bios_start) | ||
93 | bios_start = ebda_start; | ||
68 | 94 | ||
69 | /* reserve all memory between lowmem and the 1MB mark */ | 95 | /* Reserve all memory between bios_start and the 1MB mark: */ |
70 | memblock_reserve(lowmem, 0x100000 - lowmem); | 96 | memblock_reserve(bios_start, 0x100000 - bios_start); |
71 | } | 97 | } |
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index d784bb547a9d..2dda0bc4576e 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c | |||
@@ -26,7 +26,7 @@ static void __init i386_default_early_setup(void) | |||
26 | x86_init.resources.reserve_resources = i386_reserve_resources; | 26 | x86_init.resources.reserve_resources = i386_reserve_resources; |
27 | x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc; | 27 | x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc; |
28 | 28 | ||
29 | reserve_ebda_region(); | 29 | reserve_bios_regions(); |
30 | } | 30 | } |
31 | 31 | ||
32 | asmlinkage __visible void __init i386_start_kernel(void) | 32 | asmlinkage __visible void __init i386_start_kernel(void) |
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index b72fb0b71dd1..99d48e7d2974 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -183,7 +183,7 @@ void __init x86_64_start_reservations(char *real_mode_data) | |||
183 | copy_bootdata(__va(real_mode_data)); | 183 | copy_bootdata(__va(real_mode_data)); |
184 | 184 | ||
185 | x86_early_init_platform_quirks(); | 185 | x86_early_init_platform_quirks(); |
186 | reserve_ebda_region(); | 186 | reserve_bios_regions(); |
187 | 187 | ||
188 | switch (boot_params.hdr.hardware_subarch) { | 188 | switch (boot_params.hdr.hardware_subarch) { |
189 | case X86_SUBARCH_INTEL_MID: | 189 | case X86_SUBARCH_INTEL_MID: |
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 5df831ef1442..9f8efc9f0075 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | #define pud_index(x) (((x) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) | 39 | #define pud_index(x) (((x) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) |
40 | 40 | ||
41 | L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET) | 41 | L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET_BASE) |
42 | L4_START_KERNEL = pgd_index(__START_KERNEL_map) | 42 | L4_START_KERNEL = pgd_index(__START_KERNEL_map) |
43 | L3_START_KERNEL = pud_index(__START_KERNEL_map) | 43 | L3_START_KERNEL = pud_index(__START_KERNEL_map) |
44 | 44 | ||
@@ -299,6 +299,7 @@ ENTRY(secondary_startup_64) | |||
299 | pushq $__KERNEL_CS # set correct cs | 299 | pushq $__KERNEL_CS # set correct cs |
300 | pushq %rax # target address in negative space | 300 | pushq %rax # target address in negative space |
301 | lretq | 301 | lretq |
302 | ENDPROC(secondary_startup_64) | ||
302 | 303 | ||
303 | #include "verify_cpu.S" | 304 | #include "verify_cpu.S" |
304 | 305 | ||
diff --git a/arch/x86/kernel/platform-quirks.c b/arch/x86/kernel/platform-quirks.c index b2f8a33b36ff..24a50301f150 100644 --- a/arch/x86/kernel/platform-quirks.c +++ b/arch/x86/kernel/platform-quirks.c | |||
@@ -7,12 +7,12 @@ | |||
7 | void __init x86_early_init_platform_quirks(void) | 7 | void __init x86_early_init_platform_quirks(void) |
8 | { | 8 | { |
9 | x86_platform.legacy.rtc = 1; | 9 | x86_platform.legacy.rtc = 1; |
10 | x86_platform.legacy.ebda_search = 0; | 10 | x86_platform.legacy.reserve_bios_regions = 0; |
11 | x86_platform.legacy.devices.pnpbios = 1; | 11 | x86_platform.legacy.devices.pnpbios = 1; |
12 | 12 | ||
13 | switch (boot_params.hdr.hardware_subarch) { | 13 | switch (boot_params.hdr.hardware_subarch) { |
14 | case X86_SUBARCH_PC: | 14 | case X86_SUBARCH_PC: |
15 | x86_platform.legacy.ebda_search = 1; | 15 | x86_platform.legacy.reserve_bios_regions = 1; |
16 | break; | 16 | break; |
17 | case X86_SUBARCH_XEN: | 17 | case X86_SUBARCH_XEN: |
18 | case X86_SUBARCH_LGUEST: | 18 | case X86_SUBARCH_LGUEST: |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index c4e7b3991b60..a2616584b6e9 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -113,6 +113,7 @@ | |||
113 | #include <asm/prom.h> | 113 | #include <asm/prom.h> |
114 | #include <asm/microcode.h> | 114 | #include <asm/microcode.h> |
115 | #include <asm/mmu_context.h> | 115 | #include <asm/mmu_context.h> |
116 | #include <asm/kaslr.h> | ||
116 | 117 | ||
117 | /* | 118 | /* |
118 | * max_low_pfn_mapped: highest direct mapped pfn under 4GB | 119 | * max_low_pfn_mapped: highest direct mapped pfn under 4GB |
@@ -942,6 +943,8 @@ void __init setup_arch(char **cmdline_p) | |||
942 | 943 | ||
943 | x86_init.oem.arch_setup(); | 944 | x86_init.oem.arch_setup(); |
944 | 945 | ||
946 | kernel_randomize_memory(); | ||
947 | |||
945 | iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1; | 948 | iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1; |
946 | setup_memory_map(); | 949 | setup_memory_map(); |
947 | parse_setup_data(); | 950 | parse_setup_data(); |