]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - fs/proc/proc_misc.c
proc: move /proc/execdomains to kernel/exec_domain.c
[linux-2.6-omap-h63xx.git] / fs / proc / proc_misc.c
1 /*
2  *  linux/fs/proc/proc_misc.c
3  *
4  *  linux/fs/proc/array.c
5  *  Copyright (C) 1992  by Linus Torvalds
6  *  based on ideas by Darren Senn
7  *
8  *  This used to be the part of array.c. See the rest of history and credits
9  *  there. I took this into a separate file and switched the thing to generic
10  *  proc_file_inode_operations, leaving in array.c only per-process stuff.
11  *  Inumbers allocation made dynamic (via create_proc_entry()).  AV, May 1999.
12  *
13  * Changes:
14  * Fulton Green      :  Encapsulated position metric calculations.
15  *                      <kernel@FultonGreen.com>
16  */
17
18 #include <linux/types.h>
19 #include <linux/errno.h>
20 #include <linux/time.h>
21 #include <linux/kernel.h>
22 #include <linux/kernel_stat.h>
23 #include <linux/fs.h>
24 #include <linux/tty.h>
25 #include <linux/string.h>
26 #include <linux/mman.h>
27 #include <linux/quicklist.h>
28 #include <linux/proc_fs.h>
29 #include <linux/ioport.h>
30 #include <linux/mm.h>
31 #include <linux/mmzone.h>
32 #include <linux/pagemap.h>
33 #include <linux/irq.h>
34 #include <linux/interrupt.h>
35 #include <linux/swap.h>
36 #include <linux/slab.h>
37 #include <linux/genhd.h>
38 #include <linux/smp.h>
39 #include <linux/signal.h>
40 #include <linux/module.h>
41 #include <linux/init.h>
42 #include <linux/seq_file.h>
43 #include <linux/times.h>
44 #include <linux/profile.h>
45 #include <linux/utsname.h>
46 #include <linux/blkdev.h>
47 #include <linux/hugetlb.h>
48 #include <linux/jiffies.h>
49 #include <linux/vmalloc.h>
50 #include <linux/crash_dump.h>
51 #include <linux/pid_namespace.h>
52 #include <linux/bootmem.h>
53 #include <asm/uaccess.h>
54 #include <asm/pgtable.h>
55 #include <asm/io.h>
56 #include <asm/tlb.h>
57 #include <asm/div64.h>
58 #include "internal.h"
59
60 /*
61  * Warning: stuff below (imported functions) assumes that its output will fit
62  * into one page. For some of those functions it may be wrong. Moreover, we
63  * have a way to deal with that gracefully. Right now I used straightforward
64  * wrappers, but this needs further analysis wrt potential overflows.
65  */
66
67 static int proc_calc_metrics(char *page, char **start, off_t off,
68                                  int count, int *eof, int len)
69 {
70         if (len <= off+count) *eof = 1;
71         *start = page + off;
72         len -= off;
73         if (len>count) len = count;
74         if (len<0) len = 0;
75         return len;
76 }
77
78 static int fragmentation_open(struct inode *inode, struct file *file)
79 {
80         (void)inode;
81         return seq_open(file, &fragmentation_op);
82 }
83
84 static const struct file_operations fragmentation_file_operations = {
85         .open           = fragmentation_open,
86         .read           = seq_read,
87         .llseek         = seq_lseek,
88         .release        = seq_release,
89 };
90
91 static int pagetypeinfo_open(struct inode *inode, struct file *file)
92 {
93         return seq_open(file, &pagetypeinfo_op);
94 }
95
96 static const struct file_operations pagetypeinfo_file_ops = {
97         .open           = pagetypeinfo_open,
98         .read           = seq_read,
99         .llseek         = seq_lseek,
100         .release        = seq_release,
101 };
102
103 static int zoneinfo_open(struct inode *inode, struct file *file)
104 {
105         return seq_open(file, &zoneinfo_op);
106 }
107
108 static const struct file_operations proc_zoneinfo_file_operations = {
109         .open           = zoneinfo_open,
110         .read           = seq_read,
111         .llseek         = seq_lseek,
112         .release        = seq_release,
113 };
114
115 extern const struct seq_operations cpuinfo_op;
116 static int cpuinfo_open(struct inode *inode, struct file *file)
117 {
118         return seq_open(file, &cpuinfo_op);
119 }
120
121 static const struct file_operations proc_cpuinfo_operations = {
122         .open           = cpuinfo_open,
123         .read           = seq_read,
124         .llseek         = seq_lseek,
125         .release        = seq_release,
126 };
127
128 static int devinfo_show(struct seq_file *f, void *v)
129 {
130         int i = *(loff_t *) v;
131
132         if (i < CHRDEV_MAJOR_HASH_SIZE) {
133                 if (i == 0)
134                         seq_printf(f, "Character devices:\n");
135                 chrdev_show(f, i);
136         }
137 #ifdef CONFIG_BLOCK
138         else {
139                 i -= CHRDEV_MAJOR_HASH_SIZE;
140                 if (i == 0)
141                         seq_printf(f, "\nBlock devices:\n");
142                 blkdev_show(f, i);
143         }
144 #endif
145         return 0;
146 }
147
148 static void *devinfo_start(struct seq_file *f, loff_t *pos)
149 {
150         if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
151                 return pos;
152         return NULL;
153 }
154
155 static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
156 {
157         (*pos)++;
158         if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
159                 return NULL;
160         return pos;
161 }
162
163 static void devinfo_stop(struct seq_file *f, void *v)
164 {
165         /* Nothing to do */
166 }
167
168 static const struct seq_operations devinfo_ops = {
169         .start = devinfo_start,
170         .next  = devinfo_next,
171         .stop  = devinfo_stop,
172         .show  = devinfo_show
173 };
174
175 static int devinfo_open(struct inode *inode, struct file *filp)
176 {
177         return seq_open(filp, &devinfo_ops);
178 }
179
180 static const struct file_operations proc_devinfo_operations = {
181         .open           = devinfo_open,
182         .read           = seq_read,
183         .llseek         = seq_lseek,
184         .release        = seq_release,
185 };
186
187 static int vmstat_open(struct inode *inode, struct file *file)
188 {
189         return seq_open(file, &vmstat_op);
190 }
191 static const struct file_operations proc_vmstat_file_operations = {
192         .open           = vmstat_open,
193         .read           = seq_read,
194         .llseek         = seq_lseek,
195         .release        = seq_release,
196 };
197
198 #ifdef CONFIG_BLOCK
199 static int partitions_open(struct inode *inode, struct file *file)
200 {
201         return seq_open(file, &partitions_op);
202 }
203 static const struct file_operations proc_partitions_operations = {
204         .open           = partitions_open,
205         .read           = seq_read,
206         .llseek         = seq_lseek,
207         .release        = seq_release,
208 };
209
210 static int diskstats_open(struct inode *inode, struct file *file)
211 {
212         return seq_open(file, &diskstats_op);
213 }
214 static const struct file_operations proc_diskstats_operations = {
215         .open           = diskstats_open,
216         .read           = seq_read,
217         .llseek         = seq_lseek,
218         .release        = seq_release,
219 };
220 #endif
221
222 #ifdef CONFIG_MODULES
223 extern const struct seq_operations modules_op;
224 static int modules_open(struct inode *inode, struct file *file)
225 {
226         return seq_open(file, &modules_op);
227 }
228 static const struct file_operations proc_modules_operations = {
229         .open           = modules_open,
230         .read           = seq_read,
231         .llseek         = seq_lseek,
232         .release        = seq_release,
233 };
234 #endif
235
236 #ifdef CONFIG_SLABINFO
237 static int slabinfo_open(struct inode *inode, struct file *file)
238 {
239         return seq_open(file, &slabinfo_op);
240 }
241 static const struct file_operations proc_slabinfo_operations = {
242         .open           = slabinfo_open,
243         .read           = seq_read,
244         .write          = slabinfo_write,
245         .llseek         = seq_lseek,
246         .release        = seq_release,
247 };
248
249 #ifdef CONFIG_DEBUG_SLAB_LEAK
250 extern const struct seq_operations slabstats_op;
251 static int slabstats_open(struct inode *inode, struct file *file)
252 {
253         unsigned long *n = kzalloc(PAGE_SIZE, GFP_KERNEL);
254         int ret = -ENOMEM;
255         if (n) {
256                 ret = seq_open(file, &slabstats_op);
257                 if (!ret) {
258                         struct seq_file *m = file->private_data;
259                         *n = PAGE_SIZE / (2 * sizeof(unsigned long));
260                         m->private = n;
261                         n = NULL;
262                 }
263                 kfree(n);
264         }
265         return ret;
266 }
267
268 static const struct file_operations proc_slabstats_operations = {
269         .open           = slabstats_open,
270         .read           = seq_read,
271         .llseek         = seq_lseek,
272         .release        = seq_release_private,
273 };
274 #endif
275 #endif
276
277 #ifdef CONFIG_MMU
278 static int vmalloc_open(struct inode *inode, struct file *file)
279 {
280         unsigned int *ptr = NULL;
281         int ret;
282
283         if (NUMA_BUILD)
284                 ptr = kmalloc(nr_node_ids * sizeof(unsigned int), GFP_KERNEL);
285         ret = seq_open(file, &vmalloc_op);
286         if (!ret) {
287                 struct seq_file *m = file->private_data;
288                 m->private = ptr;
289         } else
290                 kfree(ptr);
291         return ret;
292 }
293
294 static const struct file_operations proc_vmalloc_operations = {
295         .open           = vmalloc_open,
296         .read           = seq_read,
297         .llseek         = seq_lseek,
298         .release        = seq_release_private,
299 };
300 #endif
301
302 #ifndef arch_irq_stat_cpu
303 #define arch_irq_stat_cpu(cpu) 0
304 #endif
305 #ifndef arch_irq_stat
306 #define arch_irq_stat() 0
307 #endif
308
309 static int show_stat(struct seq_file *p, void *v)
310 {
311         int i, j;
312         unsigned long jif;
313         cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
314         cputime64_t guest;
315         u64 sum = 0;
316         struct timespec boottime;
317         unsigned int per_irq_sum;
318
319         user = nice = system = idle = iowait =
320                 irq = softirq = steal = cputime64_zero;
321         guest = cputime64_zero;
322         getboottime(&boottime);
323         jif = boottime.tv_sec;
324
325         for_each_possible_cpu(i) {
326                 user = cputime64_add(user, kstat_cpu(i).cpustat.user);
327                 nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
328                 system = cputime64_add(system, kstat_cpu(i).cpustat.system);
329                 idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle);
330                 iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait);
331                 irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);
332                 softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
333                 steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
334                 guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
335
336                 for_each_irq_nr(j)
337                         sum += kstat_irqs_cpu(j, i);
338
339                 sum += arch_irq_stat_cpu(i);
340         }
341         sum += arch_irq_stat();
342
343         seq_printf(p, "cpu  %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
344                 (unsigned long long)cputime64_to_clock_t(user),
345                 (unsigned long long)cputime64_to_clock_t(nice),
346                 (unsigned long long)cputime64_to_clock_t(system),
347                 (unsigned long long)cputime64_to_clock_t(idle),
348                 (unsigned long long)cputime64_to_clock_t(iowait),
349                 (unsigned long long)cputime64_to_clock_t(irq),
350                 (unsigned long long)cputime64_to_clock_t(softirq),
351                 (unsigned long long)cputime64_to_clock_t(steal),
352                 (unsigned long long)cputime64_to_clock_t(guest));
353         for_each_online_cpu(i) {
354
355                 /* Copy values here to work around gcc-2.95.3, gcc-2.96 */
356                 user = kstat_cpu(i).cpustat.user;
357                 nice = kstat_cpu(i).cpustat.nice;
358                 system = kstat_cpu(i).cpustat.system;
359                 idle = kstat_cpu(i).cpustat.idle;
360                 iowait = kstat_cpu(i).cpustat.iowait;
361                 irq = kstat_cpu(i).cpustat.irq;
362                 softirq = kstat_cpu(i).cpustat.softirq;
363                 steal = kstat_cpu(i).cpustat.steal;
364                 guest = kstat_cpu(i).cpustat.guest;
365                 seq_printf(p,
366                         "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
367                         i,
368                         (unsigned long long)cputime64_to_clock_t(user),
369                         (unsigned long long)cputime64_to_clock_t(nice),
370                         (unsigned long long)cputime64_to_clock_t(system),
371                         (unsigned long long)cputime64_to_clock_t(idle),
372                         (unsigned long long)cputime64_to_clock_t(iowait),
373                         (unsigned long long)cputime64_to_clock_t(irq),
374                         (unsigned long long)cputime64_to_clock_t(softirq),
375                         (unsigned long long)cputime64_to_clock_t(steal),
376                         (unsigned long long)cputime64_to_clock_t(guest));
377         }
378         seq_printf(p, "intr %llu", (unsigned long long)sum);
379
380         /* sum again ? it could be updated? */
381         for_each_irq_nr(j) {
382                 per_irq_sum = 0;
383
384                 for_each_possible_cpu(i)
385                         per_irq_sum += kstat_irqs_cpu(j, i);
386
387                 seq_printf(p, " %u", per_irq_sum);
388         }
389
390         seq_printf(p,
391                 "\nctxt %llu\n"
392                 "btime %lu\n"
393                 "processes %lu\n"
394                 "procs_running %lu\n"
395                 "procs_blocked %lu\n",
396                 nr_context_switches(),
397                 (unsigned long)jif,
398                 total_forks,
399                 nr_running(),
400                 nr_iowait());
401
402         return 0;
403 }
404
405 static int stat_open(struct inode *inode, struct file *file)
406 {
407         unsigned size = 4096 * (1 + num_possible_cpus() / 32);
408         char *buf;
409         struct seq_file *m;
410         int res;
411
412         /* don't ask for more than the kmalloc() max size, currently 128 KB */
413         if (size > 128 * 1024)
414                 size = 128 * 1024;
415         buf = kmalloc(size, GFP_KERNEL);
416         if (!buf)
417                 return -ENOMEM;
418
419         res = single_open(file, show_stat, NULL);
420         if (!res) {
421                 m = file->private_data;
422                 m->buf = buf;
423                 m->size = size;
424         } else
425                 kfree(buf);
426         return res;
427 }
428 static const struct file_operations proc_stat_operations = {
429         .open           = stat_open,
430         .read           = seq_read,
431         .llseek         = seq_lseek,
432         .release        = single_release,
433 };
434
435 /*
436  * /proc/interrupts
437  */
438 static void *int_seq_start(struct seq_file *f, loff_t *pos)
439 {
440         return (*pos <= nr_irqs) ? pos : NULL;
441 }
442
443
444 static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos)
445 {
446         (*pos)++;
447         return (*pos <= nr_irqs) ? pos : NULL;
448 }
449
450 static void int_seq_stop(struct seq_file *f, void *v)
451 {
452         /* Nothing to do */
453 }
454
455 static const struct seq_operations int_seq_ops = {
456         .start = int_seq_start,
457         .next  = int_seq_next,
458         .stop  = int_seq_stop,
459         .show  = show_interrupts
460 };
461
462 static int interrupts_open(struct inode *inode, struct file *filp)
463 {
464         return seq_open(filp, &int_seq_ops);
465 }
466
467 static const struct file_operations proc_interrupts_operations = {
468         .open           = interrupts_open,
469         .read           = seq_read,
470         .llseek         = seq_lseek,
471         .release        = seq_release,
472 };
473
474 #ifdef CONFIG_FILE_LOCKING
475 static int locks_open(struct inode *inode, struct file *filp)
476 {
477         return seq_open(filp, &locks_seq_operations);
478 }
479
480 static const struct file_operations proc_locks_operations = {
481         .open           = locks_open,
482         .read           = seq_read,
483         .llseek         = seq_lseek,
484         .release        = seq_release,
485 };
486 #endif /* CONFIG_FILE_LOCKING */
487
488 #ifdef CONFIG_PROC_PAGE_MONITOR
489 #define KPMSIZE sizeof(u64)
490 #define KPMMASK (KPMSIZE - 1)
491 /* /proc/kpagecount - an array exposing page counts
492  *
493  * Each entry is a u64 representing the corresponding
494  * physical page count.
495  */
496 static ssize_t kpagecount_read(struct file *file, char __user *buf,
497                              size_t count, loff_t *ppos)
498 {
499         u64 __user *out = (u64 __user *)buf;
500         struct page *ppage;
501         unsigned long src = *ppos;
502         unsigned long pfn;
503         ssize_t ret = 0;
504         u64 pcount;
505
506         pfn = src / KPMSIZE;
507         count = min_t(size_t, count, (max_pfn * KPMSIZE) - src);
508         if (src & KPMMASK || count & KPMMASK)
509                 return -EINVAL;
510
511         while (count > 0) {
512                 ppage = NULL;
513                 if (pfn_valid(pfn))
514                         ppage = pfn_to_page(pfn);
515                 pfn++;
516                 if (!ppage)
517                         pcount = 0;
518                 else
519                         pcount = page_mapcount(ppage);
520
521                 if (put_user(pcount, out++)) {
522                         ret = -EFAULT;
523                         break;
524                 }
525
526                 count -= KPMSIZE;
527         }
528
529         *ppos += (char __user *)out - buf;
530         if (!ret)
531                 ret = (char __user *)out - buf;
532         return ret;
533 }
534
535 static struct file_operations proc_kpagecount_operations = {
536         .llseek = mem_lseek,
537         .read = kpagecount_read,
538 };
539
540 /* /proc/kpageflags - an array exposing page flags
541  *
542  * Each entry is a u64 representing the corresponding
543  * physical page flags.
544  */
545
546 /* These macros are used to decouple internal flags from exported ones */
547
548 #define KPF_LOCKED     0
549 #define KPF_ERROR      1
550 #define KPF_REFERENCED 2
551 #define KPF_UPTODATE   3
552 #define KPF_DIRTY      4
553 #define KPF_LRU        5
554 #define KPF_ACTIVE     6
555 #define KPF_SLAB       7
556 #define KPF_WRITEBACK  8
557 #define KPF_RECLAIM    9
558 #define KPF_BUDDY     10
559
560 #define kpf_copy_bit(flags, srcpos, dstpos) (((flags >> srcpos) & 1) << dstpos)
561
562 static ssize_t kpageflags_read(struct file *file, char __user *buf,
563                              size_t count, loff_t *ppos)
564 {
565         u64 __user *out = (u64 __user *)buf;
566         struct page *ppage;
567         unsigned long src = *ppos;
568         unsigned long pfn;
569         ssize_t ret = 0;
570         u64 kflags, uflags;
571
572         pfn = src / KPMSIZE;
573         count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
574         if (src & KPMMASK || count & KPMMASK)
575                 return -EINVAL;
576
577         while (count > 0) {
578                 ppage = NULL;
579                 if (pfn_valid(pfn))
580                         ppage = pfn_to_page(pfn);
581                 pfn++;
582                 if (!ppage)
583                         kflags = 0;
584                 else
585                         kflags = ppage->flags;
586
587                 uflags = kpf_copy_bit(KPF_LOCKED, PG_locked, kflags) |
588                         kpf_copy_bit(kflags, KPF_ERROR, PG_error) |
589                         kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) |
590                         kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) |
591                         kpf_copy_bit(kflags, KPF_DIRTY, PG_dirty) |
592                         kpf_copy_bit(kflags, KPF_LRU, PG_lru) |
593                         kpf_copy_bit(kflags, KPF_ACTIVE, PG_active) |
594                         kpf_copy_bit(kflags, KPF_SLAB, PG_slab) |
595                         kpf_copy_bit(kflags, KPF_WRITEBACK, PG_writeback) |
596                         kpf_copy_bit(kflags, KPF_RECLAIM, PG_reclaim) |
597                         kpf_copy_bit(kflags, KPF_BUDDY, PG_buddy);
598
599                 if (put_user(uflags, out++)) {
600                         ret = -EFAULT;
601                         break;
602                 }
603
604                 count -= KPMSIZE;
605         }
606
607         *ppos += (char __user *)out - buf;
608         if (!ret)
609                 ret = (char __user *)out - buf;
610         return ret;
611 }
612
613 static struct file_operations proc_kpageflags_operations = {
614         .llseek = mem_lseek,
615         .read = kpageflags_read,
616 };
617 #endif /* CONFIG_PROC_PAGE_MONITOR */
618
619 struct proc_dir_entry *proc_root_kcore;
620
621 void __init proc_misc_init(void)
622 {
623         static struct {
624                 char *name;
625                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
626         } *p, simple_ones[] = {
627                 {NULL,}
628         };
629         for (p = simple_ones; p->name; p++)
630                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
631
632         proc_symlink("mounts", NULL, "self/mounts");
633
634         /* And now for trickier ones */
635 #ifdef CONFIG_PRINTK
636         proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
637 #endif
638 #ifdef CONFIG_FILE_LOCKING
639         proc_create("locks", 0, NULL, &proc_locks_operations);
640 #endif
641         proc_create("devices", 0, NULL, &proc_devinfo_operations);
642         proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
643 #ifdef CONFIG_BLOCK
644         proc_create("partitions", 0, NULL, &proc_partitions_operations);
645 #endif
646         proc_create("stat", 0, NULL, &proc_stat_operations);
647         proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
648 #ifdef CONFIG_SLABINFO
649         proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
650 #ifdef CONFIG_DEBUG_SLAB_LEAK
651         proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
652 #endif
653 #endif
654 #ifdef CONFIG_MMU
655         proc_create("vmallocinfo", S_IRUSR, NULL, &proc_vmalloc_operations);
656 #endif
657         proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
658         proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops);
659         proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations);
660         proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations);
661 #ifdef CONFIG_BLOCK
662         proc_create("diskstats", 0, NULL, &proc_diskstats_operations);
663 #endif
664 #ifdef CONFIG_MODULES
665         proc_create("modules", 0, NULL, &proc_modules_operations);
666 #endif
667 #ifdef CONFIG_SCHEDSTATS
668         proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
669 #endif
670 #ifdef CONFIG_PROC_KCORE
671         proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
672         if (proc_root_kcore)
673                 proc_root_kcore->size =
674                                 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
675 #endif
676 #ifdef CONFIG_PROC_PAGE_MONITOR
677         proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations);
678         proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations);
679 #endif
680 #ifdef CONFIG_PROC_VMCORE
681         proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations);
682 #endif
683 }