mm: Use struct file_or_chan for VMR files
[akaros.git] / kern / include / mm.h
1 /* Copyright (c) 2009, 2010 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Memory management for processes: syscall related functions, virtual memory
6  * regions, etc. */
7
8 #pragma once
9
10 #include <ros/common.h>
11 #include <ros/mman.h>
12 #include <atomic.h>
13 #include <sys/queue.h>
14 #include <slab.h>
15 #include <kref.h>
16
17 struct file;
18 struct chan;
19 struct fd_table;
20 struct proc;                                                            /* preprocessor games */
21
22 #define F_OR_C_NONE 0
23 #define F_OR_C_FILE 1
24 #define F_OR_C_CHAN 2
25
26 struct file_or_chan {
27         int type;
28         struct file *file;
29         struct chan *chan;
30         struct kref kref;
31 };
32
33 char *foc_to_name(struct file_or_chan *foc);
34 char *foc_abs_path(struct file_or_chan *foc, char *path, size_t max_size);
35 ssize_t foc_read(struct file_or_chan *foc, void *buf, size_t amt, off64_t off);
36 struct file_or_chan *foc_open(char *path, int omode, int perm);
37 struct file_or_chan *fd_to_foc(struct fd_table *fdt, int fd);
38 void foc_incref(struct file_or_chan *foc);
39 void foc_decref(struct file_or_chan *foc);
40 void *foc_pointer(struct file_or_chan *foc);
41 size_t foc_get_len(struct file_or_chan *foc);
42
43 /* Basic structure defining a region of a process's virtual memory.  Note we
44  * don't refcnt these.  Either they are in the TAILQ/tree, or they should be
45  * freed.  There should be no other references floating around.  We still need
46  * to sort out how we share memory and how we'll do private memory with these
47  * VMRs. */
48 struct vm_region {
49         TAILQ_ENTRY(vm_region)          vm_link;
50         TAILQ_ENTRY(vm_region)          vm_pm_link;
51         struct proc                                     *vm_proc;       /* owning process, for now */
52         uintptr_t                                       vm_base;
53         uintptr_t                                       vm_end;
54         int                                                     vm_prot;
55         int                                                     vm_flags;
56         struct file_or_chan                     *__vm_foc;
57         size_t                                          vm_foff;
58 };
59 TAILQ_HEAD(vmr_tailq, vm_region);                       /* Declares 'struct vmr_tailq' */
60
61 static inline bool vmr_has_file(struct vm_region *vmr)
62 {
63         return vmr->__vm_foc ? true : false;
64 }
65
66 static inline char *vmr_to_filename(struct vm_region *vmr)
67 {
68         assert(vmr_has_file(vmr));
69         return foc_to_name(vmr->__vm_foc);
70 }
71
72 /* VM Region Management Functions.  For now, these just maintain themselves -
73  * anything related to mapping needs to be done by the caller. */
74 void vmr_init(void);
75 struct vm_region *create_vmr(struct proc *p, uintptr_t va, size_t len);
76 struct vm_region *split_vmr(struct vm_region *vmr, uintptr_t va);
77 int merge_vmr(struct vm_region *first, struct vm_region *second);
78 struct vm_region *merge_me(struct vm_region *vmr);
79 int grow_vmr(struct vm_region *vmr, uintptr_t va);
80 int shrink_vmr(struct vm_region *vmr, uintptr_t va);
81 void destroy_vmr(struct vm_region *vmr);
82 struct vm_region *find_vmr(struct proc *p, uintptr_t va);
83 struct vm_region *find_first_vmr(struct proc *p, uintptr_t va);
84 void isolate_vmrs(struct proc *p, uintptr_t va, size_t len);
85 void unmap_and_destroy_vmrs(struct proc *p);
86 int duplicate_vmrs(struct proc *p, struct proc *new_p);
87 void print_vmrs(struct proc *p);
88 void enumerate_vmrs(struct proc *p,
89                                         void (*func)(struct vm_region *vmr, void *opaque),
90                                         void *opaque);
91
92 /* mmap() related functions.  These manipulate VMRs and change the hardware page
93  * tables.  Any requests below the LOWEST_VA will silently be upped.  This may
94  * be a dynamic proc-specific variable later. */
95 #define MMAP_LOWEST_VA PAGE_SIZE
96 #define MMAP_LD_FIXED_VA 0x100000
97 void *mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
98            int fd, size_t offset);
99 void *do_mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
100               struct file_or_chan *foc, size_t offset);
101 int mprotect(struct proc *p, uintptr_t addr, size_t len, int prot);
102 int munmap(struct proc *p, uintptr_t addr, size_t len);
103 int handle_page_fault(struct proc *p, uintptr_t va, int prot);
104 int handle_page_fault_nofile(struct proc *p, uintptr_t va, int prot);
105 unsigned long populate_va(struct proc *p, uintptr_t va, unsigned long nr_pgs);
106
107 /* These assume the mm_lock is held already */
108 int __do_mprotect(struct proc *p, uintptr_t addr, size_t len, int prot);
109 int __do_munmap(struct proc *p, uintptr_t addr, size_t len);
110
111 /* Kernel Dynamic Memory Mappings */
112 struct arena *vmap_arena;
113 void vmap_init(void);
114 /* Gets PML1 page-aligned virtual addresses for the kernel's dynamic vmap.
115  * You'll need to map it to something.  When you're done, 'put-' will also unmap
116  * the vaddr for you. */
117 uintptr_t get_vmap_segment(size_t nr_bytes);
118 void put_vmap_segment(uintptr_t vaddr, size_t nr_bytes);
119 int map_vmap_segment(uintptr_t vaddr, uintptr_t paddr, unsigned long num_pages,
120                      int perm);
121 /* Helper wrappers for getting and mapping a specific paddr. */
122 uintptr_t vmap_pmem(uintptr_t paddr, size_t nr_bytes);
123 uintptr_t vmap_pmem_nocache(uintptr_t paddr, size_t nr_bytes);
124 uintptr_t vmap_pmem_writecomb(uintptr_t paddr, size_t nr_bytes);
125 int vunmap_vmem(uintptr_t vaddr, size_t nr_bytes);