]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - kernel/crash_core.c
mei: exclude device from suspend direct complete optimization
[karo-tx-linux.git] / kernel / crash_core.c
index fcbd568f1e95069e6f42a46cad5f5c739f273def..6db80fc0810b9270b0cec3d7cfa2cf9b5a3413f1 100644 (file)
 #include <asm/sections.h>
 
 /* vmcoreinfo stuff */
-static unsigned char vmcoreinfo_data[VMCOREINFO_BYTES];
-u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
-size_t vmcoreinfo_size;
-size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data);
+static unsigned char *vmcoreinfo_data;
+static size_t vmcoreinfo_size;
+u32 *vmcoreinfo_note;
+
+/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
+static unsigned char *vmcoreinfo_data_safecopy;
 
 /*
  * parsing the "crashkernel" commandline
@@ -324,8 +326,23 @@ static void update_vmcoreinfo_note(void)
        final_note(buf);
 }
 
+void crash_update_vmcoreinfo_safecopy(void *ptr)
+{
+       if (ptr)
+               memcpy(ptr, vmcoreinfo_data, vmcoreinfo_size);
+
+       vmcoreinfo_data_safecopy = ptr;
+}
+
 void crash_save_vmcoreinfo(void)
 {
+       if (!vmcoreinfo_note)
+               return;
+
+       /* Use the safe copy to generate vmcoreinfo note if have */
+       if (vmcoreinfo_data_safecopy)
+               vmcoreinfo_data = vmcoreinfo_data_safecopy;
+
        vmcoreinfo_append_str("CRASHTIME=%ld\n", get_seconds());
        update_vmcoreinfo_note();
 }
@@ -340,7 +357,7 @@ void vmcoreinfo_append_str(const char *fmt, ...)
        r = vscnprintf(buf, sizeof(buf), fmt, args);
        va_end(args);
 
-       r = min(r, vmcoreinfo_max_size - vmcoreinfo_size);
+       r = min(r, (size_t)VMCOREINFO_BYTES - vmcoreinfo_size);
 
        memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
 
@@ -356,11 +373,26 @@ void __weak arch_crash_save_vmcoreinfo(void)
 
 phys_addr_t __weak paddr_vmcoreinfo_note(void)
 {
-       return __pa_symbol((unsigned long)(char *)&vmcoreinfo_note);
+       return __pa(vmcoreinfo_note);
 }
 
 static int __init crash_save_vmcoreinfo_init(void)
 {
+       vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
+       if (!vmcoreinfo_data) {
+               pr_warn("Memory allocation for vmcoreinfo_data failed\n");
+               return -ENOMEM;
+       }
+
+       vmcoreinfo_note = alloc_pages_exact(VMCOREINFO_NOTE_SIZE,
+                                               GFP_KERNEL | __GFP_ZERO);
+       if (!vmcoreinfo_note) {
+               free_page((unsigned long)vmcoreinfo_data);
+               vmcoreinfo_data = NULL;
+               pr_warn("Memory allocation for vmcoreinfo_note failed\n");
+               return -ENOMEM;
+       }
+
        VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
        VMCOREINFO_PAGESIZE(PAGE_SIZE);