lkml.org 
[lkml]   [2013]   [Aug]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH] x86: selective remapping in parse_setup_data()
Date
PCI devices may advertise a ROM size larger than early_memremap() is
able to handle. If this occurs it leads to a NULL dereference in
parse_setup_data(). Avoid this by remapping the data only when
necessary.

Signed-off-by: Linn Crosetto <linn@hp.com>
---
arch/x86/kernel/setup.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f8ec578..2063a49 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -423,6 +423,17 @@ static void __init reserve_initrd(void)
}
#endif /* CONFIG_BLK_DEV_INITRD */

+static void __init remap_setup_data(u64 pa_data, u32 data_len,
+ struct setup_data **data, u32 *map_len)
+{
+ if (data_len <= *map_len)
+ return;
+
+ early_iounmap(*data, *map_len);
+ *data = early_memremap(pa_data, data_len);
+ *map_len = data_len;
+}
+
static void __init parse_setup_data(void)
{
struct setup_data *data;
@@ -432,18 +443,16 @@ static void __init parse_setup_data(void)
while (pa_data) {
u32 data_len, map_len;

+ /* The data length may be too large for early remapping,
+ remap the data only when needed. */
map_len = max(PAGE_SIZE - (pa_data & ~PAGE_MASK),
(u64)sizeof(struct setup_data));
data = early_memremap(pa_data, map_len);
data_len = data->len + sizeof(struct setup_data);
- if (data_len > map_len) {
- early_iounmap(data, map_len);
- data = early_memremap(pa_data, data_len);
- map_len = data_len;
- }

switch (data->type) {
case SETUP_E820_EXT:
+ remap_setup_data(pa_data, data_len, &data, &map_len);
parse_e820_ext(data);
break;
case SETUP_DTB:
--
1.7.11.3


\
 
 \ /
  Last update: 2013-08-12 23:41    [W:0.112 / U:0.588 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site