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_unreference(struct phys_region
*pr
);
17 static int shared_pagefault(struct vmproc
*vmp
, struct vir_region
*region
,
18 struct phys_region
*ph
, int write
, vfs_callback_t cb
, void *state
,
20 static int shared_sanitycheck(struct phys_region
*pr
, const 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
);
26 static int shared_pt_flags(struct vir_region
*vr
);
28 struct mem_type mem_type_shared
= {
29 .name
= "shared memory",
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
,
38 .pt_flags
= shared_pt_flags
,
41 static int shared_pt_flags(struct vir_region
*vr
){
43 return ARM_VM_PTE_CACHED
;
49 static int shared_unreference(struct phys_region
*pr
)
51 return mem_type_anon
.ev_unreference(pr
);
54 static int getsrc(struct vir_region
*region
,
55 struct vmproc
**vmp
, struct vir_region
**r
)
59 if(region
->def_memtype
!= &mem_type_shared
) {
60 printf("shared region hasn't shared type but %s.\n",
61 region
->def_memtype
->name
);
65 if(!region
->param
.shared
.ep
|| !region
->param
.shared
.vaddr
) {
66 printf("shared region has not defined source region.\n");
71 if(vm_isokendpt((endpoint_t
) region
->param
.shared
.ep
, &srcproc
) != OK
) {
72 printf("VM: shared memory with missing source process.\n");
77 *vmp
= &vmproc
[srcproc
];
79 if(!(*r
=map_lookup(*vmp
, region
->param
.shared
.vaddr
, NULL
))) {
80 printf("VM: shared memory with missing vaddr 0x%lx.\n",
81 region
->param
.shared
.vaddr
);
85 if((*r
)->def_memtype
!= &mem_type_anon
) {
86 printf("source region hasn't anon type but %s.\n",
87 (*r
)->def_memtype
->name
);
91 if(region
->param
.shared
.id
!= (*r
)->id
) {
92 printf("source region has no matching id\n");
99 static u32_t
shared_regionid(struct vir_region
*vr
)
101 struct vir_region
*src_region
;
102 struct vmproc
*src_vmp
;
104 if(getsrc(vr
, &src_vmp
, &src_region
) != OK
)
107 return src_region
->id
;
110 static void shared_delete(struct vir_region
*region
)
112 struct vir_region
*src_region
;
113 struct vmproc
*src_vmp
;
115 if(getsrc(region
, &src_vmp
, &src_region
) != OK
)
118 assert(src_region
->remaps
> 0);
119 src_region
->remaps
--;
122 static int shared_pagefault(struct vmproc
*vmp
, struct vir_region
*region
,
123 struct phys_region
*ph
, int write
, vfs_callback_t cb
,
124 void *state
, int statelen
, int *io
)
126 struct vir_region
*src_region
;
127 struct vmproc
*src_vmp
;
128 struct phys_region
*pr
;
130 if(getsrc(region
, &src_vmp
, &src_region
) != OK
) {
134 assert(ph
->ph
->phys
== MAP_NONE
);
137 if(!(pr
= physblock_get(src_region
, ph
->offset
))) {
139 if((r
=map_pf(src_vmp
, src_region
, ph
->offset
, write
,
140 NULL
, NULL
, 0, io
)) != OK
)
142 if(!(pr
= physblock_get(src_region
, ph
->offset
))) {
143 panic("missing region after pagefault handling");
147 pb_link(ph
, pr
->ph
, ph
->offset
, region
);
152 static int shared_sanitycheck(struct phys_region
*pr
, const char *file
, int line
)
157 static int shared_writable(struct phys_region
*pr
)
159 assert(pr
->ph
->refcount
> 0);
160 return pr
->ph
->phys
!= MAP_NONE
;
163 void shared_setsource(struct vir_region
*vr
, endpoint_t ep
,
164 struct vir_region
*src_vr
)
167 struct vir_region
*srcvr
;
169 vir_bytes vaddr
= src_vr
->vaddr
;
171 assert(vr
->def_memtype
== &mem_type_shared
);
173 if(!ep
|| !vaddr
|| !id
) {
174 printf("VM: shared_setsource: zero ep/vaddr/id - ignoring\n");
178 vr
->param
.shared
.ep
= ep
;
179 vr
->param
.shared
.vaddr
= vaddr
;
180 vr
->param
.shared
.id
= id
;
182 if(getsrc(vr
, &vmp
, &srcvr
) != OK
)
183 panic("initial getsrc failed");
185 assert(srcvr
== src_vr
);
190 static int shared_copy(struct vir_region
*vr
, struct vir_region
*newvr
)
193 struct vir_region
*srcvr
;
195 if(getsrc(vr
, &vmp
, &srcvr
) != OK
)
196 panic("copy: original getsrc failed");
198 shared_setsource(newvr
, vr
->param
.shared
.ep
, srcvr
);
203 static int shared_refcount(struct vir_region
*vr
)
205 return 1 + vr
->remaps
;