diff options
author | Linn Crosetto <linn@hp.com> | 2013-08-13 17:46:41 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2013-08-14 02:29:19 -0400 |
commit | 30e46b574a1db7d14404e52dca8e1aa5f5155fd2 (patch) | |
tree | 830c013b0e1bc37b77590df2998e664c89974571 /arch/x86/kernel/e820.c | |
parent | 2449f343e4adc778de1c3d45b5aa14fe788663f5 (diff) |
x86: avoid remapping data in parse_setup_data()
Type SETUP_PCI, added by setup_efi_pci(), may advertise a ROM size
larger than early_memremap() is able to handle, which is currently
limited to 256kB. If this occurs it leads to a NULL dereference in
parse_setup_data().
To avoid this, remap the setup_data header and allow parsing functions
for individual types to handle their own data remapping.
Signed-off-by: Linn Crosetto <linn@hp.com>
Link: http://lkml.kernel.org/r/1376430401-67445-1-git-send-email-linn@hp.com
Acked-by: Yinghai Lu <yinghai@kernel.org>
Reviewed-by: Pekka Enberg <penberg@kernel.org>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/kernel/e820.c')
-rw-r--r-- | arch/x86/kernel/e820.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index d32abeabbda5..174da5fc5a7b 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -658,15 +658,18 @@ __init void e820_setup_gap(void) | |||
658 | * boot_params.e820_map, others are passed via SETUP_E820_EXT node of | 658 | * boot_params.e820_map, others are passed via SETUP_E820_EXT node of |
659 | * linked list of struct setup_data, which is parsed here. | 659 | * linked list of struct setup_data, which is parsed here. |
660 | */ | 660 | */ |
661 | void __init parse_e820_ext(struct setup_data *sdata) | 661 | void __init parse_e820_ext(u64 phys_addr, u32 data_len) |
662 | { | 662 | { |
663 | int entries; | 663 | int entries; |
664 | struct e820entry *extmap; | 664 | struct e820entry *extmap; |
665 | struct setup_data *sdata; | ||
665 | 666 | ||
667 | sdata = early_memremap(phys_addr, data_len); | ||
666 | entries = sdata->len / sizeof(struct e820entry); | 668 | entries = sdata->len / sizeof(struct e820entry); |
667 | extmap = (struct e820entry *)(sdata->data); | 669 | extmap = (struct e820entry *)(sdata->data); |
668 | __append_e820_map(extmap, entries); | 670 | __append_e820_map(extmap, entries); |
669 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); | 671 | sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); |
672 | early_iounmap(sdata, data_len); | ||
670 | printk(KERN_INFO "e820: extended physical RAM map:\n"); | 673 | printk(KERN_INFO "e820: extended physical RAM map:\n"); |
671 | e820_print_map("extended"); | 674 | e820_print_map("extended"); |
672 | } | 675 | } |