kgdb,debug_core: pass the breakpoint struct instead of address and memory
[linux-flexiantxendom0-3.2.10.git] / kernel / kexec.c
index e7e3d97..7b08867 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/console.h>
 #include <linux/vmalloc.h>
 #include <linux/swap.h>
-#include <linux/kmsg_dump.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/page.h>
 #include <asm/uaccess.h>
@@ -497,7 +497,7 @@ static struct page *kimage_alloc_crash_control_pages(struct kimage *image,
        while (hole_end <= crashk_res.end) {
                unsigned long i;
 
-               if (hole_end > KEXEC_CONTROL_MEMORY_LIMIT)
+               if (hole_end > KEXEC_CRASH_CONTROL_MEMORY_LIMIT)
                        break;
                if (hole_end > crashk_res.end)
                        break;
@@ -998,6 +998,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
                        kimage_free(xchg(&kexec_crash_image, NULL));
                        result = kimage_crash_alloc(&image, entry,
                                                     nr_segments, segments);
+                       crash_map_reserved_pages();
                }
                if (result)
                        goto out;
@@ -1014,6 +1015,8 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
                                goto out;
                }
                kimage_terminate(image);
+               if (flags & KEXEC_ON_CRASH)
+                       crash_unmap_reserved_pages();
        }
        /* Install the new kernel, and  Uninstall the old */
        image = xchg(dest_image, image);
@@ -1025,6 +1028,18 @@ out:
        return result;
 }
 
+/*
+ * Add and remove page tables for crashkernel memory
+ *
+ * Provide an empty default implementation here -- architecture
+ * code may override this
+ */
+void __weak crash_map_reserved_pages(void)
+{}
+
+void __weak crash_unmap_reserved_pages(void)
+{}
+
 #ifdef CONFIG_COMPAT
 asmlinkage long compat_sys_kexec_load(unsigned long entry,
                                unsigned long nr_segments,
@@ -1078,8 +1093,6 @@ void crash_kexec(struct pt_regs *regs)
                if (kexec_crash_image) {
                        struct pt_regs fixed_regs;
 
-                       kmsg_dump(KMSG_DUMP_KEXEC);
-
                        crash_setup_regs(&fixed_regs, regs);
                        crash_save_vmcoreinfo();
                        machine_crash_shutdown(&fixed_regs);
@@ -1094,12 +1107,13 @@ size_t crash_get_memory_size(void)
        size_t size = 0;
        mutex_lock(&kexec_mutex);
        if (crashk_res.end != crashk_res.start)
-               size = crashk_res.end - crashk_res.start + 1;
+               size = resource_size(&crashk_res);
        mutex_unlock(&kexec_mutex);
        return size;
 }
 
-static void free_reserved_phys_range(unsigned long begin, unsigned long end)
+void __weak crash_free_reserved_phys_range(unsigned long begin,
+                                          unsigned long end)
 {
        unsigned long addr;
 
@@ -1115,6 +1129,8 @@ int crash_shrink_memory(unsigned long new_size)
 {
        int ret = 0;
        unsigned long start, end;
+       unsigned long old_size;
+       struct resource *ram_res;
 
        mutex_lock(&kexec_mutex);
 
@@ -1124,23 +1140,37 @@ int crash_shrink_memory(unsigned long new_size)
        }
        start = crashk_res.start;
        end = crashk_res.end;
+       old_size = (end == 0) ? 0 : end - start + 1;
+       if (new_size >= old_size) {
+               ret = (new_size == old_size) ? 0 : -EINVAL;
+               goto unlock;
+       }
 
-       if (new_size >= end - start + 1) {
-               ret = -EINVAL;
-               if (new_size == end - start + 1)
-                       ret = 0;
+       ram_res = kzalloc(sizeof(*ram_res), GFP_KERNEL);
+       if (!ram_res) {
+               ret = -ENOMEM;
                goto unlock;
        }
 
-       start = roundup(start, PAGE_SIZE);
-       end = roundup(start + new_size, PAGE_SIZE);
+       start = roundup(start, KEXEC_CRASH_MEM_ALIGN);
+       end = roundup(start + new_size, KEXEC_CRASH_MEM_ALIGN);
 
-       free_reserved_phys_range(end, crashk_res.end);
+       crash_map_reserved_pages();
+       crash_free_reserved_phys_range(end, crashk_res.end);
 
        if ((start == end) && (crashk_res.parent != NULL))
                release_resource(&crashk_res);
+
+       ram_res->start = end;
+       ram_res->end = crashk_res.end;
+       ram_res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
+       ram_res->name = "System RAM";
+
        crashk_res.end = end - 1;
 
+       insert_resource(&iomem_resource, ram_res);
+       crash_unmap_reserved_pages();
+
 unlock:
        mutex_unlock(&kexec_mutex);
        return ret;
@@ -1378,24 +1408,23 @@ int __init parse_crashkernel(char                *cmdline,
 }
 
 
-
-void crash_save_vmcoreinfo(void)
+static void update_vmcoreinfo_note(void)
 {
-       u32 *buf;
+       u32 *buf = vmcoreinfo_note;
 
        if (!vmcoreinfo_size)
                return;
-
-       vmcoreinfo_append_str("CRASHTIME=%ld", get_seconds());
-
-       buf = (u32 *)vmcoreinfo_note;
-
        buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
                              vmcoreinfo_size);
-
        final_note(buf);
 }
 
+void crash_save_vmcoreinfo(void)
+{
+       vmcoreinfo_append_str("CRASHTIME=%ld", get_seconds());
+       update_vmcoreinfo_note();
+}
+
 void vmcoreinfo_append_str(const char *fmt, ...)
 {
        va_list args;
@@ -1481,6 +1510,7 @@ static int __init crash_save_vmcoreinfo_init(void)
        VMCOREINFO_NUMBER(PG_swapcache);
 
        arch_crash_save_vmcoreinfo();
+       update_vmcoreinfo_note();
 
        return 0;
 }
@@ -1504,7 +1534,7 @@ int kernel_kexec(void)
 
 #ifdef CONFIG_KEXEC_JUMP
        if (kexec_image->preserve_context) {
-               mutex_lock(&pm_mutex);
+               lock_system_sleep();
                pm_prepare_console();
                error = freeze_processes();
                if (error) {
@@ -1529,8 +1559,7 @@ int kernel_kexec(void)
                if (error)
                        goto Enable_cpus;
                local_irq_disable();
-               /* Suspend system devices */
-               error = sysdev_suspend(PMSG_FREEZE);
+               error = syscore_suspend();
                if (error)
                        goto Enable_irqs;
        } else
@@ -1545,7 +1574,7 @@ int kernel_kexec(void)
 
 #ifdef CONFIG_KEXEC_JUMP
        if (kexec_image->preserve_context) {
-               sysdev_resume();
+               syscore_resume();
  Enable_irqs:
                local_irq_enable();
  Enable_cpus:
@@ -1558,7 +1587,7 @@ int kernel_kexec(void)
                thaw_processes();
  Restore_console:
                pm_restore_console();
-               mutex_unlock(&pm_mutex);
+               unlock_system_sleep();
        }
 #endif