kernel: restore setting KTS_NONE
[minix.git] / servers / vm / mem_shared.c
blob17252efe5893cb7ade720e73a4df39d45ce17e0a
2 /* This file implements the methods of shared memory. */
4 #include <assert.h>
6 #include "proto.h"
7 #include "vm.h"
8 #include "region.h"
9 #include "glo.h"
11 /* These functions are static so as to not pollute the
12 * global namespace, and are accessed through their function
13 * pointers.
16 static int shared_reference(struct phys_region *pr);
17 static int shared_unreference(struct phys_region *pr);
18 static int shared_pagefault(struct vmproc *vmp, struct vir_region *region,
19 struct phys_region *ph, int write);
20 static int shared_sanitycheck(struct phys_region *pr, char *file, int line);
21 static int shared_writable(struct phys_region *pr);
22 static void shared_delete(struct vir_region *region);
23 static u32_t shared_regionid(struct vir_region *region);
24 static int shared_copy(struct vir_region *vr, struct vir_region *newvr);
25 static int shared_refcount(struct vir_region *vr);
27 struct mem_type mem_type_shared = {
28 .name = "shared memory",
29 .ev_reference = shared_reference,
30 .ev_copy = shared_copy,
31 .ev_unreference = shared_unreference,
32 .ev_pagefault = shared_pagefault,
33 .ev_sanitycheck = shared_sanitycheck,
34 .ev_delete = shared_delete,
35 .regionid = shared_regionid,
36 .refcount = shared_refcount,
37 .writable = shared_writable
40 static int shared_reference(struct phys_region *pr)
42 return OK;
45 static int shared_unreference(struct phys_region *pr)
47 return mem_type_anon.ev_unreference(pr);
50 static int getsrc(struct vir_region *region,
51 struct vmproc **vmp, struct vir_region **r)
53 int srcproc;
55 if(region->memtype != &mem_type_shared) {
56 printf("shared region hasn't shared type but %s.\n",
57 region->memtype->name);
58 return EINVAL;
61 if(!region->param.shared.ep || !region->param.shared.vaddr) {
62 printf("shared region has not defined source region.\n");
63 util_stacktrace();
64 return EINVAL;
67 if(vm_isokendpt((endpoint_t) region->param.shared.ep, &srcproc) != OK) {
68 printf("VM: shared memory with missing source process.\n");
69 util_stacktrace();
70 return EINVAL;
73 *vmp = &vmproc[srcproc];
75 if(!(*r=map_lookup(*vmp, region->param.shared.vaddr, NULL))) {
76 printf("VM: shared memory with missing vaddr 0x%lx.\n",
77 region->param.shared.vaddr);
78 return EINVAL;
81 if((*r)->memtype != &mem_type_anon) {
82 printf("source region hasn't anon type but %s.\n",
83 (*r)->memtype->name);
84 return EINVAL;
87 if(region->param.shared.id != (*r)->id) {
88 printf("source region has no matching id\n");
89 return EINVAL;
92 return OK;
95 static u32_t shared_regionid(struct vir_region *vr)
97 struct vir_region *src_region;
98 struct vmproc *src_vmp;
100 if(getsrc(vr, &src_vmp, &src_region) != OK)
101 return 0;
103 return src_region->id;
106 static void shared_delete(struct vir_region *region)
108 struct vir_region *src_region;
109 struct vmproc *src_vmp;
111 if(getsrc(region, &src_vmp, &src_region) != OK)
112 return;
114 assert(src_region->remaps > 0);
115 src_region->remaps--;
118 static int shared_pagefault(struct vmproc *vmp, struct vir_region *region,
119 struct phys_region *ph, int write)
121 struct vir_region *src_region;
122 struct vmproc *src_vmp;
123 struct phys_region *pr;
125 if(getsrc(region, &src_vmp, &src_region) != OK) {
126 return EINVAL;
129 assert(ph->ph->phys == MAP_NONE);
130 pb_free(ph->ph);
132 if(!(pr = physblock_get(src_region, ph->offset))) {
133 int r;
134 if((r=map_pf(src_vmp, src_region, ph->offset, write)) != OK)
135 return r;
136 if(!(pr = physblock_get(src_region, ph->offset))) {
137 panic("missing region after pagefault handling");
141 pb_link(ph, pr->ph, ph->offset, region);
143 return OK;
146 static int shared_sanitycheck(struct phys_region *pr, char *file, int line)
148 return OK;
151 static int shared_writable(struct phys_region *pr)
153 assert(pr->ph->refcount > 0);
154 return pr->ph->phys != MAP_NONE;
157 void shared_setsource(struct vir_region *vr, endpoint_t ep,
158 struct vir_region *src_vr)
160 struct vmproc *vmp;
161 struct vir_region *srcvr;
162 int id = src_vr->id;
163 vir_bytes vaddr = src_vr->vaddr;
165 assert(vr->memtype == &mem_type_shared);
167 if(!ep || !vaddr || !id) {
168 printf("VM: shared_setsource: zero ep/vaddr/id - ignoring\n");
169 return;
172 vr->param.shared.ep = ep;
173 vr->param.shared.vaddr = vaddr;
174 vr->param.shared.id = id;
176 if(getsrc(vr, &vmp, &srcvr) != OK)
177 panic("initial getsrc failed");
179 assert(srcvr == src_vr);
181 srcvr->remaps++;
184 static int shared_copy(struct vir_region *vr, struct vir_region *newvr)
186 struct vmproc *vmp;
187 struct vir_region *srcvr;
189 if(getsrc(vr, &vmp, &srcvr) != OK)
190 panic("copy: original getsrc failed");
192 shared_setsource(newvr, vr->param.shared.ep, srcvr);
194 return OK;
197 static int shared_refcount(struct vir_region *vr)
199 return 1 + vr->remaps;