diff options
Diffstat (limited to 'fs/proc/task_mmu.c')
-rw-r--r-- | fs/proc/task_mmu.c | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index ee5a235b3056..f5532e6e1157 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -123,6 +123,56 @@ static void release_task_mempolicy(struct proc_maps_private *priv) | |||
123 | } | 123 | } |
124 | #endif | 124 | #endif |
125 | 125 | ||
126 | static void seq_print_vma_name(struct seq_file *m, struct vm_area_struct *vma) | ||
127 | { | ||
128 | const char __user *name = vma_get_anon_name(vma); | ||
129 | struct mm_struct *mm = vma->vm_mm; | ||
130 | |||
131 | unsigned long page_start_vaddr; | ||
132 | unsigned long page_offset; | ||
133 | unsigned long num_pages; | ||
134 | unsigned long max_len = NAME_MAX; | ||
135 | int i; | ||
136 | |||
137 | page_start_vaddr = (unsigned long)name & PAGE_MASK; | ||
138 | page_offset = (unsigned long)name - page_start_vaddr; | ||
139 | num_pages = DIV_ROUND_UP(page_offset + max_len, PAGE_SIZE); | ||
140 | |||
141 | seq_puts(m, "[anon:"); | ||
142 | |||
143 | for (i = 0; i < num_pages; i++) { | ||
144 | int len; | ||
145 | int write_len; | ||
146 | const char *kaddr; | ||
147 | long pages_pinned; | ||
148 | struct page *page; | ||
149 | |||
150 | pages_pinned = get_user_pages_remote(mm, page_start_vaddr, 1, 0, | ||
151 | &page, NULL, NULL); | ||
152 | if (pages_pinned < 1) { | ||
153 | seq_puts(m, "<fault>]"); | ||
154 | return; | ||
155 | } | ||
156 | |||
157 | kaddr = (const char *)kmap(page); | ||
158 | len = min(max_len, PAGE_SIZE - page_offset); | ||
159 | write_len = strnlen(kaddr + page_offset, len); | ||
160 | seq_write(m, kaddr + page_offset, write_len); | ||
161 | kunmap(page); | ||
162 | put_page(page); | ||
163 | |||
164 | /* if strnlen hit a null terminator then we're done */ | ||
165 | if (write_len != len) | ||
166 | break; | ||
167 | |||
168 | max_len -= len; | ||
169 | page_offset = 0; | ||
170 | page_start_vaddr += PAGE_SIZE; | ||
171 | } | ||
172 | |||
173 | seq_putc(m, ']'); | ||
174 | } | ||
175 | |||
126 | static void *m_start(struct seq_file *m, loff_t *ppos) | 176 | static void *m_start(struct seq_file *m, loff_t *ppos) |
127 | { | 177 | { |
128 | struct proc_maps_private *priv = m->private; | 178 | struct proc_maps_private *priv = m->private; |
@@ -319,8 +369,15 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) | |||
319 | goto done; | 369 | goto done; |
320 | } | 370 | } |
321 | 371 | ||
322 | if (is_stack(vma)) | 372 | if (is_stack(vma)) { |
323 | name = "[stack]"; | 373 | name = "[stack]"; |
374 | goto done; | ||
375 | } | ||
376 | |||
377 | if (vma_get_anon_name(vma)) { | ||
378 | seq_pad(m, ' '); | ||
379 | seq_print_vma_name(m, vma); | ||
380 | } | ||
324 | } | 381 | } |
325 | 382 | ||
326 | done: | 383 | done: |
@@ -820,6 +877,11 @@ static int show_smap(struct seq_file *m, void *v) | |||
820 | smap_gather_stats(vma, &mss, 0); | 877 | smap_gather_stats(vma, &mss, 0); |
821 | 878 | ||
822 | show_map_vma(m, vma); | 879 | show_map_vma(m, vma); |
880 | if (vma_get_anon_name(vma)) { | ||
881 | seq_puts(m, "Name: "); | ||
882 | seq_print_vma_name(m, vma); | ||
883 | seq_putc(m, '\n'); | ||
884 | } | ||
823 | 885 | ||
824 | SEQ_PUT_DEC("Size: ", vma->vm_end - vma->vm_start); | 886 | SEQ_PUT_DEC("Size: ", vma->vm_end - vma->vm_start); |
825 | SEQ_PUT_DEC(" kB\nKernelPageSize: ", vma_kernel_pagesize(vma)); | 887 | SEQ_PUT_DEC(" kB\nKernelPageSize: ", vma_kernel_pagesize(vma)); |