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 | */ |