mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-21 06:01:23 +00:00
MIPS: kdump: Add support
[ralf@linux-mips.org: Original patch by Maxim Uvarov <muvarov@gmail.com> with plenty of further shining, polishing, debugging and testing by me.] Signed-off-by: Maxim Uvarov <muvarov@gmail.com> Cc: linux-mips@linux-mips.org Cc: kexec@lists.infradead.org Cc: horms@verge.net.au Patchwork: https://patchwork.linux-mips.org/patch/1025/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
98cdee0eae
commit
7aa1c8f47e
11 changed files with 396 additions and 9 deletions
77
arch/mips/kernel/crash_dump.c
Normal file
77
arch/mips/kernel/crash_dump.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include <linux/highmem.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/crash_dump.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
|
||||
|
||||
static int __init parse_savemaxmem(char *p)
|
||||
{
|
||||
if (p)
|
||||
saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
__setup("savemaxmem=", parse_savemaxmem);
|
||||
|
||||
|
||||
static void *kdump_buf_page;
|
||||
|
||||
/**
|
||||
* copy_oldmem_page - copy one page from "oldmem"
|
||||
* @pfn: page frame number to be copied
|
||||
* @buf: target memory address for the copy; this can be in kernel address
|
||||
* space or user address space (see @userbuf)
|
||||
* @csize: number of bytes to copy
|
||||
* @offset: offset in bytes into the page (based on pfn) to begin the copy
|
||||
* @userbuf: if set, @buf is in user address space, use copy_to_user(),
|
||||
* otherwise @buf is in kernel address space, use memcpy().
|
||||
*
|
||||
* Copy a page from "oldmem". For this page, there is no pte mapped
|
||||
* in the current kernel.
|
||||
*
|
||||
* Calling copy_to_user() in atomic context is not desirable. Hence first
|
||||
* copying the data to a pre-allocated kernel page and then copying to user
|
||||
* space in non-atomic context.
|
||||
*/
|
||||
ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
|
||||
size_t csize, unsigned long offset, int userbuf)
|
||||
{
|
||||
void *vaddr;
|
||||
|
||||
if (!csize)
|
||||
return 0;
|
||||
|
||||
vaddr = kmap_atomic_pfn(pfn);
|
||||
|
||||
if (!userbuf) {
|
||||
memcpy(buf, (vaddr + offset), csize);
|
||||
kunmap_atomic(vaddr);
|
||||
} else {
|
||||
if (!kdump_buf_page) {
|
||||
pr_warning("Kdump: Kdump buffer page not allocated\n");
|
||||
|
||||
return -EFAULT;
|
||||
}
|
||||
copy_page(kdump_buf_page, vaddr);
|
||||
kunmap_atomic(vaddr);
|
||||
if (copy_to_user(buf, (kdump_buf_page + offset), csize))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return csize;
|
||||
}
|
||||
|
||||
static int __init kdump_buf_page_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!kdump_buf_page) {
|
||||
pr_warning("Kdump: Failed to allocate kdump buffer page\n");
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
arch_initcall(kdump_buf_page_init);
|
Loading…
Add table
Add a link
Reference in a new issue