kernel: fix crashlog regression on x86
[openwrt/openwrt.git] / target / linux / generic / patches-4.4 / 930-crashlog.patch
index 514ff469d8dc9f9c8101b077dc863030e9e858c9..311a4f1159c4d9e8623b14575d04f34b228c9938 100644 (file)
 +#endif
 --- a/init/Kconfig
 +++ b/init/Kconfig
-@@ -1286,6 +1286,10 @@ config RELAY
+@@ -1296,6 +1296,10 @@ config RELAY
  
          If unsure, say N.
  
 +config CRASHLOG
 +      bool "Crash logging"
-+      depends on (!NO_BOOTMEM || HAVE_MEMBLOCK) && !(ARM || SPARC || PPC)
++      depends on (!NO_BOOTMEM || HAVE_MEMBLOCK)
 +
  config BLK_DEV_INITRD
        bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support"
  
 --- /dev/null
 +++ b/kernel/crashlog.c
-@@ -0,0 +1,181 @@
+@@ -0,0 +1,196 @@
 +/*
 + * Crash information logger
-+ * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2010 Felix Fietkau <nbd@nbd.name>
 + *
 + * Based on ramoops.c
 + *   Copyright (C) 2010 Marco Stornelli <marco.stornelli@gmail.com>
@@ -75,6 +75,7 @@
 +#include <linux/kmsg_dump.h>
 +#include <linux/module.h>
 +#include <linux/pfn.h>
++#include <linux/vmalloc.h>
 +#include <asm/io.h>
 +
 +#define CRASHLOG_PAGES        4
 +      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);
 +
 +int __init crashlog_init_fs(void)
 +{
-+      if (!crashlog_addr)
++      struct page *pages[CRASHLOG_PAGES];
++      pgprot_t prot;
++      int i;
++
++      if (!crashlog_addr) {
++              printk("No memory allocated for crashlog\n");
 +              return -ENOMEM;
++      }
++
++      printk("Crashlog allocated RAM at address 0x%lx\n", (unsigned long) crashlog_addr);
++      for (i = 0; i < CRASHLOG_PAGES; i++)
++              pages[i] = pfn_to_page((crashlog_addr >> PAGE_SHIFT) + i);
 +
-+      crashlog_buf = ioremap(crashlog_addr, CRASHLOG_SIZE);
++      prot = pgprot_writecombine(PAGE_KERNEL);
++      crashlog_buf = vmap(pages, CRASHLOG_PAGES, VM_MAP, prot);
 +
 +      crashlog_copy();
 +
 +      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
        memblock_set_region_node(rgn, nid);
        type->cnt++;
        type->total_size += size;
-+      if (type == &memblock.memory && idx == 0)
++      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;
++              if (type == &memblock.memory)
++                      crashlog_init_memblock(base, 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;