mmap() and friends using vm regions
[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 #ifndef ROS_KERN_MM_H
9 #define ROS_KERN_MM_H
10
11 #include <ros/common.h>
12 #include <atomic.h>
13 #include <sys/queue.h>
14 #include <slab.h>
15
16 /* Memory region for a process, consisting of linear(virtual) addresses.  This
17  * is what the kernel allocates a process, and the physical mapping can be done
18  * lazily (or not).  This way, if a page is swapped out, and the PTE says it
19  * isn't present, we still have a way to account for how the whole region ought
20  * to be dealt with.
21  * Some things are per-region:
22  * - probably something with shared memory
23  * - mmaping files: we can have a logical connection to something other than
24  *   anonymous memory
25  * - on a fault, was this memory supposed to be there? (swap, lazy, etc), or is
26  *   the region free?
27  * Others are per-page:
28  * - was this page supposed to be protected somehow(guard)? could be per-region
29  * - where is this page in the swap?
30  * If we try to store this info in the PTE, we only have 31 bits, and it's more
31  * arch dependent.  Handling jumbos is a pain.  And it's replicated across all
32  * pages for a coarse granularity things.  And we can't add things easily.
33  *
34  * so a process has a (sorted) list of these for it's VA space, hanging off it's
35  * struct proc.  or off it's mm?
36  * - we don't share an mm between processes anymore (tasks/threads)
37  *   - though we share most everything with vpm.
38  *   - want to be able to do all the same things with vpm as with regular mem
39  *     (file back mmap, etc)
40  *   - contexts or whatever share lots of mem things, like accounting, limits,
41  *   overall process stuff, the rest of the page tables.
42  *      - so there should be some overall mm, and probably directly in the
43  *      struct proc (or just one other struct directly embedded, not a pointer
44  *      to one where a bunch of processes use it)
45  *              - if we embed, mm.h doesn't need to know about process.h
46  *   so an mm can have a bunch of "address spaces" - or at least different
47  *   contexts
48  *
49  * how does this change or where does this belong with virtual private memory?
50  * will also affect get_free_va_range
51  *      - also, do we want a separate brk per?  or just support mmap on private mem?
52  */
53 struct file;
54 struct proc;                                                            /* preprocessor games */
55
56 /* This might turn into a per-process mem management structure.  For now, we're
57  * using the proc struct.  This would have things like the vmr list/tree, cr3,
58  * mem usage stats, something with private memory, etc.  Not sure if we'll ever
59  * need this. */
60 struct mm {
61         spinlock_t mm_lock;
62 };
63
64 /* Basic structure defining a region of a process's virtual memory */
65 struct vm_region {
66         TAILQ_ENTRY(vm_region)          vm_link;
67         struct proc                                     *vm_proc;       /* owning process, for now */
68         //struct mm                                     *vm_mm;         /* owning address space */
69         uintptr_t                                       vm_base;
70         uintptr_t                                       vm_end;
71         int                                                     vm_perm;        
72         int                                                     vm_flags;       
73         struct file                                     *vm_file;
74         size_t                                          vm_foff;
75 };
76 TAILQ_HEAD(vmr_tailq, vm_region);                       /* Declares 'struct vmr_tailq' */
77
78 #include <process.h>                                            /* preprocessor games */
79
80 /* VM Region Management Functions.  For now, these just maintain themselves -
81  * anything related to mapping needs to be done by the caller. */
82 void vmr_init(void);
83 struct vm_region *create_vmr(struct proc *p, uintptr_t va, size_t len);
84 struct vm_region *split_vmr(struct vm_region *vmr, uintptr_t va);
85 int merge_vmr(struct vm_region *first, struct vm_region *second);
86 int grow_vmr(struct vm_region *vmr, uintptr_t va);
87 int shrink_vmr(struct vm_region *vmr, uintptr_t va);
88 void destroy_vmr(struct vm_region *vmr);
89 struct vm_region *find_vmr(struct proc *p, uintptr_t va);
90 struct vm_region *find_first_vmr(struct proc *p, uintptr_t va);
91 void isolate_vmrs(struct proc *p, uintptr_t va, size_t len);
92 void print_vmrs(struct proc *p);
93
94 // at least for now, we aren't using vm regions. we're storing pointers
95 // to pfault_info_t inside the PTEs in an arch-specific way.
96 typedef struct pfault_info {
97         struct file* file; // or NULL for zero-fill
98         size_t pgoff; // offset into file
99         size_t read_len; // amount of file to read into this page (zero-fill rest)
100         int prot;
101 } pfault_info_t;
102
103 void mmap_init(void);
104
105 pfault_info_t* pfault_info_alloc(struct file* file);
106 void pfault_info_free(pfault_info_t* pfi);
107
108
109 /* mmap() related functions.  These manipulate VMRs and change the hardware page
110  * tables. */
111 void *mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
112            int fd, size_t offset);
113 void *do_mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
114              struct file *f, size_t offset);
115 int mprotect(struct proc *p, uintptr_t addr, size_t len, int prot);
116 int munmap(struct proc *p, uintptr_t addr, size_t len);
117 int handle_page_fault(struct proc *p, uintptr_t va, int prot);
118
119 /* These assume the memory/proc_lock is held already */
120 void *__do_mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
121                struct file *f, size_t offset);
122 int __do_mprotect(struct proc *p, uintptr_t addr, size_t len, int prot);
123 int __do_munmap(struct proc *p, uintptr_t addr, size_t len);
124 int __handle_page_fault(struct proc* p, uintptr_t va, int prot);
125
126 #endif /* !ROS_KERN_MM_H */