diff options
| -rw-r--r-- | arch/ia64/kernel/efi.c | 30 | ||||
| -rw-r--r-- | arch/ia64/kernel/setup.c | 30 | ||||
| -rw-r--r-- | include/asm-ia64/meminit.h | 6 |
3 files changed, 65 insertions, 1 deletions
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 32ce330cbc64..4061593e5b17 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c | |||
| @@ -1183,3 +1183,33 @@ kdump_find_rsvd_region (unsigned long size, | |||
| 1183 | return ~0UL; | 1183 | return ~0UL; |
| 1184 | } | 1184 | } |
| 1185 | #endif | 1185 | #endif |
| 1186 | |||
| 1187 | #ifdef CONFIG_PROC_VMCORE | ||
| 1188 | /* locate the size find a the descriptor at a certain address */ | ||
| 1189 | unsigned long | ||
| 1190 | vmcore_find_descriptor_size (unsigned long address) | ||
| 1191 | { | ||
| 1192 | void *efi_map_start, *efi_map_end, *p; | ||
| 1193 | efi_memory_desc_t *md; | ||
| 1194 | u64 efi_desc_size; | ||
| 1195 | unsigned long ret = 0; | ||
| 1196 | |||
| 1197 | efi_map_start = __va(ia64_boot_param->efi_memmap); | ||
| 1198 | efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; | ||
| 1199 | efi_desc_size = ia64_boot_param->efi_memdesc_size; | ||
| 1200 | |||
| 1201 | for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { | ||
| 1202 | md = p; | ||
| 1203 | if (efi_wb(md) && md->type == EFI_LOADER_DATA | ||
| 1204 | && md->phys_addr == address) { | ||
| 1205 | ret = efi_md_size(md); | ||
| 1206 | break; | ||
| 1207 | } | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | if (ret == 0) | ||
| 1211 | printk(KERN_WARNING "Cannot locate EFI vmcore descriptor\n"); | ||
| 1212 | |||
| 1213 | return ret; | ||
| 1214 | } | ||
| 1215 | #endif | ||
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 5fa09d141ab7..7d6fe65c93f4 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
| @@ -251,6 +251,12 @@ reserve_memory (void) | |||
| 251 | } | 251 | } |
| 252 | #endif | 252 | #endif |
| 253 | 253 | ||
| 254 | #ifdef CONFIG_PROC_VMCORE | ||
| 255 | if (reserve_elfcorehdr(&rsvd_region[n].start, | ||
| 256 | &rsvd_region[n].end) == 0) | ||
| 257 | n++; | ||
| 258 | #endif | ||
| 259 | |||
| 254 | efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end); | 260 | efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end); |
| 255 | n++; | 261 | n++; |
| 256 | 262 | ||
| @@ -453,6 +459,30 @@ static int __init parse_elfcorehdr(char *arg) | |||
| 453 | return 0; | 459 | return 0; |
| 454 | } | 460 | } |
| 455 | early_param("elfcorehdr", parse_elfcorehdr); | 461 | early_param("elfcorehdr", parse_elfcorehdr); |
| 462 | |||
| 463 | int __init reserve_elfcorehdr(unsigned long *start, unsigned long *end) | ||
| 464 | { | ||
| 465 | unsigned long length; | ||
| 466 | |||
| 467 | /* We get the address using the kernel command line, | ||
| 468 | * but the size is extracted from the EFI tables. | ||
| 469 | * Both address and size are required for reservation | ||
| 470 | * to work properly. | ||
| 471 | */ | ||
| 472 | |||
| 473 | if (elfcorehdr_addr >= ELFCORE_ADDR_MAX) | ||
| 474 | return -EINVAL; | ||
| 475 | |||
| 476 | if ((length = vmcore_find_descriptor_size(elfcorehdr_addr)) == 0) { | ||
| 477 | elfcorehdr_addr = ELFCORE_ADDR_MAX; | ||
| 478 | return -EINVAL; | ||
| 479 | } | ||
| 480 | |||
| 481 | *start = (unsigned long)__va(elfcorehdr_addr); | ||
| 482 | *end = *start + length; | ||
| 483 | return 0; | ||
| 484 | } | ||
| 485 | |||
| 456 | #endif /* CONFIG_PROC_VMCORE */ | 486 | #endif /* CONFIG_PROC_VMCORE */ |
| 457 | 487 | ||
| 458 | void __init | 488 | void __init |
diff --git a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h index 6dd476b652c6..21ec5f3d23de 100644 --- a/include/asm-ia64/meminit.h +++ b/include/asm-ia64/meminit.h | |||
| @@ -17,10 +17,11 @@ | |||
| 17 | * - kernel code & data | 17 | * - kernel code & data |
| 18 | * - crash dumping code reserved region | 18 | * - crash dumping code reserved region |
| 19 | * - Kernel memory map built from EFI memory map | 19 | * - Kernel memory map built from EFI memory map |
| 20 | * - ELF core header | ||
| 20 | * | 21 | * |
| 21 | * More could be added if necessary | 22 | * More could be added if necessary |
| 22 | */ | 23 | */ |
| 23 | #define IA64_MAX_RSVD_REGIONS 7 | 24 | #define IA64_MAX_RSVD_REGIONS 8 |
| 24 | 25 | ||
| 25 | struct rsvd_region { | 26 | struct rsvd_region { |
| 26 | unsigned long start; /* virtual address of beginning of element */ | 27 | unsigned long start; /* virtual address of beginning of element */ |
| @@ -36,6 +37,9 @@ extern void find_initrd (void); | |||
| 36 | extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg); | 37 | extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg); |
| 37 | extern void efi_memmap_init(unsigned long *, unsigned long *); | 38 | extern void efi_memmap_init(unsigned long *, unsigned long *); |
| 38 | 39 | ||
| 40 | extern unsigned long vmcore_find_descriptor_size(unsigned long address); | ||
| 41 | extern int reserve_elfcorehdr(unsigned long *start, unsigned long *end); | ||
| 42 | |||
| 39 | /* | 43 | /* |
| 40 | * For rounding an address to the next IA64_GRANULE_SIZE or order | 44 | * For rounding an address to the next IA64_GRANULE_SIZE or order |
| 41 | */ | 45 | */ |
