diff options
| -rw-r--r-- | arch/arm64/mm/init.c | 3 | ||||
| -rw-r--r-- | arch/x86/boot/compressed/eboot.c | 18 | ||||
| -rw-r--r-- | arch/x86/boot/compressed/head_32.S | 54 | ||||
| -rw-r--r-- | arch/x86/boot/compressed/head_64.S | 56 | ||||
| -rw-r--r-- | arch/x86/include/asm/io_apic.h | 1 | ||||
| -rw-r--r-- | arch/x86/mm/dump_pagetables.c | 4 | ||||
| -rw-r--r-- | arch/x86/mm/mmap.c | 2 | ||||
| -rw-r--r-- | drivers/firmware/efi/libstub/fdt.c | 10 |
8 files changed, 108 insertions, 40 deletions
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 5472c2401876..a83061f37e43 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c | |||
| @@ -149,8 +149,7 @@ void __init arm64_memblock_init(void) | |||
| 149 | memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start); | 149 | memblock_reserve(__virt_to_phys(initrd_start), initrd_end - initrd_start); |
| 150 | #endif | 150 | #endif |
| 151 | 151 | ||
| 152 | if (!efi_enabled(EFI_MEMMAP)) | 152 | early_init_fdt_scan_reserved_mem(); |
| 153 | early_init_fdt_scan_reserved_mem(); | ||
| 154 | 153 | ||
| 155 | /* 4GB maximum for 32-bit only capable devices */ | 154 | /* 4GB maximum for 32-bit only capable devices */ |
| 156 | if (IS_ENABLED(CONFIG_ZONE_DMA)) | 155 | if (IS_ENABLED(CONFIG_ZONE_DMA)) |
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index f277184e2ac1..dca9842d8f91 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
| @@ -1032,7 +1032,6 @@ struct boot_params *make_boot_params(struct efi_config *c) | |||
| 1032 | int i; | 1032 | int i; |
| 1033 | unsigned long ramdisk_addr; | 1033 | unsigned long ramdisk_addr; |
| 1034 | unsigned long ramdisk_size; | 1034 | unsigned long ramdisk_size; |
| 1035 | unsigned long initrd_addr_max; | ||
| 1036 | 1035 | ||
| 1037 | efi_early = c; | 1036 | efi_early = c; |
| 1038 | sys_table = (efi_system_table_t *)(unsigned long)efi_early->table; | 1037 | sys_table = (efi_system_table_t *)(unsigned long)efi_early->table; |
| @@ -1095,15 +1094,20 @@ struct boot_params *make_boot_params(struct efi_config *c) | |||
| 1095 | 1094 | ||
| 1096 | memset(sdt, 0, sizeof(*sdt)); | 1095 | memset(sdt, 0, sizeof(*sdt)); |
| 1097 | 1096 | ||
| 1098 | if (hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G) | ||
| 1099 | initrd_addr_max = -1UL; | ||
| 1100 | else | ||
| 1101 | initrd_addr_max = hdr->initrd_addr_max; | ||
| 1102 | |||
| 1103 | status = handle_cmdline_files(sys_table, image, | 1097 | status = handle_cmdline_files(sys_table, image, |
| 1104 | (char *)(unsigned long)hdr->cmd_line_ptr, | 1098 | (char *)(unsigned long)hdr->cmd_line_ptr, |
| 1105 | "initrd=", initrd_addr_max, | 1099 | "initrd=", hdr->initrd_addr_max, |
| 1106 | &ramdisk_addr, &ramdisk_size); | 1100 | &ramdisk_addr, &ramdisk_size); |
| 1101 | |||
| 1102 | if (status != EFI_SUCCESS && | ||
| 1103 | hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G) { | ||
| 1104 | efi_printk(sys_table, "Trying to load files to higher address\n"); | ||
| 1105 | status = handle_cmdline_files(sys_table, image, | ||
| 1106 | (char *)(unsigned long)hdr->cmd_line_ptr, | ||
| 1107 | "initrd=", -1UL, | ||
| 1108 | &ramdisk_addr, &ramdisk_size); | ||
| 1109 | } | ||
| 1110 | |||
| 1107 | if (status != EFI_SUCCESS) | 1111 | if (status != EFI_SUCCESS) |
| 1108 | goto fail2; | 1112 | goto fail2; |
| 1109 | hdr->ramdisk_image = ramdisk_addr & 0xffffffff; | 1113 | hdr->ramdisk_image = ramdisk_addr & 0xffffffff; |
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index cbed1407a5cd..d6b8aa4c986c 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S | |||
| @@ -30,6 +30,33 @@ | |||
| 30 | #include <asm/boot.h> | 30 | #include <asm/boot.h> |
| 31 | #include <asm/asm-offsets.h> | 31 | #include <asm/asm-offsets.h> |
| 32 | 32 | ||
| 33 | /* | ||
| 34 | * Adjust our own GOT | ||
| 35 | * | ||
| 36 | * The relocation base must be in %ebx | ||
| 37 | * | ||
| 38 | * It is safe to call this macro more than once, because in some of the | ||
| 39 | * code paths multiple invocations are inevitable, e.g. via the efi* | ||
| 40 | * entry points. | ||
| 41 | * | ||
| 42 | * Relocation is only performed the first time. | ||
| 43 | */ | ||
| 44 | .macro FIXUP_GOT | ||
| 45 | cmpb $1, got_fixed(%ebx) | ||
| 46 | je 2f | ||
| 47 | |||
| 48 | leal _got(%ebx), %edx | ||
| 49 | leal _egot(%ebx), %ecx | ||
| 50 | 1: | ||
| 51 | cmpl %ecx, %edx | ||
| 52 | jae 2f | ||
| 53 | addl %ebx, (%edx) | ||
| 54 | addl $4, %edx | ||
| 55 | jmp 1b | ||
| 56 | 2: | ||
| 57 | movb $1, got_fixed(%ebx) | ||
| 58 | .endm | ||
| 59 | |||
| 33 | __HEAD | 60 | __HEAD |
| 34 | ENTRY(startup_32) | 61 | ENTRY(startup_32) |
| 35 | #ifdef CONFIG_EFI_STUB | 62 | #ifdef CONFIG_EFI_STUB |
| @@ -56,6 +83,9 @@ ENTRY(efi_pe_entry) | |||
| 56 | add %esi, 88(%eax) | 83 | add %esi, 88(%eax) |
| 57 | pushl %eax | 84 | pushl %eax |
| 58 | 85 | ||
| 86 | movl %esi, %ebx | ||
| 87 | FIXUP_GOT | ||
| 88 | |||
| 59 | call make_boot_params | 89 | call make_boot_params |
| 60 | cmpl $0, %eax | 90 | cmpl $0, %eax |
| 61 | je fail | 91 | je fail |
| @@ -81,6 +111,10 @@ ENTRY(efi32_stub_entry) | |||
| 81 | leal efi32_config(%esi), %eax | 111 | leal efi32_config(%esi), %eax |
| 82 | add %esi, 88(%eax) | 112 | add %esi, 88(%eax) |
| 83 | pushl %eax | 113 | pushl %eax |
| 114 | |||
| 115 | movl %esi, %ebx | ||
| 116 | FIXUP_GOT | ||
| 117 | |||
| 84 | 2: | 118 | 2: |
| 85 | call efi_main | 119 | call efi_main |
| 86 | cmpl $0, %eax | 120 | cmpl $0, %eax |
| @@ -190,19 +224,7 @@ relocated: | |||
| 190 | shrl $2, %ecx | 224 | shrl $2, %ecx |
| 191 | rep stosl | 225 | rep stosl |
| 192 | 226 | ||
| 193 | /* | 227 | FIXUP_GOT |
| 194 | * Adjust our own GOT | ||
| 195 | */ | ||
| 196 | leal _got(%ebx), %edx | ||
| 197 | leal _egot(%ebx), %ecx | ||
| 198 | 1: | ||
| 199 | cmpl %ecx, %edx | ||
| 200 | jae 2f | ||
| 201 | addl %ebx, (%edx) | ||
| 202 | addl $4, %edx | ||
| 203 | jmp 1b | ||
| 204 | 2: | ||
| 205 | |||
| 206 | /* | 228 | /* |
| 207 | * Do the decompression, and jump to the new kernel.. | 229 | * Do the decompression, and jump to the new kernel.. |
| 208 | */ | 230 | */ |
| @@ -225,8 +247,12 @@ relocated: | |||
| 225 | xorl %ebx, %ebx | 247 | xorl %ebx, %ebx |
| 226 | jmp *%eax | 248 | jmp *%eax |
| 227 | 249 | ||
| 228 | #ifdef CONFIG_EFI_STUB | ||
| 229 | .data | 250 | .data |
| 251 | /* Have we relocated the GOT? */ | ||
| 252 | got_fixed: | ||
| 253 | .byte 0 | ||
| 254 | |||
| 255 | #ifdef CONFIG_EFI_STUB | ||
| 230 | efi32_config: | 256 | efi32_config: |
| 231 | .fill 11,8,0 | 257 | .fill 11,8,0 |
| 232 | .long efi_call_phys | 258 | .long efi_call_phys |
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 2884e0c3e8a5..50f69c7eaaf4 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S | |||
| @@ -32,6 +32,33 @@ | |||
| 32 | #include <asm/processor-flags.h> | 32 | #include <asm/processor-flags.h> |
| 33 | #include <asm/asm-offsets.h> | 33 | #include <asm/asm-offsets.h> |
| 34 | 34 | ||
| 35 | /* | ||
| 36 | * Adjust our own GOT | ||
| 37 | * | ||
| 38 | * The relocation base must be in %rbx | ||
| 39 | * | ||
| 40 | * It is safe to call this macro more than once, because in some of the | ||
| 41 | * code paths multiple invocations are inevitable, e.g. via the efi* | ||
| 42 | * entry points. | ||
| 43 | * | ||
| 44 | * Relocation is only performed the first time. | ||
| 45 | */ | ||
| 46 | .macro FIXUP_GOT | ||
| 47 | cmpb $1, got_fixed(%rip) | ||
| 48 | je 2f | ||
| 49 | |||
| 50 | leaq _got(%rip), %rdx | ||
| 51 | leaq _egot(%rip), %rcx | ||
| 52 | 1: | ||
| 53 | cmpq %rcx, %rdx | ||
| 54 | jae 2f | ||
| 55 | addq %rbx, (%rdx) | ||
| 56 | addq $8, %rdx | ||
| 57 | jmp 1b | ||
| 58 | 2: | ||
| 59 | movb $1, got_fixed(%rip) | ||
| 60 | .endm | ||
| 61 | |||
| 35 | __HEAD | 62 | __HEAD |
| 36 | .code32 | 63 | .code32 |
| 37 | ENTRY(startup_32) | 64 | ENTRY(startup_32) |
| @@ -252,10 +279,13 @@ ENTRY(efi_pe_entry) | |||
| 252 | subq $1b, %rbp | 279 | subq $1b, %rbp |
| 253 | 280 | ||
| 254 | /* | 281 | /* |
| 255 | * Relocate efi_config->call(). | 282 | * Relocate efi_config->call() and the GOT entries. |
| 256 | */ | 283 | */ |
| 257 | addq %rbp, efi64_config+88(%rip) | 284 | addq %rbp, efi64_config+88(%rip) |
| 258 | 285 | ||
| 286 | movq %rbp, %rbx | ||
| 287 | FIXUP_GOT | ||
| 288 | |||
| 259 | movq %rax, %rdi | 289 | movq %rax, %rdi |
| 260 | call make_boot_params | 290 | call make_boot_params |
| 261 | cmpq $0,%rax | 291 | cmpq $0,%rax |
| @@ -271,10 +301,13 @@ handover_entry: | |||
| 271 | subq $1b, %rbp | 301 | subq $1b, %rbp |
| 272 | 302 | ||
| 273 | /* | 303 | /* |
| 274 | * Relocate efi_config->call(). | 304 | * Relocate efi_config->call() and the GOT entries. |
| 275 | */ | 305 | */ |
| 276 | movq efi_config(%rip), %rax | 306 | movq efi_config(%rip), %rax |
| 277 | addq %rbp, 88(%rax) | 307 | addq %rbp, 88(%rax) |
| 308 | |||
| 309 | movq %rbp, %rbx | ||
| 310 | FIXUP_GOT | ||
| 278 | 2: | 311 | 2: |
| 279 | movq efi_config(%rip), %rdi | 312 | movq efi_config(%rip), %rdi |
| 280 | call efi_main | 313 | call efi_main |
| @@ -385,19 +418,8 @@ relocated: | |||
| 385 | shrq $3, %rcx | 418 | shrq $3, %rcx |
| 386 | rep stosq | 419 | rep stosq |
| 387 | 420 | ||
| 388 | /* | 421 | FIXUP_GOT |
| 389 | * Adjust our own GOT | 422 | |
| 390 | */ | ||
| 391 | leaq _got(%rip), %rdx | ||
| 392 | leaq _egot(%rip), %rcx | ||
| 393 | 1: | ||
| 394 | cmpq %rcx, %rdx | ||
| 395 | jae 2f | ||
| 396 | addq %rbx, (%rdx) | ||
| 397 | addq $8, %rdx | ||
| 398 | jmp 1b | ||
| 399 | 2: | ||
| 400 | |||
| 401 | /* | 423 | /* |
| 402 | * Do the decompression, and jump to the new kernel.. | 424 | * Do the decompression, and jump to the new kernel.. |
| 403 | */ | 425 | */ |
| @@ -437,6 +459,10 @@ gdt: | |||
| 437 | .quad 0x0000000000000000 /* TS continued */ | 459 | .quad 0x0000000000000000 /* TS continued */ |
| 438 | gdt_end: | 460 | gdt_end: |
| 439 | 461 | ||
| 462 | /* Have we relocated the GOT? */ | ||
| 463 | got_fixed: | ||
| 464 | .byte 0 | ||
| 465 | |||
| 440 | #ifdef CONFIG_EFI_STUB | 466 | #ifdef CONFIG_EFI_STUB |
| 441 | efi_config: | 467 | efi_config: |
| 442 | .quad 0 | 468 | .quad 0 |
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 478c490f3654..1733ab49ac5e 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h | |||
| @@ -239,6 +239,7 @@ static inline int mp_find_ioapic(u32 gsi) { return 0; } | |||
| 239 | static inline u32 mp_pin_to_gsi(int ioapic, int pin) { return UINT_MAX; } | 239 | static inline u32 mp_pin_to_gsi(int ioapic, int pin) { return UINT_MAX; } |
| 240 | static inline int mp_map_gsi_to_irq(u32 gsi, unsigned int flags) { return gsi; } | 240 | static inline int mp_map_gsi_to_irq(u32 gsi, unsigned int flags) { return gsi; } |
| 241 | static inline void mp_unmap_irq(int irq) { } | 241 | static inline void mp_unmap_irq(int irq) { } |
| 242 | static inline bool mp_should_keep_irq(struct device *dev) { return 1; } | ||
| 242 | 243 | ||
| 243 | static inline int save_ioapic_entries(void) | 244 | static inline int save_ioapic_entries(void) |
| 244 | { | 245 | { |
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c index 167ffcac16ed..95a427e57887 100644 --- a/arch/x86/mm/dump_pagetables.c +++ b/arch/x86/mm/dump_pagetables.c | |||
| @@ -48,7 +48,9 @@ enum address_markers_idx { | |||
| 48 | LOW_KERNEL_NR, | 48 | LOW_KERNEL_NR, |
| 49 | VMALLOC_START_NR, | 49 | VMALLOC_START_NR, |
| 50 | VMEMMAP_START_NR, | 50 | VMEMMAP_START_NR, |
| 51 | # ifdef CONFIG_X86_ESPFIX64 | ||
| 51 | ESPFIX_START_NR, | 52 | ESPFIX_START_NR, |
| 53 | # endif | ||
| 52 | HIGH_KERNEL_NR, | 54 | HIGH_KERNEL_NR, |
| 53 | MODULES_VADDR_NR, | 55 | MODULES_VADDR_NR, |
| 54 | MODULES_END_NR, | 56 | MODULES_END_NR, |
| @@ -71,7 +73,9 @@ static struct addr_marker address_markers[] = { | |||
| 71 | { PAGE_OFFSET, "Low Kernel Mapping" }, | 73 | { PAGE_OFFSET, "Low Kernel Mapping" }, |
| 72 | { VMALLOC_START, "vmalloc() Area" }, | 74 | { VMALLOC_START, "vmalloc() Area" }, |
| 73 | { VMEMMAP_START, "Vmemmap" }, | 75 | { VMEMMAP_START, "Vmemmap" }, |
| 76 | # ifdef CONFIG_X86_ESPFIX64 | ||
| 74 | { ESPFIX_BASE_ADDR, "ESPfix Area", 16 }, | 77 | { ESPFIX_BASE_ADDR, "ESPfix Area", 16 }, |
| 78 | # endif | ||
| 75 | { __START_KERNEL_map, "High Kernel Mapping" }, | 79 | { __START_KERNEL_map, "High Kernel Mapping" }, |
| 76 | { MODULES_VADDR, "Modules" }, | 80 | { MODULES_VADDR, "Modules" }, |
| 77 | { MODULES_END, "End Modules" }, | 81 | { MODULES_END, "End Modules" }, |
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index 25e7e1372bb2..919b91205cd4 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c | |||
| @@ -31,7 +31,7 @@ | |||
| 31 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
| 32 | #include <asm/elf.h> | 32 | #include <asm/elf.h> |
| 33 | 33 | ||
| 34 | struct __read_mostly va_alignment va_align = { | 34 | struct va_alignment __read_mostly va_align = { |
| 35 | .flags = -1, | 35 | .flags = -1, |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index a56bb3528755..c846a9608cbd 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c | |||
| @@ -22,7 +22,7 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, | |||
| 22 | unsigned long map_size, unsigned long desc_size, | 22 | unsigned long map_size, unsigned long desc_size, |
| 23 | u32 desc_ver) | 23 | u32 desc_ver) |
| 24 | { | 24 | { |
| 25 | int node, prev; | 25 | int node, prev, num_rsv; |
| 26 | int status; | 26 | int status; |
| 27 | u32 fdt_val32; | 27 | u32 fdt_val32; |
| 28 | u64 fdt_val64; | 28 | u64 fdt_val64; |
| @@ -73,6 +73,14 @@ efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, | |||
| 73 | prev = node; | 73 | prev = node; |
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | /* | ||
| 77 | * Delete all memory reserve map entries. When booting via UEFI, | ||
| 78 | * kernel will use the UEFI memory map to find reserved regions. | ||
| 79 | */ | ||
| 80 | num_rsv = fdt_num_mem_rsv(fdt); | ||
| 81 | while (num_rsv-- > 0) | ||
| 82 | fdt_del_mem_rsv(fdt, num_rsv); | ||
| 83 | |||
| 76 | node = fdt_subnode_offset(fdt, 0, "chosen"); | 84 | node = fdt_subnode_offset(fdt, 0, "chosen"); |
| 77 | if (node < 0) { | 85 | if (node < 0) { |
| 78 | node = fdt_add_subnode(fdt, 0, "chosen"); | 86 | node = fdt_add_subnode(fdt, 0, "chosen"); |
