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 Thomas Gleixner:
"Assorted updates to kexec/kdump:

- Proper kexec support for 4/5-level paging and jumping from a
5-level to a 4-level paging kernel.

- Make the EFI support for kexec/kdump more robust

- Enforce that the GDT is properly aligned instead of getting the
alignment by chance"

* 'x86-boot-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/kdump/64: Restrict kdump kernel reservation to <64TB
x86/kexec/64: Prevent kexec from 5-level paging to a 4-level only kernel
x86/boot: Add xloadflags bits to check for 5-level paging support
x86/boot: Make the GDT 8-byte aligned
x86/kexec: Add the ACPI NVS region to the ident map
x86/boot: Call get_rsdp_addr() after console_init()
Revert "x86/boot: Disable RSDP parsing temporarily"
x86/boot: Use efi_setup_data for searching RSDP on kexec-ed kernels
x86/kexec: Add the EFI system tables and ACPI tables to the ident map

+234 -43
+107 -36
arch/x86/boot/compressed/acpi.c
··· 44 44 return addr; 45 45 } 46 46 47 - /* Search EFI system tables for RSDP. */ 48 - static acpi_physical_address efi_get_rsdp_addr(void) 47 + /* 48 + * Search EFI system tables for RSDP. If both ACPI_20_TABLE_GUID and 49 + * ACPI_TABLE_GUID are found, take the former, which has more features. 50 + */ 51 + static acpi_physical_address 52 + __efi_get_rsdp_addr(unsigned long config_tables, unsigned int nr_tables, 53 + bool efi_64) 49 54 { 50 55 acpi_physical_address rsdp_addr = 0; 51 56 52 57 #ifdef CONFIG_EFI 53 - unsigned long systab, systab_tables, config_tables; 58 + int i; 59 + 60 + /* Get EFI tables from systab. */ 61 + for (i = 0; i < nr_tables; i++) { 62 + acpi_physical_address table; 63 + efi_guid_t guid; 64 + 65 + if (efi_64) { 66 + efi_config_table_64_t *tbl = (efi_config_table_64_t *)config_tables + i; 67 + 68 + guid = tbl->guid; 69 + table = tbl->table; 70 + 71 + if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) { 72 + debug_putstr("Error getting RSDP address: EFI config table located above 4GB.\n"); 73 + return 0; 74 + } 75 + } else { 76 + efi_config_table_32_t *tbl = (efi_config_table_32_t *)config_tables + i; 77 + 78 + guid = tbl->guid; 79 + table = tbl->table; 80 + } 81 + 82 + if (!(efi_guidcmp(guid, ACPI_TABLE_GUID))) 83 + rsdp_addr = table; 84 + else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID))) 85 + return table; 86 + } 87 + #endif 88 + return rsdp_addr; 89 + } 90 + 91 + /* EFI/kexec support is 64-bit only. */ 92 + #ifdef CONFIG_X86_64 93 + static struct efi_setup_data *get_kexec_setup_data_addr(void) 94 + { 95 + struct setup_data *data; 96 + u64 pa_data; 97 + 98 + pa_data = boot_params->hdr.setup_data; 99 + while (pa_data) { 100 + data = (struct setup_data *)pa_data; 101 + if (data->type == SETUP_EFI) 102 + return (struct efi_setup_data *)(pa_data + sizeof(struct setup_data)); 103 + 104 + pa_data = data->next; 105 + } 106 + return NULL; 107 + } 108 + 109 + static acpi_physical_address kexec_get_rsdp_addr(void) 110 + { 111 + efi_system_table_64_t *systab; 112 + struct efi_setup_data *esd; 113 + struct efi_info *ei; 114 + char *sig; 115 + 116 + esd = (struct efi_setup_data *)get_kexec_setup_data_addr(); 117 + if (!esd) 118 + return 0; 119 + 120 + if (!esd->tables) { 121 + debug_putstr("Wrong kexec SETUP_EFI data.\n"); 122 + return 0; 123 + } 124 + 125 + ei = &boot_params->efi_info; 126 + sig = (char *)&ei->efi_loader_signature; 127 + if (strncmp(sig, EFI64_LOADER_SIGNATURE, 4)) { 128 + debug_putstr("Wrong kexec EFI loader signature.\n"); 129 + return 0; 130 + } 131 + 132 + /* Get systab from boot params. */ 133 + systab = (efi_system_table_64_t *) (ei->efi_systab | ((__u64)ei->efi_systab_hi << 32)); 134 + if (!systab) 135 + error("EFI system table not found in kexec boot_params."); 136 + 137 + return __efi_get_rsdp_addr((unsigned long)esd->tables, systab->nr_tables, true); 138 + } 139 + #else 140 + static acpi_physical_address kexec_get_rsdp_addr(void) { return 0; } 141 + #endif /* CONFIG_X86_64 */ 142 + 143 + static acpi_physical_address efi_get_rsdp_addr(void) 144 + { 145 + #ifdef CONFIG_EFI 146 + unsigned long systab, config_tables; 54 147 unsigned int nr_tables; 55 148 struct efi_info *ei; 56 149 bool efi_64; 57 - int size, i; 58 150 char *sig; 59 151 60 152 ei = &boot_params->efi_info; ··· 180 88 181 89 config_tables = stbl->tables; 182 90 nr_tables = stbl->nr_tables; 183 - size = sizeof(efi_config_table_64_t); 184 91 } else { 185 92 efi_system_table_32_t *stbl = (efi_system_table_32_t *)systab; 186 93 187 94 config_tables = stbl->tables; 188 95 nr_tables = stbl->nr_tables; 189 - size = sizeof(efi_config_table_32_t); 190 96 } 191 97 192 98 if (!config_tables) 193 99 error("EFI config tables not found."); 194 100 195 - /* Get EFI tables from systab. */ 196 - for (i = 0; i < nr_tables; i++) { 197 - acpi_physical_address table; 198 - efi_guid_t guid; 199 - 200 - config_tables += size; 201 - 202 - if (efi_64) { 203 - efi_config_table_64_t *tbl = (efi_config_table_64_t *)config_tables; 204 - 205 - guid = tbl->guid; 206 - table = tbl->table; 207 - 208 - if (!IS_ENABLED(CONFIG_X86_64) && table >> 32) { 209 - debug_putstr("Error getting RSDP address: EFI config table located above 4GB.\n"); 210 - return 0; 211 - } 212 - } else { 213 - efi_config_table_32_t *tbl = (efi_config_table_32_t *)config_tables; 214 - 215 - guid = tbl->guid; 216 - table = tbl->table; 217 - } 218 - 219 - if (!(efi_guidcmp(guid, ACPI_TABLE_GUID))) 220 - rsdp_addr = table; 221 - else if (!(efi_guidcmp(guid, ACPI_20_TABLE_GUID))) 222 - return table; 223 - } 101 + return __efi_get_rsdp_addr(config_tables, nr_tables, efi_64); 102 + #else 103 + return 0; 224 104 #endif 225 - return rsdp_addr; 226 105 } 227 106 228 107 static u8 compute_checksum(u8 *buffer, u32 length) ··· 282 219 283 220 if (!pa) 284 221 pa = boot_params->acpi_rsdp_addr; 222 + 223 + /* 224 + * Try to get EFI data from setup_data. This can happen when we're a 225 + * kexec'ed kernel and kexec(1) has passed all the required EFI info to 226 + * us. 227 + */ 228 + if (!pa) 229 + pa = kexec_get_rsdp_addr(); 285 230 286 231 if (!pa) 287 232 pa = efi_get_rsdp_addr();
+1
arch/x86/boot/compressed/head_64.S
··· 659 659 gdt64: 660 660 .word gdt_end - gdt 661 661 .quad 0 662 + .balign 8 662 663 gdt: 663 664 .word gdt_end - gdt 664 665 .long gdt
+8 -3
arch/x86/boot/compressed/misc.c
··· 351 351 /* Clear flags intended for solely in-kernel use. */ 352 352 boot_params->hdr.loadflags &= ~KASLR_FLAG; 353 353 354 - /* Save RSDP address for later use. */ 355 - /* boot_params->acpi_rsdp_addr = get_rsdp_addr(); */ 356 - 357 354 sanitize_boot_params(boot_params); 358 355 359 356 if (boot_params->screen_info.orig_video_mode == 7) { ··· 365 368 cols = boot_params->screen_info.orig_video_cols; 366 369 367 370 console_init(); 371 + 372 + /* 373 + * Save RSDP address for later use. Have this after console_init() 374 + * so that early debugging output from the RSDP parsing code can be 375 + * collected. 376 + */ 377 + boot_params->acpi_rsdp_addr = get_rsdp_addr(); 378 + 368 379 debug_putstr("early console in extract_kernel\n"); 369 380 370 381 free_mem_ptr = heap; /* Heap */
+11 -1
arch/x86/boot/header.S
··· 419 419 # define XLF4 0 420 420 #endif 421 421 422 - .word XLF0 | XLF1 | XLF23 | XLF4 422 + #ifdef CONFIG_X86_64 423 + #ifdef CONFIG_X86_5LEVEL 424 + #define XLF56 (XLF_5LEVEL|XLF_5LEVEL_ENABLED) 425 + #else 426 + #define XLF56 XLF_5LEVEL 427 + #endif 428 + #else 429 + #define XLF56 0 430 + #endif 431 + 432 + .word XLF0 | XLF1 | XLF23 | XLF4 | XLF56 423 433 424 434 cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line, 425 435 #added with boot protocol
+2
arch/x86/include/uapi/asm/bootparam.h
··· 29 29 #define XLF_EFI_HANDOVER_32 (1<<2) 30 30 #define XLF_EFI_HANDOVER_64 (1<<3) 31 31 #define XLF_EFI_KEXEC (1<<4) 32 + #define XLF_5LEVEL (1<<5) 33 + #define XLF_5LEVEL_ENABLED (1<<6) 32 34 33 35 #ifndef __ASSEMBLY__ 34 36
+5
arch/x86/kernel/kexec-bzimage64.c
··· 319 319 return ret; 320 320 } 321 321 322 + if (!(header->xloadflags & XLF_5LEVEL) && pgtable_l5_enabled()) { 323 + pr_err("bzImage cannot handle 5-level paging mode.\n"); 324 + return ret; 325 + } 326 + 322 327 /* I've got a bzImage */ 323 328 pr_debug("It's a relocatable bzImage64\n"); 324 329 ret = 0;
+87
arch/x86/kernel/machine_kexec_64.c
··· 16 16 #include <linux/io.h> 17 17 #include <linux/suspend.h> 18 18 #include <linux/vmalloc.h> 19 + #include <linux/efi.h> 19 20 20 21 #include <asm/init.h> 21 22 #include <asm/pgtable.h> ··· 28 27 #include <asm/setup.h> 29 28 #include <asm/set_memory.h> 30 29 30 + #ifdef CONFIG_ACPI 31 + /* 32 + * Used while adding mapping for ACPI tables. 33 + * Can be reused when other iomem regions need be mapped 34 + */ 35 + struct init_pgtable_data { 36 + struct x86_mapping_info *info; 37 + pgd_t *level4p; 38 + }; 39 + 40 + static int mem_region_callback(struct resource *res, void *arg) 41 + { 42 + struct init_pgtable_data *data = arg; 43 + unsigned long mstart, mend; 44 + 45 + mstart = res->start; 46 + mend = mstart + resource_size(res) - 1; 47 + 48 + return kernel_ident_mapping_init(data->info, data->level4p, mstart, mend); 49 + } 50 + 51 + static int 52 + map_acpi_tables(struct x86_mapping_info *info, pgd_t *level4p) 53 + { 54 + struct init_pgtable_data data; 55 + unsigned long flags; 56 + int ret; 57 + 58 + data.info = info; 59 + data.level4p = level4p; 60 + flags = IORESOURCE_MEM | IORESOURCE_BUSY; 61 + 62 + ret = walk_iomem_res_desc(IORES_DESC_ACPI_TABLES, flags, 0, -1, 63 + &data, mem_region_callback); 64 + if (ret && ret != -EINVAL) 65 + return ret; 66 + 67 + /* ACPI tables could be located in ACPI Non-volatile Storage region */ 68 + ret = walk_iomem_res_desc(IORES_DESC_ACPI_NV_STORAGE, flags, 0, -1, 69 + &data, mem_region_callback); 70 + if (ret && ret != -EINVAL) 71 + return ret; 72 + 73 + return 0; 74 + } 75 + #else 76 + static int map_acpi_tables(struct x86_mapping_info *info, pgd_t *level4p) { return 0; } 77 + #endif 78 + 31 79 #ifdef CONFIG_KEXEC_FILE 32 80 const struct kexec_file_ops * const kexec_file_loaders[] = { 33 81 &kexec_bzImage64_ops, 34 82 NULL 35 83 }; 36 84 #endif 85 + 86 + static int 87 + map_efi_systab(struct x86_mapping_info *info, pgd_t *level4p) 88 + { 89 + #ifdef CONFIG_EFI 90 + unsigned long mstart, mend; 91 + 92 + if (!efi_enabled(EFI_BOOT)) 93 + return 0; 94 + 95 + mstart = (boot_params.efi_info.efi_systab | 96 + ((u64)boot_params.efi_info.efi_systab_hi<<32)); 97 + 98 + if (efi_enabled(EFI_64BIT)) 99 + mend = mstart + sizeof(efi_system_table_64_t); 100 + else 101 + mend = mstart + sizeof(efi_system_table_32_t); 102 + 103 + if (!mstart) 104 + return 0; 105 + 106 + return kernel_ident_mapping_init(info, level4p, mstart, mend); 107 + #endif 108 + return 0; 109 + } 37 110 38 111 static void free_transition_pgtable(struct kimage *image) 39 112 { ··· 231 156 if (result) 232 157 return result; 233 158 } 159 + 160 + /* 161 + * Prepare EFI systab and ACPI tables for kexec kernel since they are 162 + * not covered by pfn_mapped. 163 + */ 164 + result = map_efi_systab(&info, level4p); 165 + if (result) 166 + return result; 167 + 168 + result = map_acpi_tables(&info, level4p); 169 + if (result) 170 + return result; 234 171 235 172 return init_transition_pgtable(image, level4p); 236 173 }
+12 -3
arch/x86/kernel/setup.c
··· 453 453 #define CRASH_ALIGN SZ_16M 454 454 455 455 /* 456 - * Keep the crash kernel below this limit. On 32 bits earlier kernels 457 - * would limit the kernel to the low 512 MiB due to mapping restrictions. 456 + * Keep the crash kernel below this limit. 457 + * 458 + * On 32 bits earlier kernels would limit the kernel to the low 512 MiB 459 + * due to mapping restrictions. 460 + * 461 + * On 64bit, kdump kernel need be restricted to be under 64TB, which is 462 + * the upper limit of system RAM in 4-level paing mode. Since the kdump 463 + * jumping could be from 5-level to 4-level, the jumping will fail if 464 + * kernel is put above 64TB, and there's no way to detect the paging mode 465 + * of the kernel which will be loaded for dumping during the 1st kernel 466 + * bootup. 458 467 */ 459 468 #ifdef CONFIG_X86_32 460 469 # define CRASH_ADDR_LOW_MAX SZ_512M 461 470 # define CRASH_ADDR_HIGH_MAX SZ_512M 462 471 #else 463 472 # define CRASH_ADDR_LOW_MAX SZ_4G 464 - # define CRASH_ADDR_HIGH_MAX MAXMEM 473 + # define CRASH_ADDR_HIGH_MAX SZ_64T 465 474 #endif 466 475 467 476 static int __init reserve_crashkernel_low(void)
+1
include/linux/sizes.h
··· 44 44 #define SZ_2G 0x80000000 45 45 46 46 #define SZ_4G _AC(0x100000000, ULL) 47 + #define SZ_64T _AC(0x400000000000, ULL) 47 48 48 49 #endif /* __LINUX_SIZES_H__ */