|
@@ -14,7 +14,7 @@
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/spinlock.h>
|
|
|
#include <linux/interrupt.h>
|
|
|
-
|
|
|
+#include <linux/seq_file.h>
|
|
|
#include <linux/vmalloc.h>
|
|
|
|
|
|
#include <asm/uaccess.h>
|
|
@@ -873,3 +873,77 @@ void free_vm_area(struct vm_struct *area)
|
|
|
kfree(area);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(free_vm_area);
|
|
|
+
|
|
|
+
|
|
|
+#ifdef CONFIG_PROC_FS
|
|
|
+static void *s_start(struct seq_file *m, loff_t *pos)
|
|
|
+{
|
|
|
+ loff_t n = *pos;
|
|
|
+ struct vm_struct *v;
|
|
|
+
|
|
|
+ read_lock(&vmlist_lock);
|
|
|
+ v = vmlist;
|
|
|
+ while (n > 0 && v) {
|
|
|
+ n--;
|
|
|
+ v = v->next;
|
|
|
+ }
|
|
|
+ if (!n)
|
|
|
+ return v;
|
|
|
+
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+static void *s_next(struct seq_file *m, void *p, loff_t *pos)
|
|
|
+{
|
|
|
+ struct vm_struct *v = p;
|
|
|
+
|
|
|
+ ++*pos;
|
|
|
+ return v->next;
|
|
|
+}
|
|
|
+
|
|
|
+static void s_stop(struct seq_file *m, void *p)
|
|
|
+{
|
|
|
+ read_unlock(&vmlist_lock);
|
|
|
+}
|
|
|
+
|
|
|
+static int s_show(struct seq_file *m, void *p)
|
|
|
+{
|
|
|
+ struct vm_struct *v = p;
|
|
|
+
|
|
|
+ seq_printf(m, "0x%p-0x%p %7ld",
|
|
|
+ v->addr, v->addr + v->size, v->size);
|
|
|
+
|
|
|
+ if (v->nr_pages)
|
|
|
+ seq_printf(m, " pages=%d", v->nr_pages);
|
|
|
+
|
|
|
+ if (v->phys_addr)
|
|
|
+ seq_printf(m, " phys=%lx", v->phys_addr);
|
|
|
+
|
|
|
+ if (v->flags & VM_IOREMAP)
|
|
|
+ seq_printf(m, " ioremap");
|
|
|
+
|
|
|
+ if (v->flags & VM_ALLOC)
|
|
|
+ seq_printf(m, " vmalloc");
|
|
|
+
|
|
|
+ if (v->flags & VM_MAP)
|
|
|
+ seq_printf(m, " vmap");
|
|
|
+
|
|
|
+ if (v->flags & VM_USERMAP)
|
|
|
+ seq_printf(m, " user");
|
|
|
+
|
|
|
+ if (v->flags & VM_VPAGES)
|
|
|
+ seq_printf(m, " vpages");
|
|
|
+
|
|
|
+ seq_putc(m, '\n');
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+const struct seq_operations vmalloc_op = {
|
|
|
+ .start = s_start,
|
|
|
+ .next = s_next,
|
|
|
+ .stop = s_stop,
|
|
|
+ .show = s_show,
|
|
|
+};
|
|
|
+#endif
|
|
|
+
|