aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/array.c2
-rw-r--r--fs/proc/base.c33
-rw-r--r--fs/proc/inode.c3
-rw-r--r--fs/proc/proc_misc.c24
-rw-r--r--fs/proc/task_mmu.c175
5 files changed, 146 insertions, 91 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 9e3b8c33c24b..797d775e0354 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -288,7 +288,7 @@ static void render_cap_t(struct seq_file *m, const char *header,
288 seq_printf(m, "%s", header); 288 seq_printf(m, "%s", header);
289 CAP_FOR_EACH_U32(__capi) { 289 CAP_FOR_EACH_U32(__capi) {
290 seq_printf(m, "%08x", 290 seq_printf(m, "%08x",
291 a->cap[(_LINUX_CAPABILITY_U32S-1) - __capi]); 291 a->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]);
292 } 292 }
293 seq_printf(m, "\n"); 293 seq_printf(m, "\n");
294} 294}
diff --git a/fs/proc/base.c b/fs/proc/base.c
index c447e0743a3c..3b455371e7ff 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -127,6 +127,25 @@ struct pid_entry {
127 NULL, &proc_single_file_operations, \ 127 NULL, &proc_single_file_operations, \
128 { .proc_show = &proc_##OTYPE } ) 128 { .proc_show = &proc_##OTYPE } )
129 129
130/*
131 * Count the number of hardlinks for the pid_entry table, excluding the .
132 * and .. links.
133 */
134static unsigned int pid_entry_count_dirs(const struct pid_entry *entries,
135 unsigned int n)
136{
137 unsigned int i;
138 unsigned int count;
139
140 count = 0;
141 for (i = 0; i < n; ++i) {
142 if (S_ISDIR(entries[i].mode))
143 ++count;
144 }
145
146 return count;
147}
148
130int maps_protect; 149int maps_protect;
131EXPORT_SYMBOL(maps_protect); 150EXPORT_SYMBOL(maps_protect);
132 151
@@ -2585,10 +2604,9 @@ static struct dentry *proc_pid_instantiate(struct inode *dir,
2585 inode->i_op = &proc_tgid_base_inode_operations; 2604 inode->i_op = &proc_tgid_base_inode_operations;
2586 inode->i_fop = &proc_tgid_base_operations; 2605 inode->i_fop = &proc_tgid_base_operations;
2587 inode->i_flags|=S_IMMUTABLE; 2606 inode->i_flags|=S_IMMUTABLE;
2588 inode->i_nlink = 5; 2607
2589#ifdef CONFIG_SECURITY 2608 inode->i_nlink = 2 + pid_entry_count_dirs(tgid_base_stuff,
2590 inode->i_nlink += 1; 2609 ARRAY_SIZE(tgid_base_stuff));
2591#endif
2592 2610
2593 dentry->d_op = &pid_dentry_operations; 2611 dentry->d_op = &pid_dentry_operations;
2594 2612
@@ -2816,10 +2834,9 @@ static struct dentry *proc_task_instantiate(struct inode *dir,
2816 inode->i_op = &proc_tid_base_inode_operations; 2834 inode->i_op = &proc_tid_base_inode_operations;
2817 inode->i_fop = &proc_tid_base_operations; 2835 inode->i_fop = &proc_tid_base_operations;
2818 inode->i_flags|=S_IMMUTABLE; 2836 inode->i_flags|=S_IMMUTABLE;
2819 inode->i_nlink = 4; 2837
2820#ifdef CONFIG_SECURITY 2838 inode->i_nlink = 2 + pid_entry_count_dirs(tid_base_stuff,
2821 inode->i_nlink += 1; 2839 ARRAY_SIZE(tid_base_stuff));
2822#endif
2823 2840
2824 dentry->d_op = &pid_dentry_operations; 2841 dentry->d_op = &pid_dentry_operations;
2825 2842
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 6f4e8dc97da1..b08d10017911 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -425,7 +425,8 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino,
425 } 425 }
426 } 426 }
427 unlock_new_inode(inode); 427 unlock_new_inode(inode);
428 } 428 } else
429 module_put(de->owner);
429 return inode; 430 return inode;
430 431
431out_ino: 432out_ino:
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 74a323d2b850..c652d469dc08 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -123,6 +123,11 @@ static int uptime_read_proc(char *page, char **start, off_t off,
123 return proc_calc_metrics(page, start, off, count, eof, len); 123 return proc_calc_metrics(page, start, off, count, eof, len);
124} 124}
125 125
126int __attribute__((weak)) arch_report_meminfo(char *page)
127{
128 return 0;
129}
130
126static int meminfo_read_proc(char *page, char **start, off_t off, 131static int meminfo_read_proc(char *page, char **start, off_t off,
127 int count, int *eof, void *data) 132 int count, int *eof, void *data)
128{ 133{
@@ -139,7 +144,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
139#define K(x) ((x) << (PAGE_SHIFT - 10)) 144#define K(x) ((x) << (PAGE_SHIFT - 10))
140 si_meminfo(&i); 145 si_meminfo(&i);
141 si_swapinfo(&i); 146 si_swapinfo(&i);
142 committed = atomic_read(&vm_committed_space); 147 committed = atomic_long_read(&vm_committed_space);
143 allowed = ((totalram_pages - hugetlb_total_pages()) 148 allowed = ((totalram_pages - hugetlb_total_pages())
144 * sysctl_overcommit_ratio / 100) + total_swap_pages; 149 * sysctl_overcommit_ratio / 100) + total_swap_pages;
145 150
@@ -221,6 +226,8 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
221 226
222 len += hugetlb_report_meminfo(page + len); 227 len += hugetlb_report_meminfo(page + len);
223 228
229 len += arch_report_meminfo(page + len);
230
224 return proc_calc_metrics(page, start, off, count, eof, len); 231 return proc_calc_metrics(page, start, off, count, eof, len);
225#undef K 232#undef K
226} 233}
@@ -472,6 +479,13 @@ static const struct file_operations proc_vmalloc_operations = {
472}; 479};
473#endif 480#endif
474 481
482#ifndef arch_irq_stat_cpu
483#define arch_irq_stat_cpu(cpu) 0
484#endif
485#ifndef arch_irq_stat
486#define arch_irq_stat() 0
487#endif
488
475static int show_stat(struct seq_file *p, void *v) 489static int show_stat(struct seq_file *p, void *v)
476{ 490{
477 int i; 491 int i;
@@ -509,7 +523,9 @@ static int show_stat(struct seq_file *p, void *v)
509 sum += temp; 523 sum += temp;
510 per_irq_sum[j] += temp; 524 per_irq_sum[j] += temp;
511 } 525 }
526 sum += arch_irq_stat_cpu(i);
512 } 527 }
528 sum += arch_irq_stat();
513 529
514 seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n", 530 seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
515 (unsigned long long)cputime64_to_clock_t(user), 531 (unsigned long long)cputime64_to_clock_t(user),
@@ -716,7 +732,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
716 pfn = src / KPMSIZE; 732 pfn = src / KPMSIZE;
717 count = min_t(size_t, count, (max_pfn * KPMSIZE) - src); 733 count = min_t(size_t, count, (max_pfn * KPMSIZE) - src);
718 if (src & KPMMASK || count & KPMMASK) 734 if (src & KPMMASK || count & KPMMASK)
719 return -EIO; 735 return -EINVAL;
720 736
721 while (count > 0) { 737 while (count > 0) {
722 ppage = NULL; 738 ppage = NULL;
@@ -726,7 +742,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
726 if (!ppage) 742 if (!ppage)
727 pcount = 0; 743 pcount = 0;
728 else 744 else
729 pcount = atomic_read(&ppage->_count); 745 pcount = page_mapcount(ppage);
730 746
731 if (put_user(pcount, out++)) { 747 if (put_user(pcount, out++)) {
732 ret = -EFAULT; 748 ret = -EFAULT;
@@ -782,7 +798,7 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf,
782 pfn = src / KPMSIZE; 798 pfn = src / KPMSIZE;
783 count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src); 799 count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
784 if (src & KPMMASK || count & KPMMASK) 800 if (src & KPMMASK || count & KPMMASK)
785 return -EIO; 801 return -EINVAL;
786 802
787 while (count > 0) { 803 while (count > 0) {
788 ppage = NULL; 804 ppage = NULL;
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 88717c0f941b..c492449f3b45 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -315,9 +315,9 @@ struct mem_size_stats {
315}; 315};
316 316
317static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, 317static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
318 void *private) 318 struct mm_walk *walk)
319{ 319{
320 struct mem_size_stats *mss = private; 320 struct mem_size_stats *mss = walk->private;
321 struct vm_area_struct *vma = mss->vma; 321 struct vm_area_struct *vma = mss->vma;
322 pte_t *pte, ptent; 322 pte_t *pte, ptent;
323 spinlock_t *ptl; 323 spinlock_t *ptl;
@@ -365,19 +365,21 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
365 return 0; 365 return 0;
366} 366}
367 367
368static struct mm_walk smaps_walk = { .pmd_entry = smaps_pte_range };
369
370static int show_smap(struct seq_file *m, void *v) 368static int show_smap(struct seq_file *m, void *v)
371{ 369{
372 struct vm_area_struct *vma = v; 370 struct vm_area_struct *vma = v;
373 struct mem_size_stats mss; 371 struct mem_size_stats mss;
374 int ret; 372 int ret;
373 struct mm_walk smaps_walk = {
374 .pmd_entry = smaps_pte_range,
375 .mm = vma->vm_mm,
376 .private = &mss,
377 };
375 378
376 memset(&mss, 0, sizeof mss); 379 memset(&mss, 0, sizeof mss);
377 mss.vma = vma; 380 mss.vma = vma;
378 if (vma->vm_mm && !is_vm_hugetlb_page(vma)) 381 if (vma->vm_mm && !is_vm_hugetlb_page(vma))
379 walk_page_range(vma->vm_mm, vma->vm_start, vma->vm_end, 382 walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
380 &smaps_walk, &mss);
381 383
382 ret = show_map(m, v); 384 ret = show_map(m, v);
383 if (ret) 385 if (ret)
@@ -426,9 +428,9 @@ const struct file_operations proc_smaps_operations = {
426}; 428};
427 429
428static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr, 430static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
429 unsigned long end, void *private) 431 unsigned long end, struct mm_walk *walk)
430{ 432{
431 struct vm_area_struct *vma = private; 433 struct vm_area_struct *vma = walk->private;
432 pte_t *pte, ptent; 434 pte_t *pte, ptent;
433 spinlock_t *ptl; 435 spinlock_t *ptl;
434 struct page *page; 436 struct page *page;
@@ -452,8 +454,6 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
452 return 0; 454 return 0;
453} 455}
454 456
455static struct mm_walk clear_refs_walk = { .pmd_entry = clear_refs_pte_range };
456
457static ssize_t clear_refs_write(struct file *file, const char __user *buf, 457static ssize_t clear_refs_write(struct file *file, const char __user *buf,
458 size_t count, loff_t *ppos) 458 size_t count, loff_t *ppos)
459{ 459{
@@ -476,11 +476,17 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
476 return -ESRCH; 476 return -ESRCH;
477 mm = get_task_mm(task); 477 mm = get_task_mm(task);
478 if (mm) { 478 if (mm) {
479 struct mm_walk clear_refs_walk = {
480 .pmd_entry = clear_refs_pte_range,
481 .mm = mm,
482 };
479 down_read(&mm->mmap_sem); 483 down_read(&mm->mmap_sem);
480 for (vma = mm->mmap; vma; vma = vma->vm_next) 484 for (vma = mm->mmap; vma; vma = vma->vm_next) {
485 clear_refs_walk.private = vma;
481 if (!is_vm_hugetlb_page(vma)) 486 if (!is_vm_hugetlb_page(vma))
482 walk_page_range(mm, vma->vm_start, vma->vm_end, 487 walk_page_range(vma->vm_start, vma->vm_end,
483 &clear_refs_walk, vma); 488 &clear_refs_walk);
489 }
484 flush_tlb_mm(mm); 490 flush_tlb_mm(mm);
485 up_read(&mm->mmap_sem); 491 up_read(&mm->mmap_sem);
486 mmput(mm); 492 mmput(mm);
@@ -496,7 +502,7 @@ const struct file_operations proc_clear_refs_operations = {
496}; 502};
497 503
498struct pagemapread { 504struct pagemapread {
499 char __user *out, *end; 505 u64 __user *out, *end;
500}; 506};
501 507
502#define PM_ENTRY_BYTES sizeof(u64) 508#define PM_ENTRY_BYTES sizeof(u64)
@@ -519,28 +525,18 @@ struct pagemapread {
519static int add_to_pagemap(unsigned long addr, u64 pfn, 525static int add_to_pagemap(unsigned long addr, u64 pfn,
520 struct pagemapread *pm) 526 struct pagemapread *pm)
521{ 527{
522 /*
523 * Make sure there's room in the buffer for an
524 * entire entry. Otherwise, only copy part of
525 * the pfn.
526 */
527 if (pm->out + PM_ENTRY_BYTES >= pm->end) {
528 if (copy_to_user(pm->out, &pfn, pm->end - pm->out))
529 return -EFAULT;
530 pm->out = pm->end;
531 return PM_END_OF_BUFFER;
532 }
533
534 if (put_user(pfn, pm->out)) 528 if (put_user(pfn, pm->out))
535 return -EFAULT; 529 return -EFAULT;
536 pm->out += PM_ENTRY_BYTES; 530 pm->out++;
531 if (pm->out >= pm->end)
532 return PM_END_OF_BUFFER;
537 return 0; 533 return 0;
538} 534}
539 535
540static int pagemap_pte_hole(unsigned long start, unsigned long end, 536static int pagemap_pte_hole(unsigned long start, unsigned long end,
541 void *private) 537 struct mm_walk *walk)
542{ 538{
543 struct pagemapread *pm = private; 539 struct pagemapread *pm = walk->private;
544 unsigned long addr; 540 unsigned long addr;
545 int err = 0; 541 int err = 0;
546 for (addr = start; addr < end; addr += PAGE_SIZE) { 542 for (addr = start; addr < end; addr += PAGE_SIZE) {
@@ -557,24 +553,45 @@ static u64 swap_pte_to_pagemap_entry(pte_t pte)
557 return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT); 553 return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT);
558} 554}
559 555
556static unsigned long pte_to_pagemap_entry(pte_t pte)
557{
558 unsigned long pme = 0;
559 if (is_swap_pte(pte))
560 pme = PM_PFRAME(swap_pte_to_pagemap_entry(pte))
561 | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP;
562 else if (pte_present(pte))
563 pme = PM_PFRAME(pte_pfn(pte))
564 | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT;
565 return pme;
566}
567
560static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, 568static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
561 void *private) 569 struct mm_walk *walk)
562{ 570{
563 struct pagemapread *pm = private; 571 struct vm_area_struct *vma;
572 struct pagemapread *pm = walk->private;
564 pte_t *pte; 573 pte_t *pte;
565 int err = 0; 574 int err = 0;
566 575
576 /* find the first VMA at or above 'addr' */
577 vma = find_vma(walk->mm, addr);
567 for (; addr != end; addr += PAGE_SIZE) { 578 for (; addr != end; addr += PAGE_SIZE) {
568 u64 pfn = PM_NOT_PRESENT; 579 u64 pfn = PM_NOT_PRESENT;
569 pte = pte_offset_map(pmd, addr); 580
570 if (is_swap_pte(*pte)) 581 /* check to see if we've left 'vma' behind
571 pfn = PM_PFRAME(swap_pte_to_pagemap_entry(*pte)) 582 * and need a new, higher one */
572 | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP; 583 if (vma && (addr >= vma->vm_end))
573 else if (pte_present(*pte)) 584 vma = find_vma(walk->mm, addr);
574 pfn = PM_PFRAME(pte_pfn(*pte)) 585
575 | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT; 586 /* check that 'vma' actually covers this address,
576 /* unmap so we're not in atomic when we copy to userspace */ 587 * and that it isn't a huge page vma */
577 pte_unmap(pte); 588 if (vma && (vma->vm_start <= addr) &&
589 !is_vm_hugetlb_page(vma)) {
590 pte = pte_offset_map(pmd, addr);
591 pfn = pte_to_pagemap_entry(*pte);
592 /* unmap before userspace copy */
593 pte_unmap(pte);
594 }
578 err = add_to_pagemap(addr, pfn, pm); 595 err = add_to_pagemap(addr, pfn, pm);
579 if (err) 596 if (err)
580 return err; 597 return err;
@@ -585,11 +602,6 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
585 return err; 602 return err;
586} 603}
587 604
588static struct mm_walk pagemap_walk = {
589 .pmd_entry = pagemap_pte_range,
590 .pte_hole = pagemap_pte_hole
591};
592
593/* 605/*
594 * /proc/pid/pagemap - an array mapping virtual pages to pfns 606 * /proc/pid/pagemap - an array mapping virtual pages to pfns
595 * 607 *
@@ -624,6 +636,11 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
624 struct pagemapread pm; 636 struct pagemapread pm;
625 int pagecount; 637 int pagecount;
626 int ret = -ESRCH; 638 int ret = -ESRCH;
639 struct mm_walk pagemap_walk;
640 unsigned long src;
641 unsigned long svpfn;
642 unsigned long start_vaddr;
643 unsigned long end_vaddr;
627 644
628 if (!task) 645 if (!task)
629 goto out; 646 goto out;
@@ -634,7 +651,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
634 651
635 ret = -EINVAL; 652 ret = -EINVAL;
636 /* file position must be aligned */ 653 /* file position must be aligned */
637 if (*ppos % PM_ENTRY_BYTES) 654 if ((*ppos % PM_ENTRY_BYTES) || (count % PM_ENTRY_BYTES))
638 goto out_task; 655 goto out_task;
639 656
640 ret = 0; 657 ret = 0;
@@ -642,11 +659,15 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
642 if (!mm) 659 if (!mm)
643 goto out_task; 660 goto out_task;
644 661
645 ret = -ENOMEM; 662
646 uaddr = (unsigned long)buf & PAGE_MASK; 663 uaddr = (unsigned long)buf & PAGE_MASK;
647 uend = (unsigned long)(buf + count); 664 uend = (unsigned long)(buf + count);
648 pagecount = (PAGE_ALIGN(uend) - uaddr) / PAGE_SIZE; 665 pagecount = (PAGE_ALIGN(uend) - uaddr) / PAGE_SIZE;
649 pages = kmalloc(pagecount * sizeof(struct page *), GFP_KERNEL); 666 ret = 0;
667 if (pagecount == 0)
668 goto out_mm;
669 pages = kcalloc(pagecount, sizeof(struct page *), GFP_KERNEL);
670 ret = -ENOMEM;
650 if (!pages) 671 if (!pages)
651 goto out_mm; 672 goto out_mm;
652 673
@@ -664,36 +685,36 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
664 goto out_pages; 685 goto out_pages;
665 } 686 }
666 687
667 pm.out = buf; 688 pm.out = (u64 *)buf;
668 pm.end = buf + count; 689 pm.end = (u64 *)(buf + count);
669 690
670 if (!ptrace_may_attach(task)) { 691 pagemap_walk.pmd_entry = pagemap_pte_range;
671 ret = -EIO; 692 pagemap_walk.pte_hole = pagemap_pte_hole;
672 } else { 693 pagemap_walk.mm = mm;
673 unsigned long src = *ppos; 694 pagemap_walk.private = &pm;
674 unsigned long svpfn = src / PM_ENTRY_BYTES; 695
675 unsigned long start_vaddr = svpfn << PAGE_SHIFT; 696 src = *ppos;
676 unsigned long end_vaddr = TASK_SIZE_OF(task); 697 svpfn = src / PM_ENTRY_BYTES;
677 698 start_vaddr = svpfn << PAGE_SHIFT;
678 /* watch out for wraparound */ 699 end_vaddr = TASK_SIZE_OF(task);
679 if (svpfn > TASK_SIZE_OF(task) >> PAGE_SHIFT) 700
680 start_vaddr = end_vaddr; 701 /* watch out for wraparound */
681 702 if (svpfn > TASK_SIZE_OF(task) >> PAGE_SHIFT)
682 /* 703 start_vaddr = end_vaddr;
683 * The odds are that this will stop walking way 704
684 * before end_vaddr, because the length of the 705 /*
685 * user buffer is tracked in "pm", and the walk 706 * The odds are that this will stop walking way
686 * will stop when we hit the end of the buffer. 707 * before end_vaddr, because the length of the
687 */ 708 * user buffer is tracked in "pm", and the walk
688 ret = walk_page_range(mm, start_vaddr, end_vaddr, 709 * will stop when we hit the end of the buffer.
689 &pagemap_walk, &pm); 710 */
690 if (ret == PM_END_OF_BUFFER) 711 ret = walk_page_range(start_vaddr, end_vaddr, &pagemap_walk);
691 ret = 0; 712 if (ret == PM_END_OF_BUFFER)
692 /* don't need mmap_sem for these, but this looks cleaner */ 713 ret = 0;
693 *ppos += pm.out - buf; 714 /* don't need mmap_sem for these, but this looks cleaner */
694 if (!ret) 715 *ppos += (char *)pm.out - buf;
695 ret = pm.out - buf; 716 if (!ret)
696 } 717 ret = (char *)pm.out - buf;
697 718
698out_pages: 719out_pages:
699 for (; pagecount; pagecount--) { 720 for (; pagecount; pagecount--) {