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