1433d6423SLionel Sambuc /* Function prototypes. */ 2433d6423SLionel Sambuc 3433d6423SLionel Sambuc struct vmproc; 4433d6423SLionel Sambuc struct stat; 5433d6423SLionel Sambuc struct memory; 6433d6423SLionel Sambuc struct vir_region; 7433d6423SLionel Sambuc struct phys_region; 8433d6423SLionel Sambuc 9433d6423SLionel Sambuc #include <minix/ipc.h> 10433d6423SLionel Sambuc #include <minix/endpoint.h> 11433d6423SLionel Sambuc #include <minix/safecopies.h> 12433d6423SLionel Sambuc #include <minix/vm.h> 13433d6423SLionel Sambuc #include <minix/timers.h> 14433d6423SLionel Sambuc #include <stdio.h> 15433d6423SLionel Sambuc 16433d6423SLionel Sambuc #include "pt.h" 17433d6423SLionel Sambuc #include "vm.h" 18433d6423SLionel Sambuc 19433d6423SLionel Sambuc /* acl.c */ 20433d6423SLionel Sambuc void acl_init(void); 21433d6423SLionel Sambuc int acl_check(struct vmproc *vmp, int call); 22433d6423SLionel Sambuc void acl_set(struct vmproc *vmp, bitchunk_t *mask, int sys_proc); 23433d6423SLionel Sambuc void acl_fork(struct vmproc *vmp); 24433d6423SLionel Sambuc void acl_clear(struct vmproc *vmp); 25433d6423SLionel Sambuc 26433d6423SLionel Sambuc /* alloc.c */ 27433d6423SLionel Sambuc void *reservedqueue_new(int, int, int, int); 28433d6423SLionel Sambuc int reservedqueue_alloc(void *, phys_bytes *, void **); 29433d6423SLionel Sambuc void reservedqueue_add(void *, void *, phys_bytes); 30433d6423SLionel Sambuc void alloc_cycle(void); 31433d6423SLionel Sambuc void mem_sanitycheck(const char *file, int line); 32433d6423SLionel Sambuc phys_clicks alloc_mem(phys_clicks clicks, u32_t flags); 33433d6423SLionel Sambuc void memstats(int *nodes, int *pages, int *largest); 34433d6423SLionel Sambuc void printmemstats(void); 35433d6423SLionel Sambuc void usedpages_reset(void); 36433d6423SLionel Sambuc int usedpages_add_f(phys_bytes phys, phys_bytes len, const char *file, int 37433d6423SLionel Sambuc line); 38433d6423SLionel Sambuc void free_mem(phys_clicks base, phys_clicks clicks); 39433d6423SLionel Sambuc void mem_add_total_pages(int pages); 40433d6423SLionel Sambuc #define usedpages_add(a, l) usedpages_add_f(a, l, __FILE__, __LINE__) 41433d6423SLionel Sambuc 42433d6423SLionel Sambuc void mem_init(struct memory *chunks); 43433d6423SLionel Sambuc 44433d6423SLionel Sambuc /* utility.c */ 45433d6423SLionel Sambuc void get_mem_chunks(struct memory *mem_chunks); 46433d6423SLionel Sambuc int vm_isokendpt(endpoint_t ep, int *proc); 47433d6423SLionel Sambuc int get_stack_ptr(int proc_nr, vir_bytes *sp); 48433d6423SLionel Sambuc int do_info(message *); 49433d6423SLionel Sambuc int swap_proc_slot(struct vmproc *src_vmp, struct vmproc *dst_vmp); 5063483e02SCristiano Giuffrida int swap_proc_dyn_data(struct vmproc *src_vmp, struct vmproc *dst_vmp, 5163483e02SCristiano Giuffrida int sys_upd_flags); 52*abf8a7e7SDavid van Moolenbroek int map_proc_dyn_data(struct vmproc *src_vmp, struct vmproc *dst_vmp); 5363483e02SCristiano Giuffrida void adjust_proc_refs(void); 54433d6423SLionel Sambuc int do_getrusage(message *m); 55433d6423SLionel Sambuc 56433d6423SLionel Sambuc /* exit.c */ 57433d6423SLionel Sambuc void clear_proc(struct vmproc *vmp); 58433d6423SLionel Sambuc int do_exit(message *msg); 59433d6423SLionel Sambuc int do_willexit(message *msg); 60433d6423SLionel Sambuc int do_procctl(message *msg, int transid); 61433d6423SLionel Sambuc void free_proc(struct vmproc *vmp); 62433d6423SLionel Sambuc 63433d6423SLionel Sambuc /* fork.c */ 64433d6423SLionel Sambuc int do_fork(message *msg); 65433d6423SLionel Sambuc 66433d6423SLionel Sambuc /* break.c */ 67433d6423SLionel Sambuc int do_brk(message *msg); 68433d6423SLionel Sambuc int real_brk(struct vmproc *vmp, vir_bytes v); 69433d6423SLionel Sambuc 70433d6423SLionel Sambuc /* map_mem.c */ 71433d6423SLionel Sambuc int map_memory(endpoint_t sour, endpoint_t dest, vir_bytes virt_s, 72433d6423SLionel Sambuc vir_bytes virt_d, vir_bytes length, int flag); 73433d6423SLionel Sambuc int unmap_memory(endpoint_t sour, endpoint_t dest, vir_bytes virt_s, 74433d6423SLionel Sambuc vir_bytes virt_d, vir_bytes length, int flag); 75433d6423SLionel Sambuc 76433d6423SLionel Sambuc /* mmap.c */ 77433d6423SLionel Sambuc int do_mmap(message *msg); 78433d6423SLionel Sambuc int do_munmap(message *msg); 79433d6423SLionel Sambuc int do_map_phys(message *msg); 80433d6423SLionel Sambuc int do_unmap_phys(message *msg); 81433d6423SLionel Sambuc int do_remap(message *m); 82433d6423SLionel Sambuc int do_get_phys(message *m); 83433d6423SLionel Sambuc int do_get_refcount(message *m); 84433d6423SLionel Sambuc int do_vfs_mmap(message *m); 85433d6423SLionel Sambuc 86433d6423SLionel Sambuc /* pagefaults.c */ 87433d6423SLionel Sambuc void do_pagefaults(message *m); 88433d6423SLionel Sambuc void do_memory(void); 89433d6423SLionel Sambuc char *pf_errstr(u32_t err); 90433d6423SLionel Sambuc int handle_memory_start(struct vmproc *vmp, vir_bytes mem, vir_bytes len, 91433d6423SLionel Sambuc int wrflag, endpoint_t caller, endpoint_t requestor, int transid, 92433d6423SLionel Sambuc int vfs_avail); 93433d6423SLionel Sambuc int handle_memory_once(struct vmproc *vmp, vir_bytes mem, vir_bytes len, 94433d6423SLionel Sambuc int wrflag); 95433d6423SLionel Sambuc 96433d6423SLionel Sambuc /* $(ARCH)/pagetable.c */ 97433d6423SLionel Sambuc void pt_init(void); 98433d6423SLionel Sambuc void vm_freepages(vir_bytes vir, int pages); 99433d6423SLionel Sambuc void pt_init_mem(void); 100433d6423SLionel Sambuc void pt_check(struct vmproc *vmp); 101433d6423SLionel Sambuc int pt_new(pt_t *pt); 102433d6423SLionel Sambuc void pt_free(pt_t *pt); 103433d6423SLionel Sambuc int pt_map_in_range(struct vmproc *src_vmp, struct vmproc *dst_vmp, 104433d6423SLionel Sambuc vir_bytes start, vir_bytes end); 105433d6423SLionel Sambuc int pt_ptmap(struct vmproc *src_vmp, struct vmproc *dst_vmp); 106433d6423SLionel Sambuc int pt_ptalloc_in_range(pt_t *pt, vir_bytes start, vir_bytes end, u32_t 107433d6423SLionel Sambuc flags, int verify); 108433d6423SLionel Sambuc void pt_clearmapcache(void); 109433d6423SLionel Sambuc int pt_writemap(struct vmproc * vmp, pt_t *pt, vir_bytes v, phys_bytes 110433d6423SLionel Sambuc physaddr, size_t bytes, u32_t flags, u32_t writemapflags); 111433d6423SLionel Sambuc int pt_checkrange(pt_t *pt, vir_bytes v, size_t bytes, int write); 112433d6423SLionel Sambuc int pt_bind(pt_t *pt, struct vmproc *who); 113433d6423SLionel Sambuc void *vm_mappages(phys_bytes p, int pages); 114433d6423SLionel Sambuc void *vm_allocpage(phys_bytes *p, int cat); 115433d6423SLionel Sambuc void *vm_allocpages(phys_bytes *p, int cat, int pages); 116433d6423SLionel Sambuc void *vm_allocpagedir(phys_bytes *p); 117433d6423SLionel Sambuc int pt_mapkernel(pt_t *pt); 118433d6423SLionel Sambuc void vm_pagelock(void *vir, int lockflag); 119433d6423SLionel Sambuc int vm_addrok(void *vir, int write); 120433d6423SLionel Sambuc int get_vm_self_pages(void); 121433d6423SLionel Sambuc int pt_writable(struct vmproc *vmp, vir_bytes v); 12210e6ba68SBen Gras void pt_assert(pt_t *pt); 123433d6423SLionel Sambuc 124433d6423SLionel Sambuc #if SANITYCHECKS 125433d6423SLionel Sambuc void pt_sanitycheck(pt_t *pt, const char *file, int line); 126433d6423SLionel Sambuc #endif 127433d6423SLionel Sambuc 128433d6423SLionel Sambuc /* slaballoc.c */ 129433d6423SLionel Sambuc void *slaballoc(int bytes); 130433d6423SLionel Sambuc void slabfree(void *mem, int bytes); 131433d6423SLionel Sambuc void slabstats(void); 132433d6423SLionel Sambuc void slab_sanitycheck(const char *file, int line); 133433d6423SLionel Sambuc #define SLABALLOC(var) (var = slaballoc(sizeof(*var))) 134433d6423SLionel Sambuc #define SLABFREE(ptr) do { slabfree(ptr, sizeof(*(ptr))); (ptr) = NULL; } while(0) 135433d6423SLionel Sambuc #if SANITYCHECKS 136433d6423SLionel Sambuc 137433d6423SLionel Sambuc void slabunlock(void *mem, int bytes); 138433d6423SLionel Sambuc void slablock(void *mem, int bytes); 139433d6423SLionel Sambuc int slabsane_f(const char *file, int line, void *mem, int bytes); 140433d6423SLionel Sambuc #endif 141433d6423SLionel Sambuc 142433d6423SLionel Sambuc /* region.c */ 143433d6423SLionel Sambuc void map_region_init(void); 144433d6423SLionel Sambuc struct vir_region * map_page_region(struct vmproc *vmp, vir_bytes min, 145433d6423SLionel Sambuc vir_bytes max, vir_bytes length, u32_t flags, int mapflags, 146433d6423SLionel Sambuc mem_type_t *memtype); 147433d6423SLionel Sambuc struct vir_region * map_proc_kernel(struct vmproc *dst); 148433d6423SLionel Sambuc int map_region_extend(struct vmproc *vmp, struct vir_region *vr, 149433d6423SLionel Sambuc vir_bytes delta); 150433d6423SLionel Sambuc int map_region_extend_upto_v(struct vmproc *vmp, vir_bytes vir); 151433d6423SLionel Sambuc int map_unmap_region(struct vmproc *vmp, struct vir_region *vr, 152433d6423SLionel Sambuc vir_bytes offset, vir_bytes len); 153433d6423SLionel Sambuc int map_unmap_range(struct vmproc *vmp, vir_bytes, vir_bytes); 154433d6423SLionel Sambuc int map_free_proc(struct vmproc *vmp); 155433d6423SLionel Sambuc int map_proc_copy(struct vmproc *dst, struct vmproc *src); 15663483e02SCristiano Giuffrida int map_proc_copy_range(struct vmproc *dst, struct vmproc *src, struct 15763483e02SCristiano Giuffrida vir_region *start_src_vr, struct vir_region *end_src_vr); 158433d6423SLionel Sambuc struct vir_region *map_lookup(struct vmproc *vmp, vir_bytes addr, 159433d6423SLionel Sambuc struct phys_region **pr); 160433d6423SLionel Sambuc int map_pf(struct vmproc *vmp, struct vir_region *region, vir_bytes 161433d6423SLionel Sambuc offset, int write, vfs_callback_t pf_callback, void *state, int len, 162433d6423SLionel Sambuc int *io); 163433d6423SLionel Sambuc int map_pin_memory(struct vmproc *vmp); 164433d6423SLionel Sambuc int map_handle_memory(struct vmproc *vmp, struct vir_region *region, 165433d6423SLionel Sambuc vir_bytes offset, vir_bytes len, int write, vfs_callback_t cb, 166433d6423SLionel Sambuc void *state, int statelen); 167433d6423SLionel Sambuc void map_printmap(struct vmproc *vmp); 168433d6423SLionel Sambuc int map_writept(struct vmproc *vmp); 169433d6423SLionel Sambuc void printregionstats(struct vmproc *vmp); 170433d6423SLionel Sambuc void map_setparent(struct vmproc *vmp); 171433d6423SLionel Sambuc u32_t vrallocflags(u32_t flags); 172433d6423SLionel Sambuc int map_free(struct vir_region *region); 173433d6423SLionel Sambuc struct phys_region *physblock_get(struct vir_region *region, vir_bytes offset); 174433d6423SLionel Sambuc void physblock_set(struct vir_region *region, vir_bytes offset, 175433d6423SLionel Sambuc struct phys_region *newphysr); 176433d6423SLionel Sambuc int map_ph_writept(struct vmproc *vmp, struct vir_region *vr, 177433d6423SLionel Sambuc struct phys_region *pr); 178433d6423SLionel Sambuc 17963483e02SCristiano Giuffrida struct vir_region* map_region_lookup_type(struct vmproc *vmp, u32_t flags); 180433d6423SLionel Sambuc int map_get_phys(struct vmproc *vmp, vir_bytes addr, phys_bytes *r); 181433d6423SLionel Sambuc int map_get_ref(struct vmproc *vmp, vir_bytes addr, u8_t *cnt); 182433d6423SLionel Sambuc unsigned int physregions(struct vir_region *vr); 183433d6423SLionel Sambuc 184433d6423SLionel Sambuc void get_usage_info(struct vmproc *vmp, struct vm_usage_info *vui); 185433d6423SLionel Sambuc void get_usage_info_kernel(struct vm_usage_info *vui); 186433d6423SLionel Sambuc int get_region_info(struct vmproc *vmp, struct vm_region_info *vri, int 187433d6423SLionel Sambuc count, vir_bytes *nextp); 188433d6423SLionel Sambuc int copy_abs2region(phys_bytes abs, struct vir_region *destregion, 189433d6423SLionel Sambuc phys_bytes offset, phys_bytes len); 190433d6423SLionel Sambuc #if SANITYCHECKS 191433d6423SLionel Sambuc void map_sanitycheck(const char *file, int line); 192433d6423SLionel Sambuc #endif 193433d6423SLionel Sambuc 194433d6423SLionel Sambuc /* rs.c */ 195433d6423SLionel Sambuc int do_rs_set_priv(message *m); 196*abf8a7e7SDavid van Moolenbroek int do_rs_prepare(message *m); 197433d6423SLionel Sambuc int do_rs_update(message *m); 198433d6423SLionel Sambuc int do_rs_memctl(message *m); 199433d6423SLionel Sambuc 200433d6423SLionel Sambuc /* pb.c */ 201433d6423SLionel Sambuc struct phys_block *pb_new(phys_bytes phys); 202433d6423SLionel Sambuc void pb_free(struct phys_block *); 203433d6423SLionel Sambuc struct phys_region *pb_reference(struct phys_block *newpb, 204433d6423SLionel Sambuc vir_bytes offset, struct vir_region *region, mem_type_t *); 205433d6423SLionel Sambuc void pb_unreferenced(struct vir_region *region, struct phys_region *pr, int rm); 206433d6423SLionel Sambuc void pb_link(struct phys_region *newphysr, struct phys_block *newpb, 207433d6423SLionel Sambuc vir_bytes offset, struct vir_region *parent); 208433d6423SLionel Sambuc int mem_cow(struct vir_region *region, 209433d6423SLionel Sambuc struct phys_region *ph, phys_bytes new_page_cl, phys_bytes new_page); 210433d6423SLionel Sambuc 211433d6423SLionel Sambuc /* mem_directphys.c */ 212433d6423SLionel Sambuc void phys_setphys(struct vir_region *vr, phys_bytes startaddr); 213433d6423SLionel Sambuc 214433d6423SLionel Sambuc /* mem_shared.c */ 215433d6423SLionel Sambuc void shared_setsource(struct vir_region *vr, endpoint_t ep, struct vir_region *src); 216433d6423SLionel Sambuc 217433d6423SLionel Sambuc /* mem_cache.c */ 218433d6423SLionel Sambuc int do_mapcache(message *m); 219433d6423SLionel Sambuc int do_setcache(message *m); 220e94f856bSDavid van Moolenbroek int do_forgetcache(message *m); 221433d6423SLionel Sambuc int do_clearcache(message *m); 222433d6423SLionel Sambuc 223433d6423SLionel Sambuc /* cache.c */ 224433d6423SLionel Sambuc struct cached_page *find_cached_page_bydev(dev_t dev, u64_t dev_off, 225433d6423SLionel Sambuc ino_t ino, u64_t ino_off, int touchlru); 226433d6423SLionel Sambuc struct cached_page *find_cached_page_byino(dev_t dev, ino_t ino, u64_t ino_off, int touchlru); 227e321f655SDavid van Moolenbroek int addcache(dev_t dev, u64_t def_off, ino_t ino, u64_t ino_off, int flags, 228e321f655SDavid van Moolenbroek struct phys_block *pb); 229433d6423SLionel Sambuc void cache_sanitycheck_internal(void); 230433d6423SLionel Sambuc int cache_freepages(int pages); 231433d6423SLionel Sambuc void get_stats_info(struct vm_stats_info *vsi); 232433d6423SLionel Sambuc void cache_lru_touch(struct cached_page *hb); 233433d6423SLionel Sambuc void rmcache(struct cached_page *cp); 234433d6423SLionel Sambuc void clear_cache_bydev(dev_t dev); 235433d6423SLionel Sambuc 236433d6423SLionel Sambuc /* vfs.c */ 237433d6423SLionel Sambuc int vfs_request(int reqno, int fd, struct vmproc *vmp, u64_t offset, 238433d6423SLionel Sambuc u32_t len, vfs_callback_t reply_callback, void *cbarg, void *state, 239433d6423SLionel Sambuc int statelen); 240433d6423SLionel Sambuc int do_vfs_reply(message *m); 241433d6423SLionel Sambuc 242433d6423SLionel Sambuc /* mem_file.c */ 243433d6423SLionel Sambuc int mappedfile_setfile(struct vmproc *owner, struct vir_region *region, 244433d6423SLionel Sambuc int fd, u64_t offset, 245433d6423SLionel Sambuc dev_t dev, ino_t ino, u16_t clearend, int prefill, int mayclose); 246433d6423SLionel Sambuc 247433d6423SLionel Sambuc /* fdref.c */ 248433d6423SLionel Sambuc struct fdref *fdref_new(struct vmproc *owner, ino_t ino, dev_t dev, int fd); 249433d6423SLionel Sambuc struct fdref *fdref_dedup_or_new(struct vmproc *owner, ino_t ino, dev_t dev, 250433d6423SLionel Sambuc int fd, int mayclose); 251433d6423SLionel Sambuc void fdref_ref(struct fdref *ref, struct vir_region *region); 252433d6423SLionel Sambuc void fdref_deref(struct vir_region *region); 253433d6423SLionel Sambuc void fdref_sanitycheck(void); 254