Merge tag 'v4.4.3'
[firefly-linux-kernel-4.4.55.git] / fs / proc / task_mmu.c
index 09cd3edde08a3b307cb3b4b9d0abc0ef354979a3..67aa7e63a5c169a0634ff94c3012be3aa4a9691f 100644 (file)
@@ -116,6 +116,56 @@ static void release_task_mempolicy(struct proc_maps_private *priv)
 }
 #endif
 
+static void seq_print_vma_name(struct seq_file *m, struct vm_area_struct *vma)
+{
+       const char __user *name = vma_get_anon_name(vma);
+       struct mm_struct *mm = vma->vm_mm;
+
+       unsigned long page_start_vaddr;
+       unsigned long page_offset;
+       unsigned long num_pages;
+       unsigned long max_len = NAME_MAX;
+       int i;
+
+       page_start_vaddr = (unsigned long)name & PAGE_MASK;
+       page_offset = (unsigned long)name - page_start_vaddr;
+       num_pages = DIV_ROUND_UP(page_offset + max_len, PAGE_SIZE);
+
+       seq_puts(m, "[anon:");
+
+       for (i = 0; i < num_pages; i++) {
+               int len;
+               int write_len;
+               const char *kaddr;
+               long pages_pinned;
+               struct page *page;
+
+               pages_pinned = get_user_pages(current, mm, page_start_vaddr,
+                               1, 0, 0, &page, NULL);
+               if (pages_pinned < 1) {
+                       seq_puts(m, "<fault>]");
+                       return;
+               }
+
+               kaddr = (const char *)kmap(page);
+               len = min(max_len, PAGE_SIZE - page_offset);
+               write_len = strnlen(kaddr + page_offset, len);
+               seq_write(m, kaddr + page_offset, write_len);
+               kunmap(page);
+               put_page(page);
+
+               /* if strnlen hit a null terminator then we're done */
+               if (write_len != len)
+                       break;
+
+               max_len -= len;
+               page_offset = 0;
+               page_start_vaddr += PAGE_SIZE;
+       }
+
+       seq_putc(m, ']');
+}
+
 static void vma_stop(struct proc_maps_private *priv)
 {
        struct mm_struct *mm = priv->mm;
@@ -351,6 +401,12 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
                                seq_pad(m, ' ');
                                seq_printf(m, "[stack:%d]", tid);
                        }
+                       goto done;
+               }
+
+               if (vma_get_anon_name(vma)) {
+                       seq_pad(m, ' ');
+                       seq_print_vma_name(m, vma);
                }
        }
 
@@ -676,6 +732,12 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
 
        show_map_vma(m, vma, is_pid);
 
+       if (vma_get_anon_name(vma)) {
+               seq_puts(m, "Name:           ");
+               seq_print_vma_name(m, vma);
+               seq_putc(m, '\n');
+       }
+
        seq_printf(m,
                   "Size:           %8lu kB\n"
                   "Rss:            %8lu kB\n"