vm_remap_ro
- allows shared memory to be mapped in readonly - ben@minix3.org & tom@minix3.org
This commit is contained in:
parent
88f990e122
commit
4668b84158
11 changed files with 72 additions and 12 deletions
|
@ -716,6 +716,7 @@ struct
|
||||||
{ "DELDMA", VM_DELDMA },
|
{ "DELDMA", VM_DELDMA },
|
||||||
{ "GETDMA", VM_GETDMA },
|
{ "GETDMA", VM_GETDMA },
|
||||||
{ "REMAP", VM_REMAP },
|
{ "REMAP", VM_REMAP },
|
||||||
|
{ "REMAP_RO", VM_REMAP_RO },
|
||||||
{ "SHM_UNMAP", VM_SHM_UNMAP },
|
{ "SHM_UNMAP", VM_SHM_UNMAP },
|
||||||
{ "GETPHYS", VM_GETPHYS },
|
{ "GETPHYS", VM_GETPHYS },
|
||||||
{ "GETREF", VM_GETREF },
|
{ "GETREF", VM_GETREF },
|
||||||
|
|
|
@ -999,6 +999,7 @@
|
||||||
# define VMRE_SA m1_p2
|
# define VMRE_SA m1_p2
|
||||||
# define VMRE_RETA m1_p3
|
# define VMRE_RETA m1_p3
|
||||||
# define VMRE_SIZE m1_i3
|
# define VMRE_SIZE m1_i3
|
||||||
|
# define VMRE_FLAGS m1_i3
|
||||||
|
|
||||||
#define VM_SHM_UNMAP (VM_RQ_BASE+34)
|
#define VM_SHM_UNMAP (VM_RQ_BASE+34)
|
||||||
# define VMUN_ENDPT m2_i1
|
# define VMUN_ENDPT m2_i1
|
||||||
|
@ -1051,8 +1052,11 @@
|
||||||
#define VM_WATCH_EXIT (VM_RQ_BASE+43)
|
#define VM_WATCH_EXIT (VM_RQ_BASE+43)
|
||||||
# define VM_WE_EP m1_i1
|
# define VM_WE_EP m1_i1
|
||||||
|
|
||||||
|
#define VM_REMAP_RO (VM_RQ_BASE+44)
|
||||||
|
/* same args as VM_REMAP */
|
||||||
|
|
||||||
/* Total. */
|
/* Total. */
|
||||||
#define NR_VM_CALLS 44
|
#define NR_VM_CALLS 45
|
||||||
#define VM_CALL_MASK_SIZE BITMAP_CHUNKS(NR_VM_CALLS)
|
#define VM_CALL_MASK_SIZE BITMAP_CHUNKS(NR_VM_CALLS)
|
||||||
|
|
||||||
/* not handled as a normal VM call, thus at the end of the reserved rage */
|
/* not handled as a normal VM call, thus at the end of the reserved rage */
|
||||||
|
|
|
@ -30,6 +30,8 @@ _PROTOTYPE( int minix_munmap, (void *, size_t));
|
||||||
_PROTOTYPE( int minix_munmap_text, (void *, size_t));
|
_PROTOTYPE( int minix_munmap_text, (void *, size_t));
|
||||||
_PROTOTYPE( void *vm_remap, (endpoint_t d, endpoint_t s, void *da,
|
_PROTOTYPE( void *vm_remap, (endpoint_t d, endpoint_t s, void *da,
|
||||||
void *sa, size_t si));
|
void *sa, size_t si));
|
||||||
|
_PROTOTYPE( void *vm_remap_ro, (endpoint_t d, endpoint_t s, void *da,
|
||||||
|
void *sa, size_t si));
|
||||||
_PROTOTYPE( int vm_unmap, (endpoint_t endpt, void *addr));
|
_PROTOTYPE( int vm_unmap, (endpoint_t endpt, void *addr));
|
||||||
_PROTOTYPE( unsigned long vm_getphys, (endpoint_t endpt, void *addr));
|
_PROTOTYPE( unsigned long vm_getphys, (endpoint_t endpt, void *addr));
|
||||||
_PROTOTYPE( u8_t vm_getrefcount, (endpoint_t endpt, void *addr));
|
_PROTOTYPE( u8_t vm_getrefcount, (endpoint_t endpt, void *addr));
|
||||||
|
|
|
@ -76,6 +76,28 @@ PUBLIC void *vm_remap(endpoint_t d,
|
||||||
return (void *) m.VMRE_RETA;
|
return (void *) m.VMRE_RETA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PUBLIC void *vm_remap_ro(endpoint_t d,
|
||||||
|
endpoint_t s,
|
||||||
|
void *da,
|
||||||
|
void *sa,
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
message m;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
m.VMRE_D = d;
|
||||||
|
m.VMRE_S = s;
|
||||||
|
m.VMRE_DA = (char *) da;
|
||||||
|
m.VMRE_SA = (char *) sa;
|
||||||
|
m.VMRE_SIZE = size;
|
||||||
|
|
||||||
|
r = _syscall(VM_PROC_NR, VM_REMAP_RO, &m);
|
||||||
|
if (r != OK)
|
||||||
|
return MAP_FAILED;
|
||||||
|
return (void *) m.VMRE_RETA;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PUBLIC int vm_unmap(endpoint_t endpt, void *addr)
|
PUBLIC int vm_unmap(endpoint_t endpt, void *addr)
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
|
|
|
@ -85,6 +85,27 @@ PUBLIC void *vm_remap(endpoint_t d,
|
||||||
return (void *) m.VMRE_RETA;
|
return (void *) m.VMRE_RETA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PUBLIC void *vm_remap_ro(endpoint_t d,
|
||||||
|
endpoint_t s,
|
||||||
|
void *da,
|
||||||
|
void *sa,
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
message m;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
m.VMRE_D = d;
|
||||||
|
m.VMRE_S = s;
|
||||||
|
m.VMRE_DA = (char *) da;
|
||||||
|
m.VMRE_SA = (char *) sa;
|
||||||
|
m.VMRE_SIZE = size;
|
||||||
|
|
||||||
|
r = _syscall(VM_PROC_NR, VM_REMAP_RO, &m);
|
||||||
|
if (r != OK)
|
||||||
|
return MAP_FAILED;
|
||||||
|
return (void *) m.VMRE_RETA;
|
||||||
|
}
|
||||||
|
|
||||||
PUBLIC int vm_unmap(endpoint_t endpt, void *addr)
|
PUBLIC int vm_unmap(endpoint_t endpt, void *addr)
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
|
|
|
@ -10,6 +10,7 @@ service ipc
|
||||||
;
|
;
|
||||||
vm
|
vm
|
||||||
REMAP
|
REMAP
|
||||||
|
REMAP_RO
|
||||||
SHM_UNMAP
|
SHM_UNMAP
|
||||||
GETPHYS
|
GETPHYS
|
||||||
GETREF
|
GETREF
|
||||||
|
|
|
@ -361,6 +361,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
|
||||||
|
|
||||||
/* Generic calls. */
|
/* Generic calls. */
|
||||||
CALLMAP(VM_REMAP, do_remap);
|
CALLMAP(VM_REMAP, do_remap);
|
||||||
|
CALLMAP(VM_REMAP_RO, do_remap);
|
||||||
CALLMAP(VM_GETPHYS, do_get_phys);
|
CALLMAP(VM_GETPHYS, do_get_phys);
|
||||||
CALLMAP(VM_SHM_UNMAP, do_shared_unmap);
|
CALLMAP(VM_SHM_UNMAP, do_shared_unmap);
|
||||||
CALLMAP(VM_GETREF, do_get_refcount);
|
CALLMAP(VM_GETREF, do_get_refcount);
|
||||||
|
|
|
@ -231,6 +231,13 @@ PUBLIC int do_remap(message *m)
|
||||||
struct vir_region *region;
|
struct vir_region *region;
|
||||||
struct vmproc *dvmp, *svmp;
|
struct vmproc *dvmp, *svmp;
|
||||||
int r;
|
int r;
|
||||||
|
int readonly;
|
||||||
|
|
||||||
|
if(m->m_type == VM_REMAP)
|
||||||
|
readonly = 0;
|
||||||
|
else if(m->m_type == VM_REMAP_RO)
|
||||||
|
readonly = 1;
|
||||||
|
else panic("do_remap: can't be");
|
||||||
|
|
||||||
da = (vir_bytes) m->VMRE_DA;
|
da = (vir_bytes) m->VMRE_DA;
|
||||||
sa = (vir_bytes) m->VMRE_SA;
|
sa = (vir_bytes) m->VMRE_SA;
|
||||||
|
@ -275,7 +282,7 @@ PUBLIC int do_remap(message *m)
|
||||||
return EFAULT;
|
return EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = map_remap(dvmp, da, size, region, &startv)) != OK)
|
if ((r = map_remap(dvmp, da, size, region, &startv, readonly)) != OK)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
m->VMRE_RETA = (char *) arch_map2vir(dvmp, startv);
|
m->VMRE_RETA = (char *) arch_map2vir(dvmp, startv);
|
||||||
|
|
|
@ -86,11 +86,6 @@ PUBLIC void do_pagefaults(message *m)
|
||||||
*/
|
*/
|
||||||
assert(!(region->flags & VR_NOPF));
|
assert(!(region->flags & VR_NOPF));
|
||||||
|
|
||||||
/* We do not allow shared memory to cause pagefaults.
|
|
||||||
* These pages have to be pre-allocated.
|
|
||||||
*/
|
|
||||||
assert(!(region->flags & VR_SHARED));
|
|
||||||
|
|
||||||
/* If process was writing, see if it's writable. */
|
/* If process was writing, see if it's writable. */
|
||||||
if(!(region->flags & VR_WRITABLE) && wr) {
|
if(!(region->flags & VR_WRITABLE) && wr) {
|
||||||
printf("VM: pagefault: SIGSEGV %d ro map 0x%lx %s\n",
|
printf("VM: pagefault: SIGSEGV %d ro map 0x%lx %s\n",
|
||||||
|
|
|
@ -169,7 +169,7 @@ _PROTOTYPE(struct vir_region * map_region_lookup_tag, (struct vmproc *vmp, u32_t
|
||||||
_PROTOTYPE(void map_region_set_tag, (struct vir_region *vr, u32_t tag));
|
_PROTOTYPE(void map_region_set_tag, (struct vir_region *vr, u32_t tag));
|
||||||
_PROTOTYPE(u32_t map_region_get_tag, (struct vir_region *vr));
|
_PROTOTYPE(u32_t map_region_get_tag, (struct vir_region *vr));
|
||||||
_PROTOTYPE(int map_remap, (struct vmproc *dvmp, vir_bytes da, size_t size,
|
_PROTOTYPE(int map_remap, (struct vmproc *dvmp, vir_bytes da, size_t size,
|
||||||
struct vir_region *region, vir_bytes *r));
|
struct vir_region *region, vir_bytes *r, int ro));
|
||||||
_PROTOTYPE(int map_get_phys, (struct vmproc *vmp, vir_bytes addr, phys_bytes *r));
|
_PROTOTYPE(int map_get_phys, (struct vmproc *vmp, vir_bytes addr, phys_bytes *r));
|
||||||
_PROTOTYPE(int map_get_ref, (struct vmproc *vmp, vir_bytes addr, u8_t *cnt));
|
_PROTOTYPE(int map_get_ref, (struct vmproc *vmp, vir_bytes addr, u8_t *cnt));
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,9 @@ PRIVATE yielded_t *lru_youngest = NULL, *lru_oldest = NULL;
|
||||||
|
|
||||||
/* Should a physblock be mapped writable? */
|
/* Should a physblock be mapped writable? */
|
||||||
#define WRITABLE(r, pb) \
|
#define WRITABLE(r, pb) \
|
||||||
(((r)->flags & (VR_DIRECT | VR_SHARED)) || \
|
(((r)->flags & VR_WRITABLE) && \
|
||||||
(((r)->flags & VR_WRITABLE) && (pb)->refcount == 1))
|
(((r)->flags & (VR_DIRECT | VR_SHARED)) || \
|
||||||
|
(pb)->refcount == 1))
|
||||||
|
|
||||||
FORWARD _PROTOTYPE(int map_new_physblock, (struct vmproc *vmp,
|
FORWARD _PROTOTYPE(int map_new_physblock, (struct vmproc *vmp,
|
||||||
struct vir_region *region, vir_bytes offset, vir_bytes length,
|
struct vir_region *region, vir_bytes offset, vir_bytes length,
|
||||||
|
@ -1426,6 +1427,7 @@ PRIVATE struct vir_region *map_copy_region(struct vmproc *vmp, struct vir_region
|
||||||
newvr->lower = newvr->higher = NULL;
|
newvr->lower = newvr->higher = NULL;
|
||||||
newvr->phys = phavl;
|
newvr->phys = phavl;
|
||||||
);
|
);
|
||||||
|
|
||||||
physr_init(newvr->phys);
|
physr_init(newvr->phys);
|
||||||
|
|
||||||
physr_start_iter_least(vr->phys, &iter);
|
physr_start_iter_least(vr->phys, &iter);
|
||||||
|
@ -1806,7 +1808,7 @@ PUBLIC int map_unmap_region(struct vmproc *vmp, struct vir_region *r,
|
||||||
* map_remap *
|
* map_remap *
|
||||||
*========================================================================*/
|
*========================================================================*/
|
||||||
PUBLIC int map_remap(struct vmproc *dvmp, vir_bytes da, size_t size,
|
PUBLIC int map_remap(struct vmproc *dvmp, vir_bytes da, size_t size,
|
||||||
struct vir_region *region, vir_bytes *r)
|
struct vir_region *region, vir_bytes *r, int readonly)
|
||||||
{
|
{
|
||||||
struct vir_region *vr;
|
struct vir_region *vr;
|
||||||
struct phys_region *ph;
|
struct phys_region *ph;
|
||||||
|
@ -1843,7 +1845,11 @@ PUBLIC int map_remap(struct vmproc *dvmp, vir_bytes da, size_t size,
|
||||||
vr->length = size;
|
vr->length = size;
|
||||||
vr->flags = region->flags;
|
vr->flags = region->flags;
|
||||||
vr->tag = VRT_NONE;
|
vr->tag = VRT_NONE;
|
||||||
vr->parent = dvmp;);
|
vr->parent = dvmp;
|
||||||
|
if(readonly) {
|
||||||
|
vr->flags &= ~VR_WRITABLE;
|
||||||
|
}
|
||||||
|
);
|
||||||
assert(vr->flags & VR_SHARED);
|
assert(vr->flags & VR_SHARED);
|
||||||
|
|
||||||
region_insert(&dvmp->vm_regions_avl, vr);
|
region_insert(&dvmp->vm_regions_avl, vr);
|
||||||
|
|
Loading…
Reference in a new issue