aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-04-26 22:25:57 -0400
committerPaul Mundt <lethal@hera.kernel.org>2007-05-06 22:11:56 -0400
commit4d5ade5b29c618e97a8988efb6967cb4dd0e2183 (patch)
tree376d71458747e23e7f5171b9914b0d516cad7c7b /arch/sh/kernel
parentdb62e5bd297d1f325811c5495ad23de36db0fdd4 (diff)
sh: kdump support.
This adds support for kexec based crash dumps. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/Makefile1
-rw-r--r--arch/sh/kernel/crash_dump.c46
-rw-r--r--arch/sh/kernel/machine_kexec.c29
-rw-r--r--arch/sh/kernel/setup.c6
4 files changed, 78 insertions, 4 deletions
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index ff30d7f58043..9104b6257644 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -20,5 +20,6 @@ obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
20obj-$(CONFIG_MODULES) += module.o 20obj-$(CONFIG_MODULES) += module.o
21obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 21obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
22obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 22obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
23obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
23obj-$(CONFIG_PM) += pm.o 24obj-$(CONFIG_PM) += pm.o
24obj-$(CONFIG_STACKTRACE) += stacktrace.o 25obj-$(CONFIG_STACKTRACE) += stacktrace.o
diff --git a/arch/sh/kernel/crash_dump.c b/arch/sh/kernel/crash_dump.c
new file mode 100644
index 000000000000..4a2ecbe27d8e
--- /dev/null
+++ b/arch/sh/kernel/crash_dump.c
@@ -0,0 +1,46 @@
1/*
2 * crash_dump.c - Memory preserving reboot related code.
3 *
4 * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
5 * Copyright (C) IBM Corporation, 2004. All rights reserved
6 */
7
8#include <linux/errno.h>
9#include <linux/crash_dump.h>
10#include <linux/io.h>
11#include <asm/uaccess.h>
12
13/**
14 * copy_oldmem_page - copy one page from "oldmem"
15 * @pfn: page frame number to be copied
16 * @buf: target memory address for the copy; this can be in kernel address
17 * space or user address space (see @userbuf)
18 * @csize: number of bytes to copy
19 * @offset: offset in bytes into the page (based on pfn) to begin the copy
20 * @userbuf: if set, @buf is in user address space, use copy_to_user(),
21 * otherwise @buf is in kernel address space, use memcpy().
22 *
23 * Copy a page from "oldmem". For this page, there is no pte mapped
24 * in the current kernel. We stitch up a pte, similar to kmap_atomic.
25 */
26ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
27 size_t csize, unsigned long offset, int userbuf)
28{
29 void *vaddr;
30
31 if (!csize)
32 return 0;
33
34 vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
35
36 if (userbuf) {
37 if (copy_to_user(buf, (vaddr + offset), csize)) {
38 iounmap(vaddr);
39 return -EFAULT;
40 }
41 } else
42 memcpy(buf, (vaddr + offset), csize);
43
44 iounmap(vaddr);
45 return csize;
46}
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index 08587cdb64d6..790ed69b8666 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -59,13 +59,13 @@ static void kexec_info(struct kimage *image)
59 printk(" segment[%d]: 0x%08x - 0x%08x (0x%08x)\n", 59 printk(" segment[%d]: 0x%08x - 0x%08x (0x%08x)\n",
60 i, 60 i,
61 (unsigned int)image->segment[i].mem, 61 (unsigned int)image->segment[i].mem,
62 (unsigned int)image->segment[i].mem + image->segment[i].memsz, 62 (unsigned int)image->segment[i].mem +
63 image->segment[i].memsz,
63 (unsigned int)image->segment[i].memsz); 64 (unsigned int)image->segment[i].memsz);
64 } 65 }
65 printk(" start : 0x%08x\n\n", (unsigned int)image->start); 66 printk(" start : 0x%08x\n\n", (unsigned int)image->start);
66} 67}
67 68
68
69/* 69/*
70 * Do not allocate memory (or fail in any way) in machine_kexec(). 70 * Do not allocate memory (or fail in any way) in machine_kexec().
71 * We are past the point of no return, committed to rebooting now. 71 * We are past the point of no return, committed to rebooting now.
@@ -101,6 +101,27 @@ NORET_TYPE void machine_kexec(struct kimage *image)
101 101
102 /* now call it */ 102 /* now call it */
103 rnk = (relocate_new_kernel_t) reboot_code_buffer; 103 rnk = (relocate_new_kernel_t) reboot_code_buffer;
104 (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg); 104 (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg);
105} 105}
106 106
107/* crashkernel=size@addr specifies the location to reserve for
108 * a crash kernel. By reserving this memory we guarantee
109 * that linux never sets it up as a DMA target.
110 * Useful for holding code to do something appropriate
111 * after a kernel panic.
112 */
113static int __init parse_crashkernel(char *arg)
114{
115 unsigned long size, base;
116 size = memparse(arg, &arg);
117 if (*arg == '@') {
118 base = memparse(arg+1, &arg);
119 /* FIXME: Do I want a sanity check
120 * to validate the memory range?
121 */
122 crashk_res.start = base;
123 crashk_res.end = base + size - 1;
124 }
125 return 0;
126}
127early_param("crashkernel", parse_crashkernel);
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index cab91a7665da..477d2a854fc4 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -20,6 +20,7 @@
20#include <linux/pfn.h> 20#include <linux/pfn.h>
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/mm.h> 22#include <linux/mm.h>
23#include <linux/kexec.h>
23#include <asm/uaccess.h> 24#include <asm/uaccess.h>
24#include <asm/io.h> 25#include <asm/io.h>
25#include <asm/sections.h> 26#include <asm/sections.h>
@@ -287,6 +288,11 @@ void __init setup_bootmem_allocator(unsigned long start_pfn)
287 } 288 }
288 } 289 }
289#endif 290#endif
291#ifdef CONFIG_KEXEC
292 if (crashk_res.start != crashk_res.end)
293 reserve_bootmem(crashk_res.start,
294 crashk_res.end - crashk_res.start + 1);
295#endif
290} 296}
291 297
292#ifndef CONFIG_NEED_MULTIPLE_NODES 298#ifndef CONFIG_NEED_MULTIPLE_NODES