aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/Makefile1
-rw-r--r--fs/proc/array.c22
-rw-r--r--fs/proc/base.c89
-rw-r--r--fs/proc/cmdline.c2
-rw-r--r--fs/proc/consoles.c2
-rw-r--r--fs/proc/cpuinfo.c2
-rw-r--r--fs/proc/devices.c2
-rw-r--r--fs/proc/fd.c6
-rw-r--r--fs/proc/generic.c3
-rw-r--r--fs/proc/inode.c4
-rw-r--r--fs/proc/internal.h7
-rw-r--r--fs/proc/interrupts.c2
-rw-r--r--fs/proc/kcore.c2
-rw-r--r--fs/proc/kmsg.c2
-rw-r--r--fs/proc/loadavg.c2
-rw-r--r--fs/proc/meminfo.c39
-rw-r--r--fs/proc/nommu.c2
-rw-r--r--fs/proc/page.c9
-rw-r--r--fs/proc/proc_devtree.c240
-rw-r--r--fs/proc/root.c5
-rw-r--r--fs/proc/softirqs.c2
-rw-r--r--fs/proc/stat.c4
-rw-r--r--fs/proc/task_mmu.c3
-rw-r--r--fs/proc/uptime.c4
-rw-r--r--fs/proc/version.c2
-rw-r--r--fs/proc/vmcore.c27
26 files changed, 142 insertions, 343 deletions
diff --git a/fs/proc/Makefile b/fs/proc/Makefile
index ab30716584f5..239493ec718e 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -27,6 +27,5 @@ proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o
27proc-$(CONFIG_NET) += proc_net.o 27proc-$(CONFIG_NET) += proc_net.o
28proc-$(CONFIG_PROC_KCORE) += kcore.o 28proc-$(CONFIG_PROC_KCORE) += kcore.o
29proc-$(CONFIG_PROC_VMCORE) += vmcore.o 29proc-$(CONFIG_PROC_VMCORE) += vmcore.o
30proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o
31proc-$(CONFIG_PRINTK) += kmsg.o 30proc-$(CONFIG_PRINTK) += kmsg.o
32proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o 31proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 1bd2077187fd..64db2bceac59 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -138,26 +138,17 @@ static const char * const task_state_array[] = {
138 "D (disk sleep)", /* 2 */ 138 "D (disk sleep)", /* 2 */
139 "T (stopped)", /* 4 */ 139 "T (stopped)", /* 4 */
140 "t (tracing stop)", /* 8 */ 140 "t (tracing stop)", /* 8 */
141 "Z (zombie)", /* 16 */ 141 "X (dead)", /* 16 */
142 "X (dead)", /* 32 */ 142 "Z (zombie)", /* 32 */
143 "x (dead)", /* 64 */
144 "K (wakekill)", /* 128 */
145 "W (waking)", /* 256 */
146 "P (parked)", /* 512 */
147}; 143};
148 144
149static inline const char *get_task_state(struct task_struct *tsk) 145static inline const char *get_task_state(struct task_struct *tsk)
150{ 146{
151 unsigned int state = (tsk->state & TASK_REPORT) | tsk->exit_state; 147 unsigned int state = (tsk->state | tsk->exit_state) & TASK_REPORT;
152 const char * const *p = &task_state_array[0];
153 148
154 BUILD_BUG_ON(1 + ilog2(TASK_STATE_MAX) != ARRAY_SIZE(task_state_array)); 149 BUILD_BUG_ON(1 + ilog2(TASK_REPORT) != ARRAY_SIZE(task_state_array)-1);
155 150
156 while (state) { 151 return task_state_array[fls(state)];
157 p++;
158 state >>= 1;
159 }
160 return *p;
161} 152}
162 153
163static inline void task_state(struct seq_file *m, struct pid_namespace *ns, 154static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
@@ -453,8 +444,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
453 min_flt += t->min_flt; 444 min_flt += t->min_flt;
454 maj_flt += t->maj_flt; 445 maj_flt += t->maj_flt;
455 gtime += task_gtime(t); 446 gtime += task_gtime(t);
456 t = next_thread(t); 447 } while_each_thread(task, t);
457 } while (t != task);
458 448
459 min_flt += sig->min_flt; 449 min_flt += sig->min_flt;
460 maj_flt += sig->maj_flt; 450 maj_flt += sig->maj_flt;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index cfd178dc76b2..2d696b0c93bf 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1204,6 +1204,9 @@ static ssize_t proc_fault_inject_write(struct file * file,
1204 make_it_fail = simple_strtol(strstrip(buffer), &end, 0); 1204 make_it_fail = simple_strtol(strstrip(buffer), &end, 0);
1205 if (*end) 1205 if (*end)
1206 return -EINVAL; 1206 return -EINVAL;
1207 if (make_it_fail < 0 || make_it_fail > 1)
1208 return -EINVAL;
1209
1207 task = get_proc_task(file_inode(file)); 1210 task = get_proc_task(file_inode(file));
1208 if (!task) 1211 if (!task)
1209 return -ESRCH; 1212 return -ESRCH;
@@ -1626,13 +1629,18 @@ int pid_revalidate(struct dentry *dentry, unsigned int flags)
1626 return 0; 1629 return 0;
1627} 1630}
1628 1631
1632static inline bool proc_inode_is_dead(struct inode *inode)
1633{
1634 return !proc_pid(inode)->tasks[PIDTYPE_PID].first;
1635}
1636
1629int pid_delete_dentry(const struct dentry *dentry) 1637int pid_delete_dentry(const struct dentry *dentry)
1630{ 1638{
1631 /* Is the task we represent dead? 1639 /* Is the task we represent dead?
1632 * If so, then don't put the dentry on the lru list, 1640 * If so, then don't put the dentry on the lru list,
1633 * kill it immediately. 1641 * kill it immediately.
1634 */ 1642 */
1635 return !proc_pid(dentry->d_inode)->tasks[PIDTYPE_PID].first; 1643 return proc_inode_is_dead(dentry->d_inode);
1636} 1644}
1637 1645
1638const struct dentry_operations pid_dentry_operations = 1646const struct dentry_operations pid_dentry_operations =
@@ -1787,6 +1795,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path)
1787 if (rc) 1795 if (rc)
1788 goto out_mmput; 1796 goto out_mmput;
1789 1797
1798 rc = -ENOENT;
1790 down_read(&mm->mmap_sem); 1799 down_read(&mm->mmap_sem);
1791 vma = find_exact_vma(mm, vm_start, vm_end); 1800 vma = find_exact_vma(mm, vm_start, vm_end);
1792 if (vma && vma->vm_file) { 1801 if (vma && vma->vm_file) {
@@ -2550,7 +2559,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2550 REG("environ", S_IRUSR, proc_environ_operations), 2559 REG("environ", S_IRUSR, proc_environ_operations),
2551 INF("auxv", S_IRUSR, proc_pid_auxv), 2560 INF("auxv", S_IRUSR, proc_pid_auxv),
2552 ONE("status", S_IRUGO, proc_pid_status), 2561 ONE("status", S_IRUGO, proc_pid_status),
2553 ONE("personality", S_IRUGO, proc_pid_personality), 2562 ONE("personality", S_IRUSR, proc_pid_personality),
2554 INF("limits", S_IRUGO, proc_pid_limits), 2563 INF("limits", S_IRUGO, proc_pid_limits),
2555#ifdef CONFIG_SCHED_DEBUG 2564#ifdef CONFIG_SCHED_DEBUG
2556 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), 2565 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
@@ -2560,7 +2569,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2560#endif 2569#endif
2561 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), 2570 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
2562#ifdef CONFIG_HAVE_ARCH_TRACEHOOK 2571#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2563 INF("syscall", S_IRUGO, proc_pid_syscall), 2572 INF("syscall", S_IRUSR, proc_pid_syscall),
2564#endif 2573#endif
2565 INF("cmdline", S_IRUGO, proc_pid_cmdline), 2574 INF("cmdline", S_IRUGO, proc_pid_cmdline),
2566 ONE("stat", S_IRUGO, proc_tgid_stat), 2575 ONE("stat", S_IRUGO, proc_tgid_stat),
@@ -2579,7 +2588,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2579#ifdef CONFIG_PROC_PAGE_MONITOR 2588#ifdef CONFIG_PROC_PAGE_MONITOR
2580 REG("clear_refs", S_IWUSR, proc_clear_refs_operations), 2589 REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
2581 REG("smaps", S_IRUGO, proc_pid_smaps_operations), 2590 REG("smaps", S_IRUGO, proc_pid_smaps_operations),
2582 REG("pagemap", S_IRUGO, proc_pagemap_operations), 2591 REG("pagemap", S_IRUSR, proc_pagemap_operations),
2583#endif 2592#endif
2584#ifdef CONFIG_SECURITY 2593#ifdef CONFIG_SECURITY
2585 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), 2594 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
@@ -2588,7 +2597,7 @@ static const struct pid_entry tgid_base_stuff[] = {
2588 INF("wchan", S_IRUGO, proc_pid_wchan), 2597 INF("wchan", S_IRUGO, proc_pid_wchan),
2589#endif 2598#endif
2590#ifdef CONFIG_STACKTRACE 2599#ifdef CONFIG_STACKTRACE
2591 ONE("stack", S_IRUGO, proc_pid_stack), 2600 ONE("stack", S_IRUSR, proc_pid_stack),
2592#endif 2601#endif
2593#ifdef CONFIG_SCHEDSTATS 2602#ifdef CONFIG_SCHEDSTATS
2594 INF("schedstat", S_IRUGO, proc_pid_schedstat), 2603 INF("schedstat", S_IRUGO, proc_pid_schedstat),
@@ -2889,14 +2898,14 @@ static const struct pid_entry tid_base_stuff[] = {
2889 REG("environ", S_IRUSR, proc_environ_operations), 2898 REG("environ", S_IRUSR, proc_environ_operations),
2890 INF("auxv", S_IRUSR, proc_pid_auxv), 2899 INF("auxv", S_IRUSR, proc_pid_auxv),
2891 ONE("status", S_IRUGO, proc_pid_status), 2900 ONE("status", S_IRUGO, proc_pid_status),
2892 ONE("personality", S_IRUGO, proc_pid_personality), 2901 ONE("personality", S_IRUSR, proc_pid_personality),
2893 INF("limits", S_IRUGO, proc_pid_limits), 2902 INF("limits", S_IRUGO, proc_pid_limits),
2894#ifdef CONFIG_SCHED_DEBUG 2903#ifdef CONFIG_SCHED_DEBUG
2895 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), 2904 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
2896#endif 2905#endif
2897 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), 2906 REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
2898#ifdef CONFIG_HAVE_ARCH_TRACEHOOK 2907#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2899 INF("syscall", S_IRUGO, proc_pid_syscall), 2908 INF("syscall", S_IRUSR, proc_pid_syscall),
2900#endif 2909#endif
2901 INF("cmdline", S_IRUGO, proc_pid_cmdline), 2910 INF("cmdline", S_IRUGO, proc_pid_cmdline),
2902 ONE("stat", S_IRUGO, proc_tid_stat), 2911 ONE("stat", S_IRUGO, proc_tid_stat),
@@ -2917,7 +2926,7 @@ static const struct pid_entry tid_base_stuff[] = {
2917#ifdef CONFIG_PROC_PAGE_MONITOR 2926#ifdef CONFIG_PROC_PAGE_MONITOR
2918 REG("clear_refs", S_IWUSR, proc_clear_refs_operations), 2927 REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
2919 REG("smaps", S_IRUGO, proc_tid_smaps_operations), 2928 REG("smaps", S_IRUGO, proc_tid_smaps_operations),
2920 REG("pagemap", S_IRUGO, proc_pagemap_operations), 2929 REG("pagemap", S_IRUSR, proc_pagemap_operations),
2921#endif 2930#endif
2922#ifdef CONFIG_SECURITY 2931#ifdef CONFIG_SECURITY
2923 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations), 2932 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
@@ -2926,7 +2935,7 @@ static const struct pid_entry tid_base_stuff[] = {
2926 INF("wchan", S_IRUGO, proc_pid_wchan), 2935 INF("wchan", S_IRUGO, proc_pid_wchan),
2927#endif 2936#endif
2928#ifdef CONFIG_STACKTRACE 2937#ifdef CONFIG_STACKTRACE
2929 ONE("stack", S_IRUGO, proc_pid_stack), 2938 ONE("stack", S_IRUSR, proc_pid_stack),
2930#endif 2939#endif
2931#ifdef CONFIG_SCHEDSTATS 2940#ifdef CONFIG_SCHEDSTATS
2932 INF("schedstat", S_IRUGO, proc_pid_schedstat), 2941 INF("schedstat", S_IRUGO, proc_pid_schedstat),
@@ -3060,34 +3069,42 @@ out_no_task:
3060 * In the case of a seek we start with the leader and walk nr 3069 * In the case of a seek we start with the leader and walk nr
3061 * threads past it. 3070 * threads past it.
3062 */ 3071 */
3063static struct task_struct *first_tid(struct task_struct *leader, 3072static struct task_struct *first_tid(struct pid *pid, int tid, loff_t f_pos,
3064 int tid, int nr, struct pid_namespace *ns) 3073 struct pid_namespace *ns)
3065{ 3074{
3066 struct task_struct *pos; 3075 struct task_struct *pos, *task;
3076 unsigned long nr = f_pos;
3077
3078 if (nr != f_pos) /* 32bit overflow? */
3079 return NULL;
3067 3080
3068 rcu_read_lock(); 3081 rcu_read_lock();
3069 /* Attempt to start with the pid of a thread */ 3082 task = pid_task(pid, PIDTYPE_PID);
3070 if (tid && (nr > 0)) { 3083 if (!task)
3084 goto fail;
3085
3086 /* Attempt to start with the tid of a thread */
3087 if (tid && nr) {
3071 pos = find_task_by_pid_ns(tid, ns); 3088 pos = find_task_by_pid_ns(tid, ns);
3072 if (pos && (pos->group_leader == leader)) 3089 if (pos && same_thread_group(pos, task))
3073 goto found; 3090 goto found;
3074 } 3091 }
3075 3092
3076 /* If nr exceeds the number of threads there is nothing todo */ 3093 /* If nr exceeds the number of threads there is nothing todo */
3077 pos = NULL; 3094 if (nr >= get_nr_threads(task))
3078 if (nr && nr >= get_nr_threads(leader)) 3095 goto fail;
3079 goto out;
3080 3096
3081 /* If we haven't found our starting place yet start 3097 /* If we haven't found our starting place yet start
3082 * with the leader and walk nr threads forward. 3098 * with the leader and walk nr threads forward.
3083 */ 3099 */
3084 for (pos = leader; nr > 0; --nr) { 3100 pos = task = task->group_leader;
3085 pos = next_thread(pos); 3101 do {
3086 if (pos == leader) { 3102 if (!nr--)
3087 pos = NULL; 3103 goto found;
3088 goto out; 3104 } while_each_thread(task, pos);
3089 } 3105fail:
3090 } 3106 pos = NULL;
3107 goto out;
3091found: 3108found:
3092 get_task_struct(pos); 3109 get_task_struct(pos);
3093out: 3110out:
@@ -3120,25 +3137,16 @@ static struct task_struct *next_tid(struct task_struct *start)
3120/* for the /proc/TGID/task/ directories */ 3137/* for the /proc/TGID/task/ directories */
3121static int proc_task_readdir(struct file *file, struct dir_context *ctx) 3138static int proc_task_readdir(struct file *file, struct dir_context *ctx)
3122{ 3139{
3123 struct task_struct *leader = NULL; 3140 struct inode *inode = file_inode(file);
3124 struct task_struct *task = get_proc_task(file_inode(file)); 3141 struct task_struct *task;
3125 struct pid_namespace *ns; 3142 struct pid_namespace *ns;
3126 int tid; 3143 int tid;
3127 3144
3128 if (!task) 3145 if (proc_inode_is_dead(inode))
3129 return -ENOENT;
3130 rcu_read_lock();
3131 if (pid_alive(task)) {
3132 leader = task->group_leader;
3133 get_task_struct(leader);
3134 }
3135 rcu_read_unlock();
3136 put_task_struct(task);
3137 if (!leader)
3138 return -ENOENT; 3146 return -ENOENT;
3139 3147
3140 if (!dir_emit_dots(file, ctx)) 3148 if (!dir_emit_dots(file, ctx))
3141 goto out; 3149 return 0;
3142 3150
3143 /* f_version caches the tgid value that the last readdir call couldn't 3151 /* f_version caches the tgid value that the last readdir call couldn't
3144 * return. lseek aka telldir automagically resets f_version to 0. 3152 * return. lseek aka telldir automagically resets f_version to 0.
@@ -3146,7 +3154,7 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx)
3146 ns = file->f_dentry->d_sb->s_fs_info; 3154 ns = file->f_dentry->d_sb->s_fs_info;
3147 tid = (int)file->f_version; 3155 tid = (int)file->f_version;
3148 file->f_version = 0; 3156 file->f_version = 0;
3149 for (task = first_tid(leader, tid, ctx->pos - 2, ns); 3157 for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns);
3150 task; 3158 task;
3151 task = next_tid(task), ctx->pos++) { 3159 task = next_tid(task), ctx->pos++) {
3152 char name[PROC_NUMBUF]; 3160 char name[PROC_NUMBUF];
@@ -3162,8 +3170,7 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx)
3162 break; 3170 break;
3163 } 3171 }
3164 } 3172 }
3165out: 3173
3166 put_task_struct(leader);
3167 return 0; 3174 return 0;
3168} 3175}
3169 3176
diff --git a/fs/proc/cmdline.c b/fs/proc/cmdline.c
index 82676e3fcd1d..cbd82dff7e81 100644
--- a/fs/proc/cmdline.c
+++ b/fs/proc/cmdline.c
@@ -26,4 +26,4 @@ static int __init proc_cmdline_init(void)
26 proc_create("cmdline", 0, NULL, &cmdline_proc_fops); 26 proc_create("cmdline", 0, NULL, &cmdline_proc_fops);
27 return 0; 27 return 0;
28} 28}
29module_init(proc_cmdline_init); 29fs_initcall(proc_cmdline_init);
diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
index 51942d5abcec..290ba85cb900 100644
--- a/fs/proc/consoles.c
+++ b/fs/proc/consoles.c
@@ -109,4 +109,4 @@ static int __init proc_consoles_init(void)
109 proc_create("consoles", 0, NULL, &proc_consoles_operations); 109 proc_create("consoles", 0, NULL, &proc_consoles_operations);
110 return 0; 110 return 0;
111} 111}
112module_init(proc_consoles_init); 112fs_initcall(proc_consoles_init);
diff --git a/fs/proc/cpuinfo.c b/fs/proc/cpuinfo.c
index 5a1e539a234b..06f4d31e0396 100644
--- a/fs/proc/cpuinfo.c
+++ b/fs/proc/cpuinfo.c
@@ -21,4 +21,4 @@ static int __init proc_cpuinfo_init(void)
21 proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations); 21 proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
22 return 0; 22 return 0;
23} 23}
24module_init(proc_cpuinfo_init); 24fs_initcall(proc_cpuinfo_init);
diff --git a/fs/proc/devices.c b/fs/proc/devices.c
index b14347167c35..50493edc30e5 100644
--- a/fs/proc/devices.c
+++ b/fs/proc/devices.c
@@ -67,4 +67,4 @@ static int __init proc_devices_init(void)
67 proc_create("devices", 0, NULL, &proc_devinfo_operations); 67 proc_create("devices", 0, NULL, &proc_devinfo_operations);
68 return 0; 68 return 0;
69} 69}
70module_init(proc_devices_init); 70fs_initcall(proc_devices_init);
diff --git a/fs/proc/fd.c b/fs/proc/fd.c
index 985ea881b5bc..0788d093f5d8 100644
--- a/fs/proc/fd.c
+++ b/fs/proc/fd.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/proc_fs.h> 12#include <linux/proc_fs.h>
13 13
14#include "../mount.h"
14#include "internal.h" 15#include "internal.h"
15#include "fd.h" 16#include "fd.h"
16 17
@@ -48,8 +49,9 @@ static int seq_show(struct seq_file *m, void *v)
48 } 49 }
49 50
50 if (!ret) { 51 if (!ret) {
51 seq_printf(m, "pos:\t%lli\nflags:\t0%o\n", 52 seq_printf(m, "pos:\t%lli\nflags:\t0%o\nmnt_id:\t%i\n",
52 (long long)file->f_pos, f_flags); 53 (long long)file->f_pos, f_flags,
54 real_mount(file->f_path.mnt)->mnt_id);
53 if (file->f_op->show_fdinfo) 55 if (file->f_op->show_fdinfo)
54 ret = file->f_op->show_fdinfo(m, file); 56 ret = file->f_op->show_fdinfo(m, file);
55 fput(file); 57 fput(file);
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index cca93b6fb9a9..b7f268eb5f45 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -49,8 +49,7 @@ static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
49 setattr_copy(inode, iattr); 49 setattr_copy(inode, iattr);
50 mark_inode_dirty(inode); 50 mark_inode_dirty(inode);
51 51
52 de->uid = inode->i_uid; 52 proc_set_user(de, inode->i_uid, inode->i_gid);
53 de->gid = inode->i_gid;
54 de->mode = inode->i_mode; 53 de->mode = inode->i_mode;
55 return 0; 54 return 0;
56} 55}
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 124fc43c7090..0adbc02d60e3 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -35,7 +35,7 @@ static void proc_evict_inode(struct inode *inode)
35 const struct proc_ns_operations *ns_ops; 35 const struct proc_ns_operations *ns_ops;
36 void *ns; 36 void *ns;
37 37
38 truncate_inode_pages(&inode->i_data, 0); 38 truncate_inode_pages_final(&inode->i_data);
39 clear_inode(inode); 39 clear_inode(inode);
40 40
41 /* Stop tracking associated processes */ 41 /* Stop tracking associated processes */
@@ -47,7 +47,7 @@ static void proc_evict_inode(struct inode *inode)
47 pde_put(de); 47 pde_put(de);
48 head = PROC_I(inode)->sysctl; 48 head = PROC_I(inode)->sysctl;
49 if (head) { 49 if (head) {
50 rcu_assign_pointer(PROC_I(inode)->sysctl, NULL); 50 RCU_INIT_POINTER(PROC_I(inode)->sysctl, NULL);
51 sysctl_head_put(head); 51 sysctl_head_put(head);
52 } 52 }
53 /* Release any associated namespace */ 53 /* Release any associated namespace */
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 651d09a11dde..3ab6d14e71c5 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -211,13 +211,6 @@ extern int proc_fill_super(struct super_block *);
211extern void proc_entry_rundown(struct proc_dir_entry *); 211extern void proc_entry_rundown(struct proc_dir_entry *);
212 212
213/* 213/*
214 * proc_devtree.c
215 */
216#ifdef CONFIG_PROC_DEVICETREE
217extern void proc_device_tree_init(void);
218#endif
219
220/*
221 * proc_namespaces.c 214 * proc_namespaces.c
222 */ 215 */
223extern const struct inode_operations proc_ns_dir_inode_operations; 216extern const struct inode_operations proc_ns_dir_inode_operations;
diff --git a/fs/proc/interrupts.c b/fs/proc/interrupts.c
index 05029c0e2f24..a352d5703b41 100644
--- a/fs/proc/interrupts.c
+++ b/fs/proc/interrupts.c
@@ -50,4 +50,4 @@ static int __init proc_interrupts_init(void)
50 proc_create("interrupts", 0, NULL, &proc_interrupts_operations); 50 proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
51 return 0; 51 return 0;
52} 52}
53module_init(proc_interrupts_init); 53fs_initcall(proc_interrupts_init);
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 5ed0e52d6aa0..39e6ef32f0bd 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -639,4 +639,4 @@ static int __init proc_kcore_init(void)
639 639
640 return 0; 640 return 0;
641} 641}
642module_init(proc_kcore_init); 642fs_initcall(proc_kcore_init);
diff --git a/fs/proc/kmsg.c b/fs/proc/kmsg.c
index bdfabdaefdce..05f8dcdb086e 100644
--- a/fs/proc/kmsg.c
+++ b/fs/proc/kmsg.c
@@ -61,4 +61,4 @@ static int __init proc_kmsg_init(void)
61 proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations); 61 proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
62 return 0; 62 return 0;
63} 63}
64module_init(proc_kmsg_init); 64fs_initcall(proc_kmsg_init);
diff --git a/fs/proc/loadavg.c b/fs/proc/loadavg.c
index 1afa4dd4cae2..aec66e6c2060 100644
--- a/fs/proc/loadavg.c
+++ b/fs/proc/loadavg.c
@@ -42,4 +42,4 @@ static int __init proc_loadavg_init(void)
42 proc_create("loadavg", 0, NULL, &loadavg_proc_fops); 42 proc_create("loadavg", 0, NULL, &loadavg_proc_fops);
43 return 0; 43 return 0;
44} 44}
45module_init(proc_loadavg_init); 45fs_initcall(proc_loadavg_init);
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
index a77d2b299199..7445af0b1aa3 100644
--- a/fs/proc/meminfo.c
+++ b/fs/proc/meminfo.c
@@ -26,7 +26,11 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
26 unsigned long committed; 26 unsigned long committed;
27 struct vmalloc_info vmi; 27 struct vmalloc_info vmi;
28 long cached; 28 long cached;
29 long available;
30 unsigned long pagecache;
31 unsigned long wmark_low = 0;
29 unsigned long pages[NR_LRU_LISTS]; 32 unsigned long pages[NR_LRU_LISTS];
33 struct zone *zone;
30 int lru; 34 int lru;
31 35
32/* 36/*
@@ -47,12 +51,44 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
47 for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++) 51 for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
48 pages[lru] = global_page_state(NR_LRU_BASE + lru); 52 pages[lru] = global_page_state(NR_LRU_BASE + lru);
49 53
54 for_each_zone(zone)
55 wmark_low += zone->watermark[WMARK_LOW];
56
57 /*
58 * Estimate the amount of memory available for userspace allocations,
59 * without causing swapping.
60 *
61 * Free memory cannot be taken below the low watermark, before the
62 * system starts swapping.
63 */
64 available = i.freeram - wmark_low;
65
66 /*
67 * Not all the page cache can be freed, otherwise the system will
68 * start swapping. Assume at least half of the page cache, or the
69 * low watermark worth of cache, needs to stay.
70 */
71 pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
72 pagecache -= min(pagecache / 2, wmark_low);
73 available += pagecache;
74
75 /*
76 * Part of the reclaimable slab consists of items that are in use,
77 * and cannot be freed. Cap this estimate at the low watermark.
78 */
79 available += global_page_state(NR_SLAB_RECLAIMABLE) -
80 min(global_page_state(NR_SLAB_RECLAIMABLE) / 2, wmark_low);
81
82 if (available < 0)
83 available = 0;
84
50 /* 85 /*
51 * Tagged format, for easy grepping and expansion. 86 * Tagged format, for easy grepping and expansion.
52 */ 87 */
53 seq_printf(m, 88 seq_printf(m,
54 "MemTotal: %8lu kB\n" 89 "MemTotal: %8lu kB\n"
55 "MemFree: %8lu kB\n" 90 "MemFree: %8lu kB\n"
91 "MemAvailable: %8lu kB\n"
56 "Buffers: %8lu kB\n" 92 "Buffers: %8lu kB\n"
57 "Cached: %8lu kB\n" 93 "Cached: %8lu kB\n"
58 "SwapCached: %8lu kB\n" 94 "SwapCached: %8lu kB\n"
@@ -105,6 +141,7 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
105 , 141 ,
106 K(i.totalram), 142 K(i.totalram),
107 K(i.freeram), 143 K(i.freeram),
144 K(available),
108 K(i.bufferram), 145 K(i.bufferram),
109 K(cached), 146 K(cached),
110 K(total_swapcache_pages()), 147 K(total_swapcache_pages()),
@@ -183,4 +220,4 @@ static int __init proc_meminfo_init(void)
183 proc_create("meminfo", 0, NULL, &meminfo_proc_fops); 220 proc_create("meminfo", 0, NULL, &meminfo_proc_fops);
184 return 0; 221 return 0;
185} 222}
186module_init(proc_meminfo_init); 223fs_initcall(proc_meminfo_init);
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
index 5f9bc8a746c9..d4a35746cab9 100644
--- a/fs/proc/nommu.c
+++ b/fs/proc/nommu.c
@@ -131,4 +131,4 @@ static int __init proc_nommu_init(void)
131 return 0; 131 return 0;
132} 132}
133 133
134module_init(proc_nommu_init); 134fs_initcall(proc_nommu_init);
diff --git a/fs/proc/page.c b/fs/proc/page.c
index b8730d9ebaee..e647c55275d9 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -118,10 +118,11 @@ u64 stable_page_flags(struct page *page)
118 /* 118 /*
119 * PageTransCompound can be true for non-huge compound pages (slab 119 * PageTransCompound can be true for non-huge compound pages (slab
120 * pages or pages allocated by drivers with __GFP_COMP) because it 120 * pages or pages allocated by drivers with __GFP_COMP) because it
121 * just checks PG_head/PG_tail, so we need to check PageLRU to make 121 * just checks PG_head/PG_tail, so we need to check PageLRU/PageAnon
122 * sure a given page is a thp, not a non-huge compound page. 122 * to make sure a given page is a thp, not a non-huge compound page.
123 */ 123 */
124 else if (PageTransCompound(page) && PageLRU(compound_trans_head(page))) 124 else if (PageTransCompound(page) && (PageLRU(compound_head(page)) ||
125 PageAnon(compound_head(page))))
125 u |= 1 << KPF_THP; 126 u |= 1 << KPF_THP;
126 127
127 /* 128 /*
@@ -217,4 +218,4 @@ static int __init proc_page_init(void)
217 proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations); 218 proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations);
218 return 0; 219 return 0;
219} 220}
220module_init(proc_page_init); 221fs_initcall(proc_page_init);
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c
deleted file mode 100644
index 70779b2fc209..000000000000
--- a/fs/proc/proc_devtree.c
+++ /dev/null
@@ -1,240 +0,0 @@
1/*
2 * proc_devtree.c - handles /proc/device-tree
3 *
4 * Copyright 1997 Paul Mackerras
5 */
6#include <linux/errno.h>
7#include <linux/init.h>
8#include <linux/time.h>
9#include <linux/proc_fs.h>
10#include <linux/seq_file.h>
11#include <linux/printk.h>
12#include <linux/stat.h>
13#include <linux/string.h>
14#include <linux/of.h>
15#include <linux/export.h>
16#include <linux/slab.h>
17#include <asm/uaccess.h>
18#include "internal.h"
19
20static inline void set_node_proc_entry(struct device_node *np,
21 struct proc_dir_entry *de)
22{
23 np->pde = de;
24}
25
26static struct proc_dir_entry *proc_device_tree;
27
28/*
29 * Supply data on a read from /proc/device-tree/node/property.
30 */
31static int property_proc_show(struct seq_file *m, void *v)
32{
33 struct property *pp = m->private;
34
35 seq_write(m, pp->value, pp->length);
36 return 0;
37}
38
39static int property_proc_open(struct inode *inode, struct file *file)
40{
41 return single_open(file, property_proc_show, __PDE_DATA(inode));
42}
43
44static const struct file_operations property_proc_fops = {
45 .owner = THIS_MODULE,
46 .open = property_proc_open,
47 .read = seq_read,
48 .llseek = seq_lseek,
49 .release = single_release,
50};
51
52/*
53 * For a node with a name like "gc@10", we make symlinks called "gc"
54 * and "@10" to it.
55 */
56
57/*
58 * Add a property to a node
59 */
60static struct proc_dir_entry *
61__proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp,
62 const char *name)
63{
64 struct proc_dir_entry *ent;
65
66 /*
67 * Unfortunately proc_register puts each new entry
68 * at the beginning of the list. So we rearrange them.
69 */
70 ent = proc_create_data(name,
71 strncmp(name, "security-", 9) ? S_IRUGO : S_IRUSR,
72 de, &property_proc_fops, pp);
73 if (ent == NULL)
74 return NULL;
75
76 if (!strncmp(name, "security-", 9))
77 ent->size = 0; /* don't leak number of password chars */
78 else
79 ent->size = pp->length;
80
81 return ent;
82}
83
84
85void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop)
86{
87 __proc_device_tree_add_prop(pde, prop, prop->name);
88}
89
90void proc_device_tree_remove_prop(struct proc_dir_entry *pde,
91 struct property *prop)
92{
93 remove_proc_entry(prop->name, pde);
94}
95
96void proc_device_tree_update_prop(struct proc_dir_entry *pde,
97 struct property *newprop,
98 struct property *oldprop)
99{
100 struct proc_dir_entry *ent;
101
102 if (!oldprop) {
103 proc_device_tree_add_prop(pde, newprop);
104 return;
105 }
106
107 for (ent = pde->subdir; ent != NULL; ent = ent->next)
108 if (ent->data == oldprop)
109 break;
110 if (ent == NULL) {
111 pr_warn("device-tree: property \"%s\" does not exist\n",
112 oldprop->name);
113 } else {
114 ent->data = newprop;
115 ent->size = newprop->length;
116 }
117}
118
119/*
120 * Various dodgy firmware might give us nodes and/or properties with
121 * conflicting names. That's generally ok, except for exporting via /proc,
122 * so munge names here to ensure they're unique.
123 */
124
125static int duplicate_name(struct proc_dir_entry *de, const char *name)
126{
127 struct proc_dir_entry *ent;
128 int found = 0;
129
130 spin_lock(&proc_subdir_lock);
131
132 for (ent = de->subdir; ent != NULL; ent = ent->next) {
133 if (strcmp(ent->name, name) == 0) {
134 found = 1;
135 break;
136 }
137 }
138
139 spin_unlock(&proc_subdir_lock);
140
141 return found;
142}
143
144static const char *fixup_name(struct device_node *np, struct proc_dir_entry *de,
145 const char *name)
146{
147 char *fixed_name;
148 int fixup_len = strlen(name) + 2 + 1; /* name + #x + \0 */
149 int i = 1, size;
150
151realloc:
152 fixed_name = kmalloc(fixup_len, GFP_KERNEL);
153 if (fixed_name == NULL) {
154 pr_err("device-tree: Out of memory trying to fixup "
155 "name \"%s\"\n", name);
156 return name;
157 }
158
159retry:
160 size = snprintf(fixed_name, fixup_len, "%s#%d", name, i);
161 size++; /* account for NULL */
162
163 if (size > fixup_len) {
164 /* We ran out of space, free and reallocate. */
165 kfree(fixed_name);
166 fixup_len = size;
167 goto realloc;
168 }
169
170 if (duplicate_name(de, fixed_name)) {
171 /* Multiple duplicates. Retry with a different offset. */
172 i++;
173 goto retry;
174 }
175
176 pr_warn("device-tree: Duplicate name in %s, renamed to \"%s\"\n",
177 np->full_name, fixed_name);
178
179 return fixed_name;
180}
181
182/*
183 * Process a node, adding entries for its children and its properties.
184 */
185void proc_device_tree_add_node(struct device_node *np,
186 struct proc_dir_entry *de)
187{
188 struct property *pp;
189 struct proc_dir_entry *ent;
190 struct device_node *child;
191 const char *p;
192
193 set_node_proc_entry(np, de);
194 for (child = NULL; (child = of_get_next_child(np, child));) {
195 /* Use everything after the last slash, or the full name */
196 p = kbasename(child->full_name);
197
198 if (duplicate_name(de, p))
199 p = fixup_name(np, de, p);
200
201 ent = proc_mkdir(p, de);
202 if (ent == NULL)
203 break;
204 proc_device_tree_add_node(child, ent);
205 }
206 of_node_put(child);
207
208 for (pp = np->properties; pp != NULL; pp = pp->next) {
209 p = pp->name;
210
211 if (strchr(p, '/'))
212 continue;
213
214 if (duplicate_name(de, p))
215 p = fixup_name(np, de, p);
216
217 ent = __proc_device_tree_add_prop(de, pp, p);
218 if (ent == NULL)
219 break;
220 }
221}
222
223/*
224 * Called on initialization to set up the /proc/device-tree subtree
225 */
226void __init proc_device_tree_init(void)
227{
228 struct device_node *root;
229
230 proc_device_tree = proc_mkdir("device-tree", NULL);
231 if (proc_device_tree == NULL)
232 return;
233 root = of_find_node_by_path("/");
234 if (root == NULL) {
235 pr_debug("/proc/device-tree: can't find root\n");
236 return;
237 }
238 proc_device_tree_add_node(root, proc_device_tree);
239 of_node_put(root);
240}
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 87dbcbef7fe4..5dbadecb234d 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -92,6 +92,8 @@ static int proc_parse_options(char *options, struct pid_namespace *pid)
92int proc_remount(struct super_block *sb, int *flags, char *data) 92int proc_remount(struct super_block *sb, int *flags, char *data)
93{ 93{
94 struct pid_namespace *pid = sb->s_fs_info; 94 struct pid_namespace *pid = sb->s_fs_info;
95
96 sync_filesystem(sb);
95 return !proc_parse_options(data, pid); 97 return !proc_parse_options(data, pid);
96} 98}
97 99
@@ -183,9 +185,6 @@ void __init proc_root_init(void)
183 proc_mkdir("openprom", NULL); 185 proc_mkdir("openprom", NULL);
184#endif 186#endif
185 proc_tty_init(); 187 proc_tty_init();
186#ifdef CONFIG_PROC_DEVICETREE
187 proc_device_tree_init();
188#endif
189 proc_mkdir("bus", NULL); 188 proc_mkdir("bus", NULL);
190 proc_sys_init(); 189 proc_sys_init();
191} 190}
diff --git a/fs/proc/softirqs.c b/fs/proc/softirqs.c
index 62604be9f58d..ad8a77f94beb 100644
--- a/fs/proc/softirqs.c
+++ b/fs/proc/softirqs.c
@@ -41,4 +41,4 @@ static int __init proc_softirqs_init(void)
41 proc_create("softirqs", 0, NULL, &proc_softirqs_operations); 41 proc_create("softirqs", 0, NULL, &proc_softirqs_operations);
42 return 0; 42 return 0;
43} 43}
44module_init(proc_softirqs_init); 44fs_initcall(proc_softirqs_init);
diff --git a/fs/proc/stat.c b/fs/proc/stat.c
index 1cf86c0e8689..9d231e9e5f0e 100644
--- a/fs/proc/stat.c
+++ b/fs/proc/stat.c
@@ -9,7 +9,7 @@
9#include <linux/slab.h> 9#include <linux/slab.h>
10#include <linux/time.h> 10#include <linux/time.h>
11#include <linux/irqnr.h> 11#include <linux/irqnr.h>
12#include <asm/cputime.h> 12#include <linux/cputime.h>
13#include <linux/tick.h> 13#include <linux/tick.h>
14 14
15#ifndef arch_irq_stat_cpu 15#ifndef arch_irq_stat_cpu
@@ -221,4 +221,4 @@ static int __init proc_stat_init(void)
221 proc_create("stat", 0, NULL, &proc_stat_operations); 221 proc_create("stat", 0, NULL, &proc_stat_operations);
222 return 0; 222 return 0;
223} 223}
224module_init(proc_stat_init); 224fs_initcall(proc_stat_init);
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index fb52b548080d..442177b1119a 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -1,4 +1,5 @@
1#include <linux/mm.h> 1#include <linux/mm.h>
2#include <linux/vmacache.h>
2#include <linux/hugetlb.h> 3#include <linux/hugetlb.h>
3#include <linux/huge_mm.h> 4#include <linux/huge_mm.h>
4#include <linux/mount.h> 5#include <linux/mount.h>
@@ -152,7 +153,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
152 153
153 /* 154 /*
154 * We remember last_addr rather than next_addr to hit with 155 * We remember last_addr rather than next_addr to hit with
155 * mmap_cache most of the time. We have zero last_addr at 156 * vmacache most of the time. We have zero last_addr at
156 * the beginning and also after lseek. We will have -1 last_addr 157 * the beginning and also after lseek. We will have -1 last_addr
157 * after the end of the vmas. 158 * after the end of the vmas.
158 */ 159 */
diff --git a/fs/proc/uptime.c b/fs/proc/uptime.c
index 061894625903..33de567c25af 100644
--- a/fs/proc/uptime.c
+++ b/fs/proc/uptime.c
@@ -5,7 +5,7 @@
5#include <linux/seq_file.h> 5#include <linux/seq_file.h>
6#include <linux/time.h> 6#include <linux/time.h>
7#include <linux/kernel_stat.h> 7#include <linux/kernel_stat.h>
8#include <asm/cputime.h> 8#include <linux/cputime.h>
9 9
10static int uptime_proc_show(struct seq_file *m, void *v) 10static int uptime_proc_show(struct seq_file *m, void *v)
11{ 11{
@@ -49,4 +49,4 @@ static int __init proc_uptime_init(void)
49 proc_create("uptime", 0, NULL, &uptime_proc_fops); 49 proc_create("uptime", 0, NULL, &uptime_proc_fops);
50 return 0; 50 return 0;
51} 51}
52module_init(proc_uptime_init); 52fs_initcall(proc_uptime_init);
diff --git a/fs/proc/version.c b/fs/proc/version.c
index 76817a60678c..d2154eb6d78f 100644
--- a/fs/proc/version.c
+++ b/fs/proc/version.c
@@ -31,4 +31,4 @@ static int __init proc_version_init(void)
31 proc_create("version", 0, NULL, &version_proc_fops); 31 proc_create("version", 0, NULL, &version_proc_fops);
32 return 0; 32 return 0;
33} 33}
34module_init(proc_version_init); 34fs_initcall(proc_version_init);
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index 9100d6959886..6a8e785b29da 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -468,17 +468,23 @@ static int __init update_note_header_size_elf64(const Elf64_Ehdr *ehdr_ptr)
468 return rc; 468 return rc;
469 } 469 }
470 nhdr_ptr = notes_section; 470 nhdr_ptr = notes_section;
471 while (real_sz < max_sz) { 471 while (nhdr_ptr->n_namesz != 0) {
472 if (nhdr_ptr->n_namesz == 0)
473 break;
474 sz = sizeof(Elf64_Nhdr) + 472 sz = sizeof(Elf64_Nhdr) +
475 ((nhdr_ptr->n_namesz + 3) & ~3) + 473 ((nhdr_ptr->n_namesz + 3) & ~3) +
476 ((nhdr_ptr->n_descsz + 3) & ~3); 474 ((nhdr_ptr->n_descsz + 3) & ~3);
475 if ((real_sz + sz) > max_sz) {
476 pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n",
477 nhdr_ptr->n_namesz, nhdr_ptr->n_descsz);
478 break;
479 }
477 real_sz += sz; 480 real_sz += sz;
478 nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz); 481 nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz);
479 } 482 }
480 kfree(notes_section); 483 kfree(notes_section);
481 phdr_ptr->p_memsz = real_sz; 484 phdr_ptr->p_memsz = real_sz;
485 if (real_sz == 0) {
486 pr_warn("Warning: Zero PT_NOTE entries found\n");
487 }
482 } 488 }
483 489
484 return 0; 490 return 0;
@@ -648,17 +654,23 @@ static int __init update_note_header_size_elf32(const Elf32_Ehdr *ehdr_ptr)
648 return rc; 654 return rc;
649 } 655 }
650 nhdr_ptr = notes_section; 656 nhdr_ptr = notes_section;
651 while (real_sz < max_sz) { 657 while (nhdr_ptr->n_namesz != 0) {
652 if (nhdr_ptr->n_namesz == 0)
653 break;
654 sz = sizeof(Elf32_Nhdr) + 658 sz = sizeof(Elf32_Nhdr) +
655 ((nhdr_ptr->n_namesz + 3) & ~3) + 659 ((nhdr_ptr->n_namesz + 3) & ~3) +
656 ((nhdr_ptr->n_descsz + 3) & ~3); 660 ((nhdr_ptr->n_descsz + 3) & ~3);
661 if ((real_sz + sz) > max_sz) {
662 pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n",
663 nhdr_ptr->n_namesz, nhdr_ptr->n_descsz);
664 break;
665 }
657 real_sz += sz; 666 real_sz += sz;
658 nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz); 667 nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz);
659 } 668 }
660 kfree(notes_section); 669 kfree(notes_section);
661 phdr_ptr->p_memsz = real_sz; 670 phdr_ptr->p_memsz = real_sz;
671 if (real_sz == 0) {
672 pr_warn("Warning: Zero PT_NOTE entries found\n");
673 }
662 } 674 }
663 675
664 return 0; 676 return 0;
@@ -1082,7 +1094,7 @@ static int __init vmcore_init(void)
1082 proc_vmcore->size = vmcore_size; 1094 proc_vmcore->size = vmcore_size;
1083 return 0; 1095 return 0;
1084} 1096}
1085module_init(vmcore_init) 1097fs_initcall(vmcore_init);
1086 1098
1087/* Cleanup function for vmcore module. */ 1099/* Cleanup function for vmcore module. */
1088void vmcore_cleanup(void) 1100void vmcore_cleanup(void)
@@ -1104,4 +1116,3 @@ void vmcore_cleanup(void)
1104 } 1116 }
1105 free_elfcorebuf(); 1117 free_elfcorebuf();
1106} 1118}
1107EXPORT_SYMBOL_GPL(vmcore_cleanup);