Merge tag 'v3.10.97' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / binfmt_elf.c
index 948e6f21b5940a18641161e6a53491b78922dba7..b308a2c47f3461f7c1770897c0091d3c77d82cfe 100644 (file)
@@ -1105,6 +1105,11 @@ out:
  * Jeremy Fitzhardinge <jeremy@sw.oz.au>
  */
 
+#ifdef CONFIG_MTK_EXTMEM
+extern bool extmem_in_mspace(struct vm_area_struct *vma);
+extern unsigned long get_virt_from_mspace(unsigned long pa);
+#endif
+
 /*
  * The purpose of always_dump_vma() is to make sure that special kernel mappings
  * that are useful for post-mortem analysis are included in every core dump.
@@ -1125,6 +1130,11 @@ static bool always_dump_vma(struct vm_area_struct *vma)
        if (arch_vma_name(vma))
                return true;
 
+#ifdef CONFIG_MTK_EXTMEM
+       if (extmem_in_mspace(vma)) {
+               return true;
+       }       
+#endif
        return false;
 }
 
@@ -2066,6 +2076,8 @@ static int elf_core_dump(struct coredump_params *cprm)
        Elf_Half e_phnum;
        elf_addr_t e_shoff;
 
+       printk(KERN_WARNING "coredump(%d): start\n", current->pid);
+
        /*
         * We no longer stop all VM operations.
         * 
@@ -2194,6 +2206,8 @@ static int elf_core_dump(struct coredump_params *cprm)
        if (!dump_seek(cprm->file, dataoff - foffset))
                goto end_coredump;
 
+       printk(KERN_WARNING "coredump(%d): write output program header and notes\n", current->pid);
+
        for (vma = first_vma(current, gate_vma); vma != NULL;
                        vma = next_vma(vma, gate_vma)) {
                unsigned long addr;
@@ -2201,6 +2215,24 @@ static int elf_core_dump(struct coredump_params *cprm)
 
                end = vma->vm_start + vma_dump_size(vma, cprm->mm_flags);
 
+#ifdef CONFIG_MTK_EXTMEM
+               if (extmem_in_mspace(vma)) {
+                       void *extmem_va = (void *)get_virt_from_mspace(vma->vm_pgoff << PAGE_SHIFT);
+                       for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE, extmem_va += PAGE_SIZE) {
+                               int stop;
+                               int dump_write_ret = dump_write(cprm->file, extmem_va, PAGE_SIZE);
+                               stop = ((size += PAGE_SIZE) > cprm->limit) || (!dump_write_ret);
+                               if (stop) {
+                                       printk(KERN_WARNING "[EXT_MEM]stop addr:0x%lx, size:%zx, limit:0x%lx, dump_write_ret:%d\n", 
+                                                       addr, size, cprm->limit, dump_write_ret);
+                                       goto end_coredump;
+                               }
+                       }
+                       continue;
+               }
+#endif
+
+               //printk(KERN_WARNING "coredump(%d): write out load vm start:%08lx, end:%08lx\n", current->pid, vma->vm_start, end);
                for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
                        struct page *page;
                        int stop;
@@ -2213,13 +2245,22 @@ static int elf_core_dump(struct coredump_params *cprm)
                                                    PAGE_SIZE);
                                kunmap(page);
                                page_cache_release(page);
-                       } else
+                               if (stop) {
+                                       printk(KERN_WARNING "coredump(%d): failed to write core dump\n", current->pid);
+                               }
+                       } else {
                                stop = !dump_seek(cprm->file, PAGE_SIZE);
+                               if (stop) {
+                                       printk(KERN_WARNING "coredump(%d): failed to seek core dump\n", current->pid);
+                               }
+                       }
                        if (stop)
                                goto end_coredump;
                }
        }
 
+       printk(KERN_WARNING "coredump(%d): write loads\n", current->pid);
+
        if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
                goto end_coredump;
 
@@ -2231,6 +2272,8 @@ static int elf_core_dump(struct coredump_params *cprm)
                        goto end_coredump;
        }
 
+       printk(KERN_WARNING "coredump(%d): write out completed %lld\n", current->pid, offset);
+
 end_coredump:
        set_fs(fs);