1 /* nommu.c: mmu-less memory info files 2 * 3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12 #include <linux/init.h> 13 #include <linux/module.h> 14 #include <linux/errno.h> 15 #include <linux/time.h> 16 #include <linux/kernel.h> 17 #include <linux/string.h> 18 #include <linux/mman.h> 19 #include <linux/proc_fs.h> 20 #include <linux/mm.h> 21 #include <linux/mmzone.h> 22 #include <linux/pagemap.h> 23 #include <linux/swap.h> 24 #include <linux/slab.h> 25 #include <linux/smp.h> 26 #include <linux/seq_file.h> 27 #include <linux/hugetlb.h> 28 #include <linux/vmalloc.h> 29 #include <asm/uaccess.h> 30 #include <asm/pgtable.h> 31 #include <asm/tlb.h> 32 #include <asm/div64.h> 33 #include "internal.h" 34 35 /* 36 * display a list of all the VMAs the kernel knows about 37 * - nommu kernals have a single flat list 38 */ 39 static int nommu_vma_list_show(struct seq_file *m, void *v) 40 { 41 struct vm_area_struct *vma; 42 unsigned long ino = 0; 43 struct file *file; 44 dev_t dev = 0; 45 int flags, len; 46 47 vma = rb_entry((struct rb_node *) v, struct vm_area_struct, vm_rb); 48 49 flags = vma->vm_flags; 50 file = vma->vm_file; 51 52 if (file) { 53 struct inode *inode = vma->vm_file->f_dentry->d_inode; 54 dev = inode->i_sb->s_dev; 55 ino = inode->i_ino; 56 } 57 58 seq_printf(m, 59 "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n", 60 vma->vm_start, 61 vma->vm_end, 62 flags & VM_READ ? 'r' : '-', 63 flags & VM_WRITE ? 'w' : '-', 64 flags & VM_EXEC ? 'x' : '-', 65 flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p', 66 vma->vm_pgoff << PAGE_SHIFT, 67 MAJOR(dev), MINOR(dev), ino, &len); 68 69 if (file) { 70 len = 25 + sizeof(void *) * 6 - len; 71 if (len < 1) 72 len = 1; 73 seq_printf(m, "%*c", len, ' '); 74 seq_path(m, file->f_vfsmnt, file->f_dentry, ""); 75 } 76 77 seq_putc(m, '\n'); 78 return 0; 79 } 80 81 static void *nommu_vma_list_start(struct seq_file *m, loff_t *_pos) 82 { 83 struct rb_node *_rb; 84 loff_t pos = *_pos; 85 void *next = NULL; 86 87 down_read(&nommu_vma_sem); 88 89 for (_rb = rb_first(&nommu_vma_tree); _rb; _rb = rb_next(_rb)) { 90 if (pos == 0) { 91 next = _rb; 92 break; 93 } 94 } 95 96 return next; 97 } 98 99 static void nommu_vma_list_stop(struct seq_file *m, void *v) 100 { 101 up_read(&nommu_vma_sem); 102 } 103 104 static void *nommu_vma_list_next(struct seq_file *m, void *v, loff_t *pos) 105 { 106 (*pos)++; 107 return rb_next((struct rb_node *) v); 108 } 109 110 static struct seq_operations proc_nommu_vma_list_seqop = { 111 .start = nommu_vma_list_start, 112 .next = nommu_vma_list_next, 113 .stop = nommu_vma_list_stop, 114 .show = nommu_vma_list_show 115 }; 116 117 static int proc_nommu_vma_list_open(struct inode *inode, struct file *file) 118 { 119 return seq_open(file, &proc_nommu_vma_list_seqop); 120 } 121 122 static struct file_operations proc_nommu_vma_list_operations = { 123 .open = proc_nommu_vma_list_open, 124 .read = seq_read, 125 .llseek = seq_lseek, 126 .release = seq_release, 127 }; 128 129 static int __init proc_nommu_init(void) 130 { 131 create_seq_entry("maps", S_IRUGO, &proc_nommu_vma_list_operations); 132 return 0; 133 } 134 135 module_init(proc_nommu_init); 136