2 /* This file implements the methods of anonymous memory.
4 * Anonymous memory is memory that is for private use to a process
5 * and can not be related to a file (hence anonymous).
15 /* These functions are static so as to not pollute the
16 * global namespace, and are accessed through their function
20 static int anon_reference(struct phys_region
*pr
);
21 static int anon_unreference(struct phys_region
*pr
);
22 static int anon_pagefault(struct vmproc
*vmp
, struct vir_region
*region
,
23 struct phys_region
*ph
, int write
);
24 static int anon_sanitycheck(struct phys_region
*pr
, char *file
, int line
);
25 static int anon_writable(struct phys_region
*pr
);
26 static int anon_resize(struct vmproc
*vmp
, struct vir_region
*vr
, vir_bytes l
);
27 static u32_t
anon_regionid(struct vir_region
*region
);
28 static int anon_refcount(struct vir_region
*vr
);
30 struct mem_type mem_type_anon
= {
31 .name
= "anonymous memory",
32 .ev_reference
= anon_reference
,
33 .ev_unreference
= anon_unreference
,
34 .ev_pagefault
= anon_pagefault
,
35 .ev_resize
= anon_resize
,
36 .ev_sanitycheck
= anon_sanitycheck
,
37 .regionid
= anon_regionid
,
38 .writable
= anon_writable
,
39 .refcount
= anon_refcount
42 static int anon_reference(struct phys_region
*pr
)
47 static int anon_unreference(struct phys_region
*pr
)
49 assert(pr
->ph
->refcount
== 0);
50 if(pr
->ph
->phys
!= MAP_NONE
)
51 free_mem(ABS2CLICK(pr
->ph
->phys
), 1);
55 static int anon_pagefault(struct vmproc
*vmp
, struct vir_region
*region
,
56 struct phys_region
*ph
, int write
)
58 phys_bytes new_page
, new_page_cl
;
59 struct phys_block
*pb
;
62 allocflags
= vrallocflags(region
->flags
);
64 assert(ph
->ph
->refcount
> 0);
66 if((new_page_cl
= alloc_mem(1, allocflags
)) == NO_MEM
)
68 new_page
= CLICK2ABS(new_page_cl
);
70 /* Totally new block? Create it. */
71 if(ph
->ph
->phys
== MAP_NONE
) {
72 ph
->ph
->phys
= new_page
;
73 assert(ph
->ph
->phys
!= MAP_NONE
);
78 if(ph
->ph
->refcount
< 2 || !write
) {
79 printf("anon_pagefault: %d refcount, %d write - not handling pagefault\n",
80 ph
->ph
->refcount
, write
);
84 assert(region
->flags
& VR_WRITABLE
);
86 if(sys_abscopy(ph
->ph
->phys
, new_page
, VM_PAGE_SIZE
) != OK
) {
87 panic("VM: abscopy failed\n");
91 if(!(pb
= pb_new(new_page
))) {
92 free_mem(new_page_cl
, 1);
96 pb_unreferenced(region
, ph
, 0);
97 pb_link(ph
, pb
, ph
->offset
, region
);
102 static int anon_sanitycheck(struct phys_region
*pr
, char *file
, int line
)
104 MYASSERT(usedpages_add(pr
->ph
->phys
, VM_PAGE_SIZE
) == OK
);
108 static int anon_writable(struct phys_region
*pr
)
110 assert(pr
->ph
->refcount
> 0);
111 if(pr
->parent
->remaps
> 0)
113 return pr
->ph
->phys
!= MAP_NONE
&& pr
->ph
->refcount
== 1;
116 static int anon_resize(struct vmproc
*vmp
, struct vir_region
*vr
, vir_bytes l
)
118 /* Shrinking not implemented; silently ignored.
119 * (Which is ok for brk().)
125 assert(vr
->flags
& VR_ANON
);
126 assert(!(l
% VM_PAGE_SIZE
));
128 USE(vr
, vr
->length
= l
;);
133 static u32_t
anon_regionid(struct vir_region
*region
)
138 static int anon_refcount(struct vir_region
*vr
)
140 return 1 + vr
->remaps
;