kernel: fix crashlog regression on x86
authorFelix Fietkau <nbd@nbd.name>
Sat, 30 Jul 2016 10:18:08 +0000 (12:18 +0200)
committerFelix Fietkau <nbd@nbd.name>
Sat, 30 Jul 2016 10:25:57 +0000 (12:25 +0200)
Check memblock regions for sufficient size before attempting to use
them. Allow checks for multiple memblock regions until a suitable one is
found.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
target/linux/generic/patches-4.4/930-crashlog.patch

index 339cffa..311a4f1 100644 (file)
@@ -43,7 +43,7 @@
  
 --- /dev/null
 +++ b/kernel/crashlog.c
-@@ -0,0 +1,193 @@
+@@ -0,0 +1,196 @@
 +/*
 + * Crash information logger
 + * Copyright (C) 2010 Felix Fietkau <nbd@nbd.name>
 +      if (crashlog_addr)
 +              return;
 +
++      if (size <= CRASHLOG_OFFSET + CRASHLOG_SIZE)
++              return;
++
 +      addr += size - CRASHLOG_OFFSET;
 +      if (memblock_reserve(addr, CRASHLOG_SIZE)) {
 +              printk("Crashlog failed to allocate RAM at address 0x%lx\n", (unsigned long) addr);
 +      return 0;
 +}
 +module_init(crashlog_init_fs);
---- a/mm/bootmem.c
-+++ b/mm/bootmem.c
-@@ -15,6 +15,7 @@
- #include <linux/export.h>
- #include <linux/kmemleak.h>
- #include <linux/range.h>
-+#include <linux/crashlog.h>
- #include <linux/memblock.h>
- #include <linux/bug.h>
- #include <linux/io.h>
-@@ -177,6 +178,7 @@ static unsigned long __init free_all_boo
-       if (!bdata->node_bootmem_map)
-               return 0;
-+      crashlog_init_bootmem(bdata);
-       map = bdata->node_bootmem_map;
-       start = bdata->node_min_pfn;
-       end = bdata->node_low_pfn;
 --- a/kernel/module.c
 +++ b/kernel/module.c
 @@ -275,6 +275,9 @@ static void mod_update_bounds(struct mod
  
  #include <asm-generic/sections.h>
  #include <linux/io.h>
-@@ -541,6 +542,8 @@ int __init_memblock memblock_add_range(s
+@@ -503,6 +504,8 @@ static void __init_memblock memblock_ins
+       memblock_set_region_node(rgn, nid);
+       type->cnt++;
+       type->total_size += size;
++      if (type == &memblock.memory)
++              crashlog_init_memblock(base, size);
+ }
+ /**
+@@ -541,6 +544,8 @@ int __init_memblock memblock_add_range(s
                type->regions[0].flags = flags;
                memblock_set_region_node(&type->regions[0], nid);
                type->total_size = size;
                return 0;
        }
  repeat:
+--- a/mm/bootmem.c
++++ b/mm/bootmem.c
+@@ -15,6 +15,7 @@
+ #include <linux/export.h>
+ #include <linux/kmemleak.h>
+ #include <linux/range.h>
++#include <linux/crashlog.h>
+ #include <linux/memblock.h>
+ #include <linux/bug.h>
+ #include <linux/io.h>
+@@ -177,6 +178,7 @@ static unsigned long __init free_all_boo
+       if (!bdata->node_bootmem_map)
+               return 0;
++      crashlog_init_bootmem(bdata);
+       map = bdata->node_bootmem_map;
+       start = bdata->node_min_pfn;
+       end = bdata->node_low_pfn;