aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/Kconfig4
-rw-r--r--fs/proc/array.c2
-rw-r--r--fs/proc/consoles.c10
-rw-r--r--fs/proc/fd.c2
-rw-r--r--fs/proc/generic.c18
-rw-r--r--fs/proc/inode.c24
-rw-r--r--fs/proc/kcore.c3
-rw-r--r--fs/proc/meminfo.c13
-rw-r--r--fs/proc/namespaces.c8
-rw-r--r--fs/proc/nommu.c12
-rw-r--r--fs/proc/proc_devtree.c3
-rw-r--r--fs/proc/root.c6
-rw-r--r--fs/proc/self.c10
-rw-r--r--fs/proc/task_mmu.c97
-rw-r--r--fs/proc/task_nommu.c19
-rw-r--r--fs/proc/vmcore.c154
16 files changed, 253 insertions, 132 deletions
diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
index 15af6222f8a4..2183fcf41d59 100644
--- a/fs/proc/Kconfig
+++ b/fs/proc/Kconfig
@@ -31,6 +31,10 @@ config PROC_FS
31config PROC_KCORE 31config PROC_KCORE
32 bool "/proc/kcore support" if !ARM 32 bool "/proc/kcore support" if !ARM
33 depends on PROC_FS && MMU 33 depends on PROC_FS && MMU
34 help
35 Provides a virtual ELF core file of the live kernel. This can
36 be read with gdb and other ELF tools. No modifications can be
37 made using this mechanism.
34 38
35config PROC_VMCORE 39config PROC_VMCORE
36 bool "/proc/vmcore support" 40 bool "/proc/vmcore support"
diff --git a/fs/proc/array.c b/fs/proc/array.c
index cbd0f1b324b9..1bd2077187fd 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -183,6 +183,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
183 seq_printf(m, 183 seq_printf(m,
184 "State:\t%s\n" 184 "State:\t%s\n"
185 "Tgid:\t%d\n" 185 "Tgid:\t%d\n"
186 "Ngid:\t%d\n"
186 "Pid:\t%d\n" 187 "Pid:\t%d\n"
187 "PPid:\t%d\n" 188 "PPid:\t%d\n"
188 "TracerPid:\t%d\n" 189 "TracerPid:\t%d\n"
@@ -190,6 +191,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
190 "Gid:\t%d\t%d\t%d\t%d\n", 191 "Gid:\t%d\t%d\t%d\t%d\n",
191 get_task_state(p), 192 get_task_state(p),
192 task_tgid_nr_ns(p, ns), 193 task_tgid_nr_ns(p, ns),
194 task_numa_group_id(p),
193 pid_nr_ns(pid, ns), 195 pid_nr_ns(pid, ns),
194 ppid, tpid, 196 ppid, tpid,
195 from_kuid_munged(user_ns, cred->uid), 197 from_kuid_munged(user_ns, cred->uid),
diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
index b701eaa482bf..51942d5abcec 100644
--- a/fs/proc/consoles.c
+++ b/fs/proc/consoles.c
@@ -29,7 +29,6 @@ static int show_console_dev(struct seq_file *m, void *v)
29 char flags[ARRAY_SIZE(con_flags) + 1]; 29 char flags[ARRAY_SIZE(con_flags) + 1];
30 struct console *con = v; 30 struct console *con = v;
31 unsigned int a; 31 unsigned int a;
32 int len;
33 dev_t dev = 0; 32 dev_t dev = 0;
34 33
35 if (con->device) { 34 if (con->device) {
@@ -47,11 +46,10 @@ static int show_console_dev(struct seq_file *m, void *v)
47 con_flags[a].name : ' '; 46 con_flags[a].name : ' ';
48 flags[a] = 0; 47 flags[a] = 0;
49 48
50 seq_printf(m, "%s%d%n", con->name, con->index, &len); 49 seq_setwidth(m, 21 - 1);
51 len = 21 - len; 50 seq_printf(m, "%s%d", con->name, con->index);
52 if (len < 1) 51 seq_pad(m, ' ');
53 len = 1; 52 seq_printf(m, "%c%c%c (%s)", con->read ? 'R' : '-',
54 seq_printf(m, "%*c%c%c%c (%s)", len, ' ', con->read ? 'R' : '-',
55 con->write ? 'W' : '-', con->unblank ? 'U' : '-', 53 con->write ? 'W' : '-', con->unblank ? 'U' : '-',
56 flags); 54 flags);
57 if (dev) 55 if (dev)
diff --git a/fs/proc/fd.c b/fs/proc/fd.c
index 0ff80f9b930f..985ea881b5bc 100644
--- a/fs/proc/fd.c
+++ b/fs/proc/fd.c
@@ -286,7 +286,7 @@ int proc_fd_permission(struct inode *inode, int mask)
286 int rv = generic_permission(inode, mask); 286 int rv = generic_permission(inode, mask);
287 if (rv == 0) 287 if (rv == 0)
288 return 0; 288 return 0;
289 if (task_pid(current) == proc_pid(inode)) 289 if (task_tgid(current) == proc_pid(inode))
290 rv = 0; 290 rv = 0;
291 return rv; 291 return rv;
292} 292}
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 737e15615b04..cca93b6fb9a9 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -175,22 +175,6 @@ static const struct inode_operations proc_link_inode_operations = {
175}; 175};
176 176
177/* 177/*
178 * As some entries in /proc are volatile, we want to
179 * get rid of unused dentries. This could be made
180 * smarter: we could keep a "volatile" flag in the
181 * inode to indicate which ones to keep.
182 */
183static int proc_delete_dentry(const struct dentry * dentry)
184{
185 return 1;
186}
187
188static const struct dentry_operations proc_dentry_operations =
189{
190 .d_delete = proc_delete_dentry,
191};
192
193/*
194 * Don't create negative dentries here, return -ENOENT by hand 178 * Don't create negative dentries here, return -ENOENT by hand
195 * instead. 179 * instead.
196 */ 180 */
@@ -209,7 +193,7 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
209 inode = proc_get_inode(dir->i_sb, de); 193 inode = proc_get_inode(dir->i_sb, de);
210 if (!inode) 194 if (!inode)
211 return ERR_PTR(-ENOMEM); 195 return ERR_PTR(-ENOMEM);
212 d_set_d_op(dentry, &proc_dentry_operations); 196 d_set_d_op(dentry, &simple_dentry_operations);
213 d_add(dentry, inode); 197 d_add(dentry, inode);
214 return NULL; 198 return NULL;
215 } 199 }
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 073aea60cf8f..28955d4b7218 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -285,6 +285,28 @@ static int proc_reg_mmap(struct file *file, struct vm_area_struct *vma)
285 return rv; 285 return rv;
286} 286}
287 287
288static unsigned long
289proc_reg_get_unmapped_area(struct file *file, unsigned long orig_addr,
290 unsigned long len, unsigned long pgoff,
291 unsigned long flags)
292{
293 struct proc_dir_entry *pde = PDE(file_inode(file));
294 unsigned long rv = -EIO;
295 unsigned long (*get_area)(struct file *, unsigned long, unsigned long,
296 unsigned long, unsigned long) = NULL;
297 if (use_pde(pde)) {
298#ifdef CONFIG_MMU
299 get_area = current->mm->get_unmapped_area;
300#endif
301 if (pde->proc_fops->get_unmapped_area)
302 get_area = pde->proc_fops->get_unmapped_area;
303 if (get_area)
304 rv = get_area(file, orig_addr, len, pgoff, flags);
305 unuse_pde(pde);
306 }
307 return rv;
308}
309
288static int proc_reg_open(struct inode *inode, struct file *file) 310static int proc_reg_open(struct inode *inode, struct file *file)
289{ 311{
290 struct proc_dir_entry *pde = PDE(inode); 312 struct proc_dir_entry *pde = PDE(inode);
@@ -356,6 +378,7 @@ static const struct file_operations proc_reg_file_ops = {
356 .compat_ioctl = proc_reg_compat_ioctl, 378 .compat_ioctl = proc_reg_compat_ioctl,
357#endif 379#endif
358 .mmap = proc_reg_mmap, 380 .mmap = proc_reg_mmap,
381 .get_unmapped_area = proc_reg_get_unmapped_area,
359 .open = proc_reg_open, 382 .open = proc_reg_open,
360 .release = proc_reg_release, 383 .release = proc_reg_release,
361}; 384};
@@ -368,6 +391,7 @@ static const struct file_operations proc_reg_file_ops_no_compat = {
368 .poll = proc_reg_poll, 391 .poll = proc_reg_poll,
369 .unlocked_ioctl = proc_reg_unlocked_ioctl, 392 .unlocked_ioctl = proc_reg_unlocked_ioctl,
370 .mmap = proc_reg_mmap, 393 .mmap = proc_reg_mmap,
394 .get_unmapped_area = proc_reg_get_unmapped_area,
371 .open = proc_reg_open, 395 .open = proc_reg_open,
372 .release = proc_reg_release, 396 .release = proc_reg_release,
373}; 397};
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 06ea155e1a59..5ed0e52d6aa0 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -255,8 +255,7 @@ static int kcore_update_ram(void)
255 end_pfn = 0; 255 end_pfn = 0;
256 for_each_node_state(nid, N_MEMORY) { 256 for_each_node_state(nid, N_MEMORY) {
257 unsigned long node_end; 257 unsigned long node_end;
258 node_end = NODE_DATA(nid)->node_start_pfn + 258 node_end = node_end_pfn(nid);
259 NODE_DATA(nid)->node_spanned_pages;
260 if (end_pfn < node_end) 259 if (end_pfn < node_end)
261 end_pfn = node_end; 260 end_pfn = node_end;
262 } 261 }
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
index 5aa847a603c0..a77d2b299199 100644
--- a/fs/proc/meminfo.c
+++ b/fs/proc/meminfo.c
@@ -1,8 +1,8 @@
1#include <linux/fs.h> 1#include <linux/fs.h>
2#include <linux/hugetlb.h>
3#include <linux/init.h> 2#include <linux/init.h>
4#include <linux/kernel.h> 3#include <linux/kernel.h>
5#include <linux/mm.h> 4#include <linux/mm.h>
5#include <linux/hugetlb.h>
6#include <linux/mman.h> 6#include <linux/mman.h>
7#include <linux/mmzone.h> 7#include <linux/mmzone.h>
8#include <linux/proc_fs.h> 8#include <linux/proc_fs.h>
@@ -24,7 +24,6 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
24{ 24{
25 struct sysinfo i; 25 struct sysinfo i;
26 unsigned long committed; 26 unsigned long committed;
27 unsigned long allowed;
28 struct vmalloc_info vmi; 27 struct vmalloc_info vmi;
29 long cached; 28 long cached;
30 unsigned long pages[NR_LRU_LISTS]; 29 unsigned long pages[NR_LRU_LISTS];
@@ -37,8 +36,6 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
37 si_meminfo(&i); 36 si_meminfo(&i);
38 si_swapinfo(&i); 37 si_swapinfo(&i);
39 committed = percpu_counter_read_positive(&vm_committed_as); 38 committed = percpu_counter_read_positive(&vm_committed_as);
40 allowed = ((totalram_pages - hugetlb_total_pages())
41 * sysctl_overcommit_ratio / 100) + total_swap_pages;
42 39
43 cached = global_page_state(NR_FILE_PAGES) - 40 cached = global_page_state(NR_FILE_PAGES) -
44 total_swapcache_pages() - i.bufferram; 41 total_swapcache_pages() - i.bufferram;
@@ -132,13 +129,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
132 K(i.freeswap), 129 K(i.freeswap),
133 K(global_page_state(NR_FILE_DIRTY)), 130 K(global_page_state(NR_FILE_DIRTY)),
134 K(global_page_state(NR_WRITEBACK)), 131 K(global_page_state(NR_WRITEBACK)),
135#ifdef CONFIG_TRANSPARENT_HUGEPAGE
136 K(global_page_state(NR_ANON_PAGES)
137 + global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) *
138 HPAGE_PMD_NR),
139#else
140 K(global_page_state(NR_ANON_PAGES)), 132 K(global_page_state(NR_ANON_PAGES)),
141#endif
142 K(global_page_state(NR_FILE_MAPPED)), 133 K(global_page_state(NR_FILE_MAPPED)),
143 K(global_page_state(NR_SHMEM)), 134 K(global_page_state(NR_SHMEM)),
144 K(global_page_state(NR_SLAB_RECLAIMABLE) + 135 K(global_page_state(NR_SLAB_RECLAIMABLE) +
@@ -153,7 +144,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
153 K(global_page_state(NR_UNSTABLE_NFS)), 144 K(global_page_state(NR_UNSTABLE_NFS)),
154 K(global_page_state(NR_BOUNCE)), 145 K(global_page_state(NR_BOUNCE)),
155 K(global_page_state(NR_WRITEBACK_TEMP)), 146 K(global_page_state(NR_WRITEBACK_TEMP)),
156 K(allowed), 147 K(vm_commit_limit()),
157 K(committed), 148 K(committed),
158 (unsigned long)VMALLOC_TOTAL >> 10, 149 (unsigned long)VMALLOC_TOTAL >> 10,
159 vmi.used >> 10, 150 vmi.used >> 10,
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
index 49a7fff2e83a..9ae46b87470d 100644
--- a/fs/proc/namespaces.c
+++ b/fs/proc/namespaces.c
@@ -42,12 +42,6 @@ static const struct inode_operations ns_inode_operations = {
42 .setattr = proc_setattr, 42 .setattr = proc_setattr,
43}; 43};
44 44
45static int ns_delete_dentry(const struct dentry *dentry)
46{
47 /* Don't cache namespace inodes when not in use */
48 return 1;
49}
50
51static char *ns_dname(struct dentry *dentry, char *buffer, int buflen) 45static char *ns_dname(struct dentry *dentry, char *buffer, int buflen)
52{ 46{
53 struct inode *inode = dentry->d_inode; 47 struct inode *inode = dentry->d_inode;
@@ -59,7 +53,7 @@ static char *ns_dname(struct dentry *dentry, char *buffer, int buflen)
59 53
60const struct dentry_operations ns_dentry_operations = 54const struct dentry_operations ns_dentry_operations =
61{ 55{
62 .d_delete = ns_delete_dentry, 56 .d_delete = always_delete_dentry,
63 .d_dname = ns_dname, 57 .d_dname = ns_dname,
64}; 58};
65 59
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
index ccfd99bd1c5a..5f9bc8a746c9 100644
--- a/fs/proc/nommu.c
+++ b/fs/proc/nommu.c
@@ -39,7 +39,7 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
39 unsigned long ino = 0; 39 unsigned long ino = 0;
40 struct file *file; 40 struct file *file;
41 dev_t dev = 0; 41 dev_t dev = 0;
42 int flags, len; 42 int flags;
43 43
44 flags = region->vm_flags; 44 flags = region->vm_flags;
45 file = region->vm_file; 45 file = region->vm_file;
@@ -50,8 +50,9 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
50 ino = inode->i_ino; 50 ino = inode->i_ino;
51 } 51 }
52 52
53 seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);
53 seq_printf(m, 54 seq_printf(m,
54 "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n", 55 "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
55 region->vm_start, 56 region->vm_start,
56 region->vm_end, 57 region->vm_end,
57 flags & VM_READ ? 'r' : '-', 58 flags & VM_READ ? 'r' : '-',
@@ -59,13 +60,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
59 flags & VM_EXEC ? 'x' : '-', 60 flags & VM_EXEC ? 'x' : '-',
60 flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p', 61 flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p',
61 ((loff_t)region->vm_pgoff) << PAGE_SHIFT, 62 ((loff_t)region->vm_pgoff) << PAGE_SHIFT,
62 MAJOR(dev), MINOR(dev), ino, &len); 63 MAJOR(dev), MINOR(dev), ino);
63 64
64 if (file) { 65 if (file) {
65 len = 25 + sizeof(void *) * 6 - len; 66 seq_pad(m, ' ');
66 if (len < 1)
67 len = 1;
68 seq_printf(m, "%*c", len, ' ');
69 seq_path(m, &file->f_path, ""); 67 seq_path(m, &file->f_path, "");
70 } 68 }
71 69
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
index 106a83570630..70779b2fc209 100644
--- a/fs/proc/proc_devtree.c
+++ b/fs/proc/proc_devtree.c
@@ -14,16 +14,13 @@
14#include <linux/of.h> 14#include <linux/of.h>
15#include <linux/export.h> 15#include <linux/export.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <asm/prom.h>
18#include <asm/uaccess.h> 17#include <asm/uaccess.h>
19#include "internal.h" 18#include "internal.h"
20 19
21static inline void set_node_proc_entry(struct device_node *np, 20static inline void set_node_proc_entry(struct device_node *np,
22 struct proc_dir_entry *de) 21 struct proc_dir_entry *de)
23{ 22{
24#ifdef HAVE_ARCH_DEVTREE_FIXUPS
25 np->pde = de; 23 np->pde = de;
26#endif
27} 24}
28 25
29static struct proc_dir_entry *proc_device_tree; 26static struct proc_dir_entry *proc_device_tree;
diff --git a/fs/proc/root.c b/fs/proc/root.c
index e0a790da726d..87dbcbef7fe4 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -110,7 +110,11 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
110 ns = task_active_pid_ns(current); 110 ns = task_active_pid_ns(current);
111 options = data; 111 options = data;
112 112
113 if (!current_user_ns()->may_mount_proc) 113 if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
114 return ERR_PTR(-EPERM);
115
116 /* Does the mounter have privilege over the pid namespace? */
117 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
114 return ERR_PTR(-EPERM); 118 return ERR_PTR(-EPERM);
115 } 119 }
116 120
diff --git a/fs/proc/self.c b/fs/proc/self.c
index 6b6a993b5c25..ffeb202ec942 100644
--- a/fs/proc/self.c
+++ b/fs/proc/self.c
@@ -36,18 +36,10 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
36 return NULL; 36 return NULL;
37} 37}
38 38
39static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd,
40 void *cookie)
41{
42 char *s = nd_get_link(nd);
43 if (!IS_ERR(s))
44 kfree(s);
45}
46
47static const struct inode_operations proc_self_inode_operations = { 39static const struct inode_operations proc_self_inode_operations = {
48 .readlink = proc_self_readlink, 40 .readlink = proc_self_readlink,
49 .follow_link = proc_self_follow_link, 41 .follow_link = proc_self_follow_link,
50 .put_link = proc_self_put_link, 42 .put_link = kfree_put_link,
51}; 43};
52 44
53static unsigned self_inum; 45static unsigned self_inum;
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 107d026f5d6e..fb52b548080d 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -62,7 +62,8 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
62 total_rss << (PAGE_SHIFT-10), 62 total_rss << (PAGE_SHIFT-10),
63 data << (PAGE_SHIFT-10), 63 data << (PAGE_SHIFT-10),
64 mm->stack_vm << (PAGE_SHIFT-10), text, lib, 64 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
65 (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10, 65 (PTRS_PER_PTE * sizeof(pte_t) *
66 atomic_long_read(&mm->nr_ptes)) >> 10,
66 swap << (PAGE_SHIFT-10)); 67 swap << (PAGE_SHIFT-10));
67} 68}
68 69
@@ -83,14 +84,6 @@ unsigned long task_statm(struct mm_struct *mm,
83 return mm->total_vm; 84 return mm->total_vm;
84} 85}
85 86
86static void pad_len_spaces(struct seq_file *m, int len)
87{
88 len = 25 + sizeof(void*) * 6 - len;
89 if (len < 1)
90 len = 1;
91 seq_printf(m, "%*c", len, ' ');
92}
93
94#ifdef CONFIG_NUMA 87#ifdef CONFIG_NUMA
95/* 88/*
96 * These functions are for numa_maps but called in generic **maps seq_file 89 * These functions are for numa_maps but called in generic **maps seq_file
@@ -268,7 +261,6 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
268 unsigned long long pgoff = 0; 261 unsigned long long pgoff = 0;
269 unsigned long start, end; 262 unsigned long start, end;
270 dev_t dev = 0; 263 dev_t dev = 0;
271 int len;
272 const char *name = NULL; 264 const char *name = NULL;
273 265
274 if (file) { 266 if (file) {
@@ -286,7 +278,8 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
286 if (stack_guard_page_end(vma, end)) 278 if (stack_guard_page_end(vma, end))
287 end -= PAGE_SIZE; 279 end -= PAGE_SIZE;
288 280
289 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n", 281 seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);
282 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
290 start, 283 start,
291 end, 284 end,
292 flags & VM_READ ? 'r' : '-', 285 flags & VM_READ ? 'r' : '-',
@@ -294,14 +287,14 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
294 flags & VM_EXEC ? 'x' : '-', 287 flags & VM_EXEC ? 'x' : '-',
295 flags & VM_MAYSHARE ? 's' : 'p', 288 flags & VM_MAYSHARE ? 's' : 'p',
296 pgoff, 289 pgoff,
297 MAJOR(dev), MINOR(dev), ino, &len); 290 MAJOR(dev), MINOR(dev), ino);
298 291
299 /* 292 /*
300 * Print the dentry name for named mappings, and a 293 * Print the dentry name for named mappings, and a
301 * special [heap] marker for the heap: 294 * special [heap] marker for the heap:
302 */ 295 */
303 if (file) { 296 if (file) {
304 pad_len_spaces(m, len); 297 seq_pad(m, ' ');
305 seq_path(m, &file->f_path, "\n"); 298 seq_path(m, &file->f_path, "\n");
306 goto done; 299 goto done;
307 } 300 }
@@ -333,7 +326,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
333 name = "[stack]"; 326 name = "[stack]";
334 } else { 327 } else {
335 /* Thread stack in /proc/PID/maps */ 328 /* Thread stack in /proc/PID/maps */
336 pad_len_spaces(m, len); 329 seq_pad(m, ' ');
337 seq_printf(m, "[stack:%d]", tid); 330 seq_printf(m, "[stack:%d]", tid);
338 } 331 }
339 } 332 }
@@ -341,7 +334,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
341 334
342done: 335done:
343 if (name) { 336 if (name) {
344 pad_len_spaces(m, len); 337 seq_pad(m, ' ');
345 seq_puts(m, name); 338 seq_puts(m, name);
346 } 339 }
347 seq_putc(m, '\n'); 340 seq_putc(m, '\n');
@@ -505,9 +498,9 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
505 pte_t *pte; 498 pte_t *pte;
506 spinlock_t *ptl; 499 spinlock_t *ptl;
507 500
508 if (pmd_trans_huge_lock(pmd, vma) == 1) { 501 if (pmd_trans_huge_lock(pmd, vma, &ptl) == 1) {
509 smaps_pte_entry(*(pte_t *)pmd, addr, HPAGE_PMD_SIZE, walk); 502 smaps_pte_entry(*(pte_t *)pmd, addr, HPAGE_PMD_SIZE, walk);
510 spin_unlock(&walk->mm->page_table_lock); 503 spin_unlock(ptl);
511 mss->anonymous_thp += HPAGE_PMD_SIZE; 504 mss->anonymous_thp += HPAGE_PMD_SIZE;
512 return 0; 505 return 0;
513 } 506 }
@@ -561,6 +554,9 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
561 [ilog2(VM_NONLINEAR)] = "nl", 554 [ilog2(VM_NONLINEAR)] = "nl",
562 [ilog2(VM_ARCH_1)] = "ar", 555 [ilog2(VM_ARCH_1)] = "ar",
563 [ilog2(VM_DONTDUMP)] = "dd", 556 [ilog2(VM_DONTDUMP)] = "dd",
557#ifdef CONFIG_MEM_SOFT_DIRTY
558 [ilog2(VM_SOFTDIRTY)] = "sd",
559#endif
564 [ilog2(VM_MIXEDMAP)] = "mm", 560 [ilog2(VM_MIXEDMAP)] = "mm",
565 [ilog2(VM_HUGEPAGE)] = "hg", 561 [ilog2(VM_HUGEPAGE)] = "hg",
566 [ilog2(VM_NOHUGEPAGE)] = "nh", 562 [ilog2(VM_NOHUGEPAGE)] = "nh",
@@ -740,6 +736,9 @@ static inline void clear_soft_dirty(struct vm_area_struct *vma,
740 ptent = pte_file_clear_soft_dirty(ptent); 736 ptent = pte_file_clear_soft_dirty(ptent);
741 } 737 }
742 738
739 if (vma->vm_flags & VM_SOFTDIRTY)
740 vma->vm_flags &= ~VM_SOFTDIRTY;
741
743 set_pte_at(vma->vm_mm, addr, pte, ptent); 742 set_pte_at(vma->vm_mm, addr, pte, ptent);
744#endif 743#endif
745} 744}
@@ -938,6 +937,8 @@ static void pte_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *pm,
938 frame = pte_pfn(pte); 937 frame = pte_pfn(pte);
939 flags = PM_PRESENT; 938 flags = PM_PRESENT;
940 page = vm_normal_page(vma, addr, pte); 939 page = vm_normal_page(vma, addr, pte);
940 if (pte_soft_dirty(pte))
941 flags2 |= __PM_SOFT_DIRTY;
941 } else if (is_swap_pte(pte)) { 942 } else if (is_swap_pte(pte)) {
942 swp_entry_t entry; 943 swp_entry_t entry;
943 if (pte_swp_soft_dirty(pte)) 944 if (pte_swp_soft_dirty(pte))
@@ -949,13 +950,15 @@ static void pte_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *pm,
949 if (is_migration_entry(entry)) 950 if (is_migration_entry(entry))
950 page = migration_entry_to_page(entry); 951 page = migration_entry_to_page(entry);
951 } else { 952 } else {
952 *pme = make_pme(PM_NOT_PRESENT(pm->v2)); 953 if (vma->vm_flags & VM_SOFTDIRTY)
954 flags2 |= __PM_SOFT_DIRTY;
955 *pme = make_pme(PM_NOT_PRESENT(pm->v2) | PM_STATUS2(pm->v2, flags2));
953 return; 956 return;
954 } 957 }
955 958
956 if (page && !PageAnon(page)) 959 if (page && !PageAnon(page))
957 flags |= PM_FILE; 960 flags |= PM_FILE;
958 if (pte_soft_dirty(pte)) 961 if ((vma->vm_flags & VM_SOFTDIRTY))
959 flags2 |= __PM_SOFT_DIRTY; 962 flags2 |= __PM_SOFT_DIRTY;
960 963
961 *pme = make_pme(PM_PFRAME(frame) | PM_STATUS2(pm->v2, flags2) | flags); 964 *pme = make_pme(PM_PFRAME(frame) | PM_STATUS2(pm->v2, flags2) | flags);
@@ -974,7 +977,7 @@ static void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *p
974 *pme = make_pme(PM_PFRAME(pmd_pfn(pmd) + offset) 977 *pme = make_pme(PM_PFRAME(pmd_pfn(pmd) + offset)
975 | PM_STATUS2(pm->v2, pmd_flags2) | PM_PRESENT); 978 | PM_STATUS2(pm->v2, pmd_flags2) | PM_PRESENT);
976 else 979 else
977 *pme = make_pme(PM_NOT_PRESENT(pm->v2)); 980 *pme = make_pme(PM_NOT_PRESENT(pm->v2) | PM_STATUS2(pm->v2, pmd_flags2));
978} 981}
979#else 982#else
980static inline void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *pm, 983static inline void thp_pmd_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *pm,
@@ -988,16 +991,21 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
988{ 991{
989 struct vm_area_struct *vma; 992 struct vm_area_struct *vma;
990 struct pagemapread *pm = walk->private; 993 struct pagemapread *pm = walk->private;
994 spinlock_t *ptl;
991 pte_t *pte; 995 pte_t *pte;
992 int err = 0; 996 int err = 0;
993 pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2)); 997 pagemap_entry_t pme = make_pme(PM_NOT_PRESENT(pm->v2));
994 998
995 /* find the first VMA at or above 'addr' */ 999 /* find the first VMA at or above 'addr' */
996 vma = find_vma(walk->mm, addr); 1000 vma = find_vma(walk->mm, addr);
997 if (vma && pmd_trans_huge_lock(pmd, vma) == 1) { 1001 if (vma && pmd_trans_huge_lock(pmd, vma, &ptl) == 1) {
998 int pmd_flags2; 1002 int pmd_flags2;
999 1003
1000 pmd_flags2 = (pmd_soft_dirty(*pmd) ? __PM_SOFT_DIRTY : 0); 1004 if ((vma->vm_flags & VM_SOFTDIRTY) || pmd_soft_dirty(*pmd))
1005 pmd_flags2 = __PM_SOFT_DIRTY;
1006 else
1007 pmd_flags2 = 0;
1008
1001 for (; addr != end; addr += PAGE_SIZE) { 1009 for (; addr != end; addr += PAGE_SIZE) {
1002 unsigned long offset; 1010 unsigned long offset;
1003 1011
@@ -1008,19 +1016,24 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
1008 if (err) 1016 if (err)
1009 break; 1017 break;
1010 } 1018 }
1011 spin_unlock(&walk->mm->page_table_lock); 1019 spin_unlock(ptl);
1012 return err; 1020 return err;
1013 } 1021 }
1014 1022
1015 if (pmd_trans_unstable(pmd)) 1023 if (pmd_trans_unstable(pmd))
1016 return 0; 1024 return 0;
1017 for (; addr != end; addr += PAGE_SIZE) { 1025 for (; addr != end; addr += PAGE_SIZE) {
1026 int flags2;
1018 1027
1019 /* check to see if we've left 'vma' behind 1028 /* check to see if we've left 'vma' behind
1020 * and need a new, higher one */ 1029 * and need a new, higher one */
1021 if (vma && (addr >= vma->vm_end)) { 1030 if (vma && (addr >= vma->vm_end)) {
1022 vma = find_vma(walk->mm, addr); 1031 vma = find_vma(walk->mm, addr);
1023 pme = make_pme(PM_NOT_PRESENT(pm->v2)); 1032 if (vma && (vma->vm_flags & VM_SOFTDIRTY))
1033 flags2 = __PM_SOFT_DIRTY;
1034 else
1035 flags2 = 0;
1036 pme = make_pme(PM_NOT_PRESENT(pm->v2) | PM_STATUS2(pm->v2, flags2));
1024 } 1037 }
1025 1038
1026 /* check that 'vma' actually covers this address, 1039 /* check that 'vma' actually covers this address,
@@ -1044,13 +1057,15 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
1044 1057
1045#ifdef CONFIG_HUGETLB_PAGE 1058#ifdef CONFIG_HUGETLB_PAGE
1046static void huge_pte_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *pm, 1059static void huge_pte_to_pagemap_entry(pagemap_entry_t *pme, struct pagemapread *pm,
1047 pte_t pte, int offset) 1060 pte_t pte, int offset, int flags2)
1048{ 1061{
1049 if (pte_present(pte)) 1062 if (pte_present(pte))
1050 *pme = make_pme(PM_PFRAME(pte_pfn(pte) + offset) 1063 *pme = make_pme(PM_PFRAME(pte_pfn(pte) + offset) |
1051 | PM_STATUS2(pm->v2, 0) | PM_PRESENT); 1064 PM_STATUS2(pm->v2, flags2) |
1065 PM_PRESENT);
1052 else 1066 else
1053 *pme = make_pme(PM_NOT_PRESENT(pm->v2)); 1067 *pme = make_pme(PM_NOT_PRESENT(pm->v2) |
1068 PM_STATUS2(pm->v2, flags2));
1054} 1069}
1055 1070
1056/* This function walks within one hugetlb entry in the single call */ 1071/* This function walks within one hugetlb entry in the single call */
@@ -1059,12 +1074,22 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
1059 struct mm_walk *walk) 1074 struct mm_walk *walk)
1060{ 1075{
1061 struct pagemapread *pm = walk->private; 1076 struct pagemapread *pm = walk->private;
1077 struct vm_area_struct *vma;
1062 int err = 0; 1078 int err = 0;
1079 int flags2;
1063 pagemap_entry_t pme; 1080 pagemap_entry_t pme;
1064 1081
1082 vma = find_vma(walk->mm, addr);
1083 WARN_ON_ONCE(!vma);
1084
1085 if (vma && (vma->vm_flags & VM_SOFTDIRTY))
1086 flags2 = __PM_SOFT_DIRTY;
1087 else
1088 flags2 = 0;
1089
1065 for (; addr != end; addr += PAGE_SIZE) { 1090 for (; addr != end; addr += PAGE_SIZE) {
1066 int offset = (addr & ~hmask) >> PAGE_SHIFT; 1091 int offset = (addr & ~hmask) >> PAGE_SHIFT;
1067 huge_pte_to_pagemap_entry(&pme, pm, *pte, offset); 1092 huge_pte_to_pagemap_entry(&pme, pm, *pte, offset, flags2);
1068 err = add_to_pagemap(addr, &pme, pm); 1093 err = add_to_pagemap(addr, &pme, pm);
1069 if (err) 1094 if (err)
1070 return err; 1095 return err;
@@ -1293,7 +1318,7 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
1293 1318
1294 md = walk->private; 1319 md = walk->private;
1295 1320
1296 if (pmd_trans_huge_lock(pmd, md->vma) == 1) { 1321 if (pmd_trans_huge_lock(pmd, md->vma, &ptl) == 1) {
1297 pte_t huge_pte = *(pte_t *)pmd; 1322 pte_t huge_pte = *(pte_t *)pmd;
1298 struct page *page; 1323 struct page *page;
1299 1324
@@ -1301,7 +1326,7 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
1301 if (page) 1326 if (page)
1302 gather_stats(page, md, pte_dirty(huge_pte), 1327 gather_stats(page, md, pte_dirty(huge_pte),
1303 HPAGE_PMD_SIZE/PAGE_SIZE); 1328 HPAGE_PMD_SIZE/PAGE_SIZE);
1304 spin_unlock(&walk->mm->page_table_lock); 1329 spin_unlock(ptl);
1305 return 0; 1330 return 0;
1306 } 1331 }
1307 1332
@@ -1359,8 +1384,8 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
1359 struct mm_struct *mm = vma->vm_mm; 1384 struct mm_struct *mm = vma->vm_mm;
1360 struct mm_walk walk = {}; 1385 struct mm_walk walk = {};
1361 struct mempolicy *pol; 1386 struct mempolicy *pol;
1362 int n; 1387 char buffer[64];
1363 char buffer[50]; 1388 int nid;
1364 1389
1365 if (!mm) 1390 if (!mm)
1366 return 0; 1391 return 0;
@@ -1430,9 +1455,9 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
1430 if (md->writeback) 1455 if (md->writeback)
1431 seq_printf(m, " writeback=%lu", md->writeback); 1456 seq_printf(m, " writeback=%lu", md->writeback);
1432 1457
1433 for_each_node_state(n, N_MEMORY) 1458 for_each_node_state(nid, N_MEMORY)
1434 if (md->node[n]) 1459 if (md->node[nid])
1435 seq_printf(m, " N%d=%lu", n, md->node[n]); 1460 seq_printf(m, " N%d=%lu", nid, md->node[nid]);
1436out: 1461out:
1437 seq_putc(m, '\n'); 1462 seq_putc(m, '\n');
1438 1463
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
index 56123a6f462e..678455d2d683 100644
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -123,14 +123,6 @@ unsigned long task_statm(struct mm_struct *mm,
123 return size; 123 return size;
124} 124}
125 125
126static void pad_len_spaces(struct seq_file *m, int len)
127{
128 len = 25 + sizeof(void*) * 6 - len;
129 if (len < 1)
130 len = 1;
131 seq_printf(m, "%*c", len, ' ');
132}
133
134/* 126/*
135 * display a single VMA to a sequenced file 127 * display a single VMA to a sequenced file
136 */ 128 */
@@ -142,7 +134,7 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
142 unsigned long ino = 0; 134 unsigned long ino = 0;
143 struct file *file; 135 struct file *file;
144 dev_t dev = 0; 136 dev_t dev = 0;
145 int flags, len; 137 int flags;
146 unsigned long long pgoff = 0; 138 unsigned long long pgoff = 0;
147 139
148 flags = vma->vm_flags; 140 flags = vma->vm_flags;
@@ -155,8 +147,9 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
155 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; 147 pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
156 } 148 }
157 149
150 seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);
158 seq_printf(m, 151 seq_printf(m,
159 "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n", 152 "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
160 vma->vm_start, 153 vma->vm_start,
161 vma->vm_end, 154 vma->vm_end,
162 flags & VM_READ ? 'r' : '-', 155 flags & VM_READ ? 'r' : '-',
@@ -164,16 +157,16 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
164 flags & VM_EXEC ? 'x' : '-', 157 flags & VM_EXEC ? 'x' : '-',
165 flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p', 158 flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p',
166 pgoff, 159 pgoff,
167 MAJOR(dev), MINOR(dev), ino, &len); 160 MAJOR(dev), MINOR(dev), ino);
168 161
169 if (file) { 162 if (file) {
170 pad_len_spaces(m, len); 163 seq_pad(m, ' ');
171 seq_path(m, &file->f_path, ""); 164 seq_path(m, &file->f_path, "");
172 } else if (mm) { 165 } else if (mm) {
173 pid_t tid = vm_is_stack(priv->task, vma, is_pid); 166 pid_t tid = vm_is_stack(priv->task, vma, is_pid);
174 167
175 if (tid != 0) { 168 if (tid != 0) {
176 pad_len_spaces(m, len); 169 seq_pad(m, ' ');
177 /* 170 /*
178 * Thread stack in /proc/PID/task/TID/maps or 171 * Thread stack in /proc/PID/task/TID/maps or
179 * the main process stack. 172 * the main process stack.
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index a1a16eb97c7b..9100d6959886 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -21,6 +21,7 @@
21#include <linux/crash_dump.h> 21#include <linux/crash_dump.h>
22#include <linux/list.h> 22#include <linux/list.h>
23#include <linux/vmalloc.h> 23#include <linux/vmalloc.h>
24#include <linux/pagemap.h>
24#include <asm/uaccess.h> 25#include <asm/uaccess.h>
25#include <asm/io.h> 26#include <asm/io.h>
26#include "internal.h" 27#include "internal.h"
@@ -123,11 +124,65 @@ static ssize_t read_from_oldmem(char *buf, size_t count,
123 return read; 124 return read;
124} 125}
125 126
127/*
128 * Architectures may override this function to allocate ELF header in 2nd kernel
129 */
130int __weak elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
131{
132 return 0;
133}
134
135/*
136 * Architectures may override this function to free header
137 */
138void __weak elfcorehdr_free(unsigned long long addr)
139{}
140
141/*
142 * Architectures may override this function to read from ELF header
143 */
144ssize_t __weak elfcorehdr_read(char *buf, size_t count, u64 *ppos)
145{
146 return read_from_oldmem(buf, count, ppos, 0);
147}
148
149/*
150 * Architectures may override this function to read from notes sections
151 */
152ssize_t __weak elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos)
153{
154 return read_from_oldmem(buf, count, ppos, 0);
155}
156
157/*
158 * Architectures may override this function to map oldmem
159 */
160int __weak remap_oldmem_pfn_range(struct vm_area_struct *vma,
161 unsigned long from, unsigned long pfn,
162 unsigned long size, pgprot_t prot)
163{
164 return remap_pfn_range(vma, from, pfn, size, prot);
165}
166
167/*
168 * Copy to either kernel or user space
169 */
170static int copy_to(void *target, void *src, size_t size, int userbuf)
171{
172 if (userbuf) {
173 if (copy_to_user((char __user *) target, src, size))
174 return -EFAULT;
175 } else {
176 memcpy(target, src, size);
177 }
178 return 0;
179}
180
126/* Read from the ELF header and then the crash dump. On error, negative value is 181/* Read from the ELF header and then the crash dump. On error, negative value is
127 * returned otherwise number of bytes read are returned. 182 * returned otherwise number of bytes read are returned.
128 */ 183 */
129static ssize_t read_vmcore(struct file *file, char __user *buffer, 184static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos,
130 size_t buflen, loff_t *fpos) 185 int userbuf)
131{ 186{
132 ssize_t acc = 0, tmp; 187 ssize_t acc = 0, tmp;
133 size_t tsz; 188 size_t tsz;
@@ -144,7 +199,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer,
144 /* Read ELF core header */ 199 /* Read ELF core header */
145 if (*fpos < elfcorebuf_sz) { 200 if (*fpos < elfcorebuf_sz) {
146 tsz = min(elfcorebuf_sz - (size_t)*fpos, buflen); 201 tsz = min(elfcorebuf_sz - (size_t)*fpos, buflen);
147 if (copy_to_user(buffer, elfcorebuf + *fpos, tsz)) 202 if (copy_to(buffer, elfcorebuf + *fpos, tsz, userbuf))
148 return -EFAULT; 203 return -EFAULT;
149 buflen -= tsz; 204 buflen -= tsz;
150 *fpos += tsz; 205 *fpos += tsz;
@@ -162,7 +217,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer,
162 217
163 tsz = min(elfcorebuf_sz + elfnotes_sz - (size_t)*fpos, buflen); 218 tsz = min(elfcorebuf_sz + elfnotes_sz - (size_t)*fpos, buflen);
164 kaddr = elfnotes_buf + *fpos - elfcorebuf_sz; 219 kaddr = elfnotes_buf + *fpos - elfcorebuf_sz;
165 if (copy_to_user(buffer, kaddr, tsz)) 220 if (copy_to(buffer, kaddr, tsz, userbuf))
166 return -EFAULT; 221 return -EFAULT;
167 buflen -= tsz; 222 buflen -= tsz;
168 *fpos += tsz; 223 *fpos += tsz;
@@ -178,7 +233,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer,
178 if (*fpos < m->offset + m->size) { 233 if (*fpos < m->offset + m->size) {
179 tsz = min_t(size_t, m->offset + m->size - *fpos, buflen); 234 tsz = min_t(size_t, m->offset + m->size - *fpos, buflen);
180 start = m->paddr + *fpos - m->offset; 235 start = m->paddr + *fpos - m->offset;
181 tmp = read_from_oldmem(buffer, tsz, &start, 1); 236 tmp = read_from_oldmem(buffer, tsz, &start, userbuf);
182 if (tmp < 0) 237 if (tmp < 0)
183 return tmp; 238 return tmp;
184 buflen -= tsz; 239 buflen -= tsz;
@@ -195,6 +250,55 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer,
195 return acc; 250 return acc;
196} 251}
197 252
253static ssize_t read_vmcore(struct file *file, char __user *buffer,
254 size_t buflen, loff_t *fpos)
255{
256 return __read_vmcore((__force char *) buffer, buflen, fpos, 1);
257}
258
259/*
260 * The vmcore fault handler uses the page cache and fills data using the
261 * standard __vmcore_read() function.
262 *
263 * On s390 the fault handler is used for memory regions that can't be mapped
264 * directly with remap_pfn_range().
265 */
266static int mmap_vmcore_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
267{
268#ifdef CONFIG_S390
269 struct address_space *mapping = vma->vm_file->f_mapping;
270 pgoff_t index = vmf->pgoff;
271 struct page *page;
272 loff_t offset;
273 char *buf;
274 int rc;
275
276 page = find_or_create_page(mapping, index, GFP_KERNEL);
277 if (!page)
278 return VM_FAULT_OOM;
279 if (!PageUptodate(page)) {
280 offset = (loff_t) index << PAGE_CACHE_SHIFT;
281 buf = __va((page_to_pfn(page) << PAGE_SHIFT));
282 rc = __read_vmcore(buf, PAGE_SIZE, &offset, 0);
283 if (rc < 0) {
284 unlock_page(page);
285 page_cache_release(page);
286 return (rc == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
287 }
288 SetPageUptodate(page);
289 }
290 unlock_page(page);
291 vmf->page = page;
292 return 0;
293#else
294 return VM_FAULT_SIGBUS;
295#endif
296}
297
298static const struct vm_operations_struct vmcore_mmap_ops = {
299 .fault = mmap_vmcore_fault,
300};
301
198/** 302/**
199 * alloc_elfnotes_buf - allocate buffer for ELF note segment in 303 * alloc_elfnotes_buf - allocate buffer for ELF note segment in
200 * vmalloc memory 304 * vmalloc memory
@@ -223,7 +327,7 @@ static inline char *alloc_elfnotes_buf(size_t notes_sz)
223 * regions in the 1st kernel pointed to by PT_LOAD entries) into 327 * regions in the 1st kernel pointed to by PT_LOAD entries) into
224 * virtually contiguous user-space in ELF layout. 328 * virtually contiguous user-space in ELF layout.
225 */ 329 */
226#if defined(CONFIG_MMU) && !defined(CONFIG_S390) 330#ifdef CONFIG_MMU
227static int mmap_vmcore(struct file *file, struct vm_area_struct *vma) 331static int mmap_vmcore(struct file *file, struct vm_area_struct *vma)
228{ 332{
229 size_t size = vma->vm_end - vma->vm_start; 333 size_t size = vma->vm_end - vma->vm_start;
@@ -241,6 +345,7 @@ static int mmap_vmcore(struct file *file, struct vm_area_struct *vma)
241 345
242 vma->vm_flags &= ~(VM_MAYWRITE | VM_MAYEXEC); 346 vma->vm_flags &= ~(VM_MAYWRITE | VM_MAYEXEC);
243 vma->vm_flags |= VM_MIXEDMAP; 347 vma->vm_flags |= VM_MIXEDMAP;
348 vma->vm_ops = &vmcore_mmap_ops;
244 349
245 len = 0; 350 len = 0;
246 351
@@ -282,9 +387,9 @@ static int mmap_vmcore(struct file *file, struct vm_area_struct *vma)
282 387
283 tsz = min_t(size_t, m->offset + m->size - start, size); 388 tsz = min_t(size_t, m->offset + m->size - start, size);
284 paddr = m->paddr + start - m->offset; 389 paddr = m->paddr + start - m->offset;
285 if (remap_pfn_range(vma, vma->vm_start + len, 390 if (remap_oldmem_pfn_range(vma, vma->vm_start + len,
286 paddr >> PAGE_SHIFT, tsz, 391 paddr >> PAGE_SHIFT, tsz,
287 vma->vm_page_prot)) 392 vma->vm_page_prot))
288 goto fail; 393 goto fail;
289 size -= tsz; 394 size -= tsz;
290 start += tsz; 395 start += tsz;
@@ -357,7 +462,7 @@ static int __init update_note_header_size_elf64(const Elf64_Ehdr *ehdr_ptr)
357 notes_section = kmalloc(max_sz, GFP_KERNEL); 462 notes_section = kmalloc(max_sz, GFP_KERNEL);
358 if (!notes_section) 463 if (!notes_section)
359 return -ENOMEM; 464 return -ENOMEM;
360 rc = read_from_oldmem(notes_section, max_sz, &offset, 0); 465 rc = elfcorehdr_read_notes(notes_section, max_sz, &offset);
361 if (rc < 0) { 466 if (rc < 0) {
362 kfree(notes_section); 467 kfree(notes_section);
363 return rc; 468 return rc;
@@ -444,7 +549,8 @@ static int __init copy_notes_elf64(const Elf64_Ehdr *ehdr_ptr, char *notes_buf)
444 if (phdr_ptr->p_type != PT_NOTE) 549 if (phdr_ptr->p_type != PT_NOTE)
445 continue; 550 continue;
446 offset = phdr_ptr->p_offset; 551 offset = phdr_ptr->p_offset;
447 rc = read_from_oldmem(notes_buf, phdr_ptr->p_memsz, &offset, 0); 552 rc = elfcorehdr_read_notes(notes_buf, phdr_ptr->p_memsz,
553 &offset);
448 if (rc < 0) 554 if (rc < 0)
449 return rc; 555 return rc;
450 notes_buf += phdr_ptr->p_memsz; 556 notes_buf += phdr_ptr->p_memsz;
@@ -536,7 +642,7 @@ static int __init update_note_header_size_elf32(const Elf32_Ehdr *ehdr_ptr)
536 notes_section = kmalloc(max_sz, GFP_KERNEL); 642 notes_section = kmalloc(max_sz, GFP_KERNEL);
537 if (!notes_section) 643 if (!notes_section)
538 return -ENOMEM; 644 return -ENOMEM;
539 rc = read_from_oldmem(notes_section, max_sz, &offset, 0); 645 rc = elfcorehdr_read_notes(notes_section, max_sz, &offset);
540 if (rc < 0) { 646 if (rc < 0) {
541 kfree(notes_section); 647 kfree(notes_section);
542 return rc; 648 return rc;
@@ -623,7 +729,8 @@ static int __init copy_notes_elf32(const Elf32_Ehdr *ehdr_ptr, char *notes_buf)
623 if (phdr_ptr->p_type != PT_NOTE) 729 if (phdr_ptr->p_type != PT_NOTE)
624 continue; 730 continue;
625 offset = phdr_ptr->p_offset; 731 offset = phdr_ptr->p_offset;
626 rc = read_from_oldmem(notes_buf, phdr_ptr->p_memsz, &offset, 0); 732 rc = elfcorehdr_read_notes(notes_buf, phdr_ptr->p_memsz,
733 &offset);
627 if (rc < 0) 734 if (rc < 0)
628 return rc; 735 return rc;
629 notes_buf += phdr_ptr->p_memsz; 736 notes_buf += phdr_ptr->p_memsz;
@@ -810,7 +917,7 @@ static int __init parse_crash_elf64_headers(void)
810 addr = elfcorehdr_addr; 917 addr = elfcorehdr_addr;
811 918
812 /* Read Elf header */ 919 /* Read Elf header */
813 rc = read_from_oldmem((char*)&ehdr, sizeof(Elf64_Ehdr), &addr, 0); 920 rc = elfcorehdr_read((char *)&ehdr, sizeof(Elf64_Ehdr), &addr);
814 if (rc < 0) 921 if (rc < 0)
815 return rc; 922 return rc;
816 923
@@ -837,7 +944,7 @@ static int __init parse_crash_elf64_headers(void)
837 if (!elfcorebuf) 944 if (!elfcorebuf)
838 return -ENOMEM; 945 return -ENOMEM;
839 addr = elfcorehdr_addr; 946 addr = elfcorehdr_addr;
840 rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz_orig, &addr, 0); 947 rc = elfcorehdr_read(elfcorebuf, elfcorebuf_sz_orig, &addr);
841 if (rc < 0) 948 if (rc < 0)
842 goto fail; 949 goto fail;
843 950
@@ -866,7 +973,7 @@ static int __init parse_crash_elf32_headers(void)
866 addr = elfcorehdr_addr; 973 addr = elfcorehdr_addr;
867 974
868 /* Read Elf header */ 975 /* Read Elf header */
869 rc = read_from_oldmem((char*)&ehdr, sizeof(Elf32_Ehdr), &addr, 0); 976 rc = elfcorehdr_read((char *)&ehdr, sizeof(Elf32_Ehdr), &addr);
870 if (rc < 0) 977 if (rc < 0)
871 return rc; 978 return rc;
872 979
@@ -892,7 +999,7 @@ static int __init parse_crash_elf32_headers(void)
892 if (!elfcorebuf) 999 if (!elfcorebuf)
893 return -ENOMEM; 1000 return -ENOMEM;
894 addr = elfcorehdr_addr; 1001 addr = elfcorehdr_addr;
895 rc = read_from_oldmem(elfcorebuf, elfcorebuf_sz_orig, &addr, 0); 1002 rc = elfcorehdr_read(elfcorebuf, elfcorebuf_sz_orig, &addr);
896 if (rc < 0) 1003 if (rc < 0)
897 goto fail; 1004 goto fail;
898 1005
@@ -919,7 +1026,7 @@ static int __init parse_crash_elf_headers(void)
919 int rc=0; 1026 int rc=0;
920 1027
921 addr = elfcorehdr_addr; 1028 addr = elfcorehdr_addr;
922 rc = read_from_oldmem(e_ident, EI_NIDENT, &addr, 0); 1029 rc = elfcorehdr_read(e_ident, EI_NIDENT, &addr);
923 if (rc < 0) 1030 if (rc < 0)
924 return rc; 1031 return rc;
925 if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) { 1032 if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) {
@@ -952,7 +1059,14 @@ static int __init vmcore_init(void)
952{ 1059{
953 int rc = 0; 1060 int rc = 0;
954 1061
955 /* If elfcorehdr= has been passed in cmdline, then capture the dump.*/ 1062 /* Allow architectures to allocate ELF header in 2nd kernel */
1063 rc = elfcorehdr_alloc(&elfcorehdr_addr, &elfcorehdr_size);
1064 if (rc)
1065 return rc;
1066 /*
1067 * If elfcorehdr= has been passed in cmdline or created in 2nd kernel,
1068 * then capture the dump.
1069 */
956 if (!(is_vmcore_usable())) 1070 if (!(is_vmcore_usable()))
957 return rc; 1071 return rc;
958 rc = parse_crash_elf_headers(); 1072 rc = parse_crash_elf_headers();
@@ -960,6 +1074,8 @@ static int __init vmcore_init(void)
960 pr_warn("Kdump: vmcore not initialized\n"); 1074 pr_warn("Kdump: vmcore not initialized\n");
961 return rc; 1075 return rc;
962 } 1076 }
1077 elfcorehdr_free(elfcorehdr_addr);
1078 elfcorehdr_addr = ELFCORE_ADDR_ERR;
963 1079
964 proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations); 1080 proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations);
965 if (proc_vmcore) 1081 if (proc_vmcore)