2 /* This file implements the methods of shared memory. */
11 /* These functions are static so as to not pollute the
12 * global namespace, and are accessed through their function
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
)
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
)
55 if(region
->memtype
!= &mem_type_shared
) {
56 printf("shared region hasn't shared type but %s.\n",
57 region
->memtype
->name
);
61 if(!region
->param
.shared
.ep
|| !region
->param
.shared
.vaddr
) {
62 printf("shared region has not defined source region.\n");
67 if(vm_isokendpt((endpoint_t
) region
->param
.shared
.ep
, &srcproc
) != OK
) {
68 printf("VM: shared memory with missing source process.\n");
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
);
81 if((*r
)->memtype
!= &mem_type_anon
) {
82 printf("source region hasn't anon type but %s.\n",
87 if(region
->param
.shared
.id
!= (*r
)->id
) {
88 printf("source region has no matching id\n");
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
)
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
)
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
) {
129 assert(ph
->ph
->phys
== MAP_NONE
);
132 if(!(pr
= physblock_get(src_region
, ph
->offset
))) {
134 if((r
=map_pf(src_vmp
, src_region
, ph
->offset
, write
)) != OK
)
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
);
146 static int shared_sanitycheck(struct phys_region
*pr
, char *file
, int line
)
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
)
161 struct vir_region
*srcvr
;
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");
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
);
184 static int shared_copy(struct vir_region
*vr
, struct vir_region
*newvr
)
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
);
197 static int shared_refcount(struct vir_region
*vr
)
199 return 1 + vr
->remaps
;