Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 176708
b: refs/heads/master
c: 06a7f71
h: refs/heads/master
v: v3
  • Loading branch information
Amerigo Wang authored and Linus Torvalds committed Dec 16, 2009
1 parent 236428e commit 7dcab0d
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1f2c19f8c959c1d0ccd3e33b1f480593b66d95dd
refs/heads/master: 06a7f711246b081afc21fff859f1003f1f2a0fbc
2 changes: 2 additions & 0 deletions trunk/include/linux/kexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ extern size_t vmcoreinfo_max_size;

int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
unsigned long long *crash_size, unsigned long long *crash_base);
int crash_shrink_memory(unsigned long new_size);
size_t crash_get_memory_size(void);

#else /* !CONFIG_KEXEC */
struct pt_regs;
Expand Down
59 changes: 59 additions & 0 deletions trunk/kernel/kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <linux/cpu.h>
#include <linux/console.h>
#include <linux/vmalloc.h>
#include <linux/swap.h>

#include <asm/page.h>
#include <asm/uaccess.h>
Expand Down Expand Up @@ -1082,6 +1083,64 @@ void crash_kexec(struct pt_regs *regs)
}
}

size_t crash_get_memory_size(void)
{
size_t size;
mutex_lock(&kexec_mutex);
size = crashk_res.end - crashk_res.start + 1;
mutex_unlock(&kexec_mutex);
return size;
}

static void free_reserved_phys_range(unsigned long begin, unsigned long end)
{
unsigned long addr;

for (addr = begin; addr < end; addr += PAGE_SIZE) {
ClearPageReserved(pfn_to_page(addr >> PAGE_SHIFT));
init_page_count(pfn_to_page(addr >> PAGE_SHIFT));
free_page((unsigned long)__va(addr));
totalram_pages++;
}
}

int crash_shrink_memory(unsigned long new_size)
{
int ret = 0;
unsigned long start, end;

mutex_lock(&kexec_mutex);

if (kexec_crash_image) {
ret = -ENOENT;
goto unlock;
}
start = crashk_res.start;
end = crashk_res.end;

if (new_size >= end - start + 1) {
ret = -EINVAL;
if (new_size == end - start + 1)
ret = 0;
goto unlock;
}

start = roundup(start, PAGE_SIZE);
end = roundup(start + new_size, PAGE_SIZE);

free_reserved_phys_range(end, crashk_res.end);

if (start == end) {
crashk_res.end = end;
release_resource(&crashk_res);
} else
crashk_res.end = end - 1;

unlock:
mutex_unlock(&kexec_mutex);
return ret;
}

static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
size_t data_len)
{
Expand Down
21 changes: 21 additions & 0 deletions trunk/kernel/ksysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,26 @@ static ssize_t kexec_crash_loaded_show(struct kobject *kobj,
}
KERNEL_ATTR_RO(kexec_crash_loaded);

static ssize_t kexec_crash_size_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%zu\n", crash_get_memory_size());
}
static ssize_t kexec_crash_size_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
unsigned long cnt;
int ret;

if (strict_strtoul(buf, 0, &cnt))
return -EINVAL;

ret = crash_shrink_memory(cnt);
return ret < 0 ? ret : count;
}
KERNEL_ATTR_RW(kexec_crash_size);

static ssize_t vmcoreinfo_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
Expand Down Expand Up @@ -147,6 +167,7 @@ static struct attribute * kernel_attrs[] = {
#ifdef CONFIG_KEXEC
&kexec_loaded_attr.attr,
&kexec_crash_loaded_attr.attr,
&kexec_crash_size_attr.attr,
&vmcoreinfo_attr.attr,
#endif
NULL
Expand Down

0 comments on commit 7dcab0d

Please sign in to comment.