linux/fs/proc/nommu.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/* nommu.c: mmu-less memory info files
   3 *
   4 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
   5 * Written by David Howells (dhowells@redhat.com)
   6 */
   7
   8#include <linux/init.h>
   9#include <linux/module.h>
  10#include <linux/errno.h>
  11#include <linux/time.h>
  12#include <linux/kernel.h>
  13#include <linux/string.h>
  14#include <linux/mman.h>
  15#include <linux/proc_fs.h>
  16#include <linux/mm.h>
  17#include <linux/mmzone.h>
  18#include <linux/pagemap.h>
  19#include <linux/swap.h>
  20#include <linux/smp.h>
  21#include <linux/seq_file.h>
  22#include <linux/hugetlb.h>
  23#include <linux/vmalloc.h>
  24#include <linux/uaccess.h>
  25#include <asm/tlb.h>
  26#include <asm/div64.h>
  27#include "internal.h"
  28
  29/*
  30 * display a single region to a sequenced file
  31 */
  32static int nommu_region_show(struct seq_file *m, struct vm_region *region)
  33{
  34        unsigned long ino = 0;
  35        struct file *file;
  36        dev_t dev = 0;
  37        int flags;
  38
  39        flags = region->vm_flags;
  40        file = region->vm_file;
  41
  42        if (file) {
  43                struct inode *inode = file_inode(region->vm_file);
  44                dev = inode->i_sb->s_dev;
  45                ino = inode->i_ino;
  46        }
  47
  48        seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);
  49        seq_printf(m,
  50                   "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
  51                   region->vm_start,
  52                   region->vm_end,
  53                   flags & VM_READ ? 'r' : '-',
  54                   flags & VM_WRITE ? 'w' : '-',
  55                   flags & VM_EXEC ? 'x' : '-',
  56                   flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p',
  57                   ((loff_t)region->vm_pgoff) << PAGE_SHIFT,
  58                   MAJOR(dev), MINOR(dev), ino);
  59
  60        if (file) {
  61                seq_pad(m, ' ');
  62                seq_file_path(m, file, "");
  63        }
  64
  65        seq_putc(m, '\n');
  66        return 0;
  67}
  68
  69/*
  70 * display a list of all the REGIONs the kernel knows about
  71 * - nommu kernels have a single flat list
  72 */
  73static int nommu_region_list_show(struct seq_file *m, void *_p)
  74{
  75        struct rb_node *p = _p;
  76
  77        return nommu_region_show(m, rb_entry(p, struct vm_region, vm_rb));
  78}
  79
  80static void *nommu_region_list_start(struct seq_file *m, loff_t *_pos)
  81{
  82        struct rb_node *p;
  83        loff_t pos = *_pos;
  84
  85        down_read(&nommu_region_sem);
  86
  87        for (p = rb_first(&nommu_region_tree); p; p = rb_next(p))
  88                if (pos-- == 0)
  89                        return p;
  90        return NULL;
  91}
  92
  93static void nommu_region_list_stop(struct seq_file *m, void *v)
  94{
  95        up_read(&nommu_region_sem);
  96}
  97
  98static void *nommu_region_list_next(struct seq_file *m, void *v, loff_t *pos)
  99{
 100        (*pos)++;
 101        return rb_next((struct rb_node *) v);
 102}
 103
 104static const struct seq_operations proc_nommu_region_list_seqop = {
 105        .start  = nommu_region_list_start,
 106        .next   = nommu_region_list_next,
 107        .stop   = nommu_region_list_stop,
 108        .show   = nommu_region_list_show
 109};
 110
 111static int __init proc_nommu_init(void)
 112{
 113        proc_create_seq("maps", S_IRUGO, NULL, &proc_nommu_region_list_seqop);
 114        return 0;
 115}
 116
 117fs_initcall(proc_nommu_init);
 118