kernel: fix crashlog regression on x86
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>
This commit is contained in:
parent
50e7c1f79d
commit
9a3852bf8c
1 changed files with 32 additions and 20 deletions
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/kernel/crashlog.c
|
+++ b/kernel/crashlog.c
|
||||||
@@ -0,0 +1,193 @@
|
@@ -0,0 +1,196 @@
|
||||||
+/*
|
+/*
|
||||||
+ * Crash information logger
|
+ * Crash information logger
|
||||||
+ * Copyright (C) 2010 Felix Fietkau <nbd@nbd.name>
|
+ * Copyright (C) 2010 Felix Fietkau <nbd@nbd.name>
|
||||||
|
@ -127,6 +127,9 @@
|
||||||
+ if (crashlog_addr)
|
+ if (crashlog_addr)
|
||||||
+ return;
|
+ return;
|
||||||
+
|
+
|
||||||
|
+ if (size <= CRASHLOG_OFFSET + CRASHLOG_SIZE)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
+ addr += size - CRASHLOG_OFFSET;
|
+ addr += size - CRASHLOG_OFFSET;
|
||||||
+ if (memblock_reserve(addr, CRASHLOG_SIZE)) {
|
+ if (memblock_reserve(addr, CRASHLOG_SIZE)) {
|
||||||
+ printk("Crashlog failed to allocate RAM at address 0x%lx\n", (unsigned long) addr);
|
+ printk("Crashlog failed to allocate RAM at address 0x%lx\n", (unsigned long) addr);
|
||||||
|
@ -237,24 +240,6 @@
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+}
|
+}
|
||||||
+module_init(crashlog_init_fs);
|
+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
|
--- a/kernel/module.c
|
||||||
+++ b/kernel/module.c
|
+++ b/kernel/module.c
|
||||||
@@ -275,6 +275,9 @@ static void mod_update_bounds(struct mod
|
@@ -275,6 +275,9 @@ static void mod_update_bounds(struct mod
|
||||||
|
@ -277,7 +262,16 @@
|
||||||
|
|
||||||
#include <asm-generic/sections.h>
|
#include <asm-generic/sections.h>
|
||||||
#include <linux/io.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;
|
type->regions[0].flags = flags;
|
||||||
memblock_set_region_node(&type->regions[0], nid);
|
memblock_set_region_node(&type->regions[0], nid);
|
||||||
type->total_size = size;
|
type->total_size = size;
|
||||||
|
@ -286,3 +280,21 @@
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
repeat:
|
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;
|
||||||
|
|
Loading…
Reference in a new issue