drop safemap code
This commit is contained in:
@@ -69,9 +69,6 @@ int main(int argc, char **argv)
|
||||
case DS_CHECK:
|
||||
result = do_check(&m);
|
||||
break;
|
||||
case DS_SNAPSHOT:
|
||||
result = do_snapshot(&m);
|
||||
break;
|
||||
case COMMON_GETSYSINFO:
|
||||
result = do_getsysinfo(&m);
|
||||
break;
|
||||
|
||||
@@ -166,21 +166,6 @@ static int get_key_name(const message *m_ptr, char *key_name)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* check_snapshot_index *
|
||||
*===========================================================================*/
|
||||
static int check_snapshot_index(const struct data_store *dsp, int index)
|
||||
{
|
||||
/* See if the given snapshot index is valid. */
|
||||
int min;
|
||||
|
||||
min = dsp->u.map.sindex < NR_DS_SNAPSHOT
|
||||
? 0
|
||||
: dsp->u.map.sindex - NR_DS_SNAPSHOT + 1;
|
||||
|
||||
return (index >= min && index <= dsp->u.map.sindex) ? 0 : 1;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* check_sub_match *
|
||||
*===========================================================================*/
|
||||
@@ -303,10 +288,6 @@ int do_publish(message *m_ptr)
|
||||
if((flags & DSF_TYPE_LABEL) && m_ptr->m_source != RS_PROC_NR)
|
||||
return EPERM;
|
||||
|
||||
/* MAP should not be overwritten. */
|
||||
if((flags & DSF_TYPE_MAP) && (flags & DSF_OVERWRITE))
|
||||
return EINVAL;
|
||||
|
||||
/* Get key name. */
|
||||
if((r = get_key_name(m_ptr, key_name)) != OK)
|
||||
return r;
|
||||
@@ -365,25 +346,6 @@ int do_publish(message *m_ptr)
|
||||
((char*)dsp->u.mem.data)[length-1] = '\0';
|
||||
}
|
||||
break;
|
||||
case DSF_TYPE_MAP:
|
||||
/* Allocate buffer, the address should be aligned by CLICK_SIZE. */
|
||||
length = m_ptr->DS_VAL_LEN;
|
||||
if((dsp->u.map.realpointer = malloc(length + CLICK_SIZE)) == NULL)
|
||||
return ENOMEM;
|
||||
dsp->u.map.data = (void*) CLICK_CEIL(dsp->u.map.realpointer);
|
||||
|
||||
/* Map memory. */
|
||||
r = sys_safemap(m_ptr->m_source, (cp_grant_id_t) m_ptr->DS_VAL, 0,
|
||||
(vir_bytes) dsp->u.map.data, length, 0);
|
||||
if(r != OK) {
|
||||
printf("DS: publish: memory map/copy failed from %d: %d\n",
|
||||
m_ptr->m_source, r);
|
||||
free(dsp->u.map.realpointer);
|
||||
return r;
|
||||
}
|
||||
dsp->u.map.length = length;
|
||||
dsp->u.map.sindex = -1;
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
@@ -409,8 +371,7 @@ int do_retrieve(message *m_ptr)
|
||||
int flags = m_ptr->DS_FLAGS;
|
||||
int type = flags & DSF_MASK_TYPE;
|
||||
size_t length;
|
||||
void *data;
|
||||
int index, r;
|
||||
int r;
|
||||
|
||||
/* Get key name. */
|
||||
if((r = get_key_name(m_ptr, key_name)) != OK)
|
||||
@@ -440,49 +401,6 @@ int do_retrieve(message *m_ptr)
|
||||
}
|
||||
m_ptr->DS_VAL_LEN = length;
|
||||
break;
|
||||
case DSF_TYPE_MAP:
|
||||
/* The caller requested to map a mapped memory range.
|
||||
* Create a MAP grant for the caller, the caller will do the
|
||||
* safemap itself later.
|
||||
*/
|
||||
if(flags & DSMF_MAP_MAPPED) {
|
||||
cp_grant_id_t gid;
|
||||
gid = cpf_grant_direct(m_ptr->m_source,
|
||||
(vir_bytes)dsp->u.map.data,
|
||||
dsp->u.map.length,
|
||||
CPF_READ|CPF_WRITE|CPF_MAP);
|
||||
if(!GRANT_VALID(gid))
|
||||
return -1;
|
||||
m_ptr->DS_VAL = gid;
|
||||
m_ptr->DS_VAL_LEN = dsp->u.map.length;
|
||||
}
|
||||
|
||||
/* The caller requested a copy of a mapped mem range or a snapshot. */
|
||||
else if(flags & (DSMF_COPY_MAPPED|DSMF_COPY_SNAPSHOT)) {
|
||||
if(flags & DSMF_COPY_MAPPED) {
|
||||
data = dsp->u.map.data;
|
||||
} else {
|
||||
index = m_ptr->DS_NR_SNAPSHOT;
|
||||
if(check_snapshot_index(dsp, index))
|
||||
return EINVAL;
|
||||
data = dsp->u.map.snapshots[index % NR_DS_SNAPSHOT];
|
||||
}
|
||||
|
||||
length = MIN(m_ptr->DS_VAL_LEN, dsp->u.map.length);
|
||||
r = sys_safecopyto(m_ptr->m_source,
|
||||
(cp_grant_id_t) m_ptr->DS_VAL, (vir_bytes) 0,
|
||||
(vir_bytes) data, length);
|
||||
if(r != OK) {
|
||||
printf("DS: retrieve: copy failed to %d: %d\n",
|
||||
m_ptr->m_source, r);
|
||||
return r;
|
||||
}
|
||||
m_ptr->DS_VAL_LEN = length;
|
||||
}
|
||||
else {
|
||||
return EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
@@ -647,7 +565,7 @@ int do_delete(message *m_ptr)
|
||||
char *source;
|
||||
char *label;
|
||||
int type = m_ptr->DS_FLAGS & DSF_MASK_TYPE;
|
||||
int top, i, r;
|
||||
int i, r;
|
||||
|
||||
/* Lookup the source. */
|
||||
source = ds_getprocname(m_ptr->m_source);
|
||||
@@ -694,25 +612,6 @@ int do_delete(message *m_ptr)
|
||||
case DSF_TYPE_MEM:
|
||||
free(dsp->u.mem.data);
|
||||
break;
|
||||
case DSF_TYPE_MAP:
|
||||
/* Unmap the mapped data. */
|
||||
r = sys_safeunmap((vir_bytes)dsp->u.map.data);
|
||||
if(r != OK)
|
||||
printf("DS: sys_safeunmap failed. Grant already revoked?\n");
|
||||
|
||||
/* Revoke all the mapped grants. */
|
||||
r = sys_saferevmap_addr((vir_bytes)dsp->u.map.data);
|
||||
if(r != OK)
|
||||
return r;
|
||||
|
||||
/* Free snapshots. */
|
||||
top = MIN(NR_DS_SNAPSHOT - 1, dsp->u.map.sindex);
|
||||
for(i = 0; i <= top; i++) {
|
||||
free(dsp->u.map.snapshots[i]);
|
||||
}
|
||||
|
||||
free(dsp->u.map.realpointer);
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
}
|
||||
@@ -726,47 +625,6 @@ int do_delete(message *m_ptr)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* do_snapshot *
|
||||
*===========================================================================*/
|
||||
int do_snapshot(message *m_ptr)
|
||||
{
|
||||
struct data_store *dsp;
|
||||
struct dsi_map *p;
|
||||
char key_name[DS_MAX_KEYLEN];
|
||||
int i, r;
|
||||
|
||||
/* Get key name. */
|
||||
if((r = get_key_name(m_ptr, key_name)) != OK)
|
||||
return r;
|
||||
|
||||
/* Lookup the entry. */
|
||||
if((dsp = lookup_entry(key_name, DSF_TYPE_MAP)) == NULL)
|
||||
return ESRCH;
|
||||
|
||||
if(!check_auth(dsp, m_ptr->m_source, DSF_PRIV_SNAPSHOT))
|
||||
return EPERM;
|
||||
|
||||
/* Find a snapshot slot. */
|
||||
p = &dsp->u.map;
|
||||
p->sindex++;
|
||||
i = p->sindex % DS_MAX_KEYLEN;
|
||||
if(p->sindex < DS_MAX_KEYLEN) {
|
||||
if((p->snapshots[i] = malloc(p->length)) == NULL) {
|
||||
p->sindex--;
|
||||
return ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* Store the snapshot. */
|
||||
memcpy(p->snapshots[i], p->data, p->length);
|
||||
|
||||
/* Copy the snapshot index. */
|
||||
m_ptr->DS_NR_SNAPSHOT = p->sindex;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* do_getsysinfo *
|
||||
*===========================================================================*/
|
||||
|
||||
@@ -34,10 +34,6 @@ void data_store_dmp()
|
||||
case DSF_TYPE_MEM:
|
||||
printf("%-10s %12u\n", "MEM", p->u.mem.length);
|
||||
break;
|
||||
case DSF_TYPE_MAP:
|
||||
printf("%-10s %9u/%3u\n", "MAP", p->u.map.length,
|
||||
p->u.map.sindex);
|
||||
break;
|
||||
case DSF_TYPE_LABEL:
|
||||
printf("%-10s %12u\n", "LABEL", p->u.u32);
|
||||
break;
|
||||
|
||||
@@ -83,12 +83,6 @@ static int anon_pagefault(struct vmproc *vmp, struct vir_region *region,
|
||||
|
||||
assert(region->flags & VR_WRITABLE);
|
||||
|
||||
if(ph->ph->share_flag != PBSH_COW) {
|
||||
printf("VM: write RO mapped pages.\n");
|
||||
free_mem(new_page_cl, 1);
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
if(sys_abscopy(ph->ph->phys, new_page, VM_PAGE_SIZE) != OK) {
|
||||
panic("VM: abscopy failed\n");
|
||||
return EFAULT;
|
||||
|
||||
@@ -140,15 +140,6 @@ void do_memory(void)
|
||||
|
||||
r = handle_memory(vmp, mem, len, wrflag);
|
||||
break;
|
||||
case VMPTYPE_COWMAP:
|
||||
r = map_memory(who_s, who, mem_s, mem, len, -1);
|
||||
break;
|
||||
case VMPTYPE_SMAP:
|
||||
r = map_memory(who_s, who, mem_s, mem, len, wrflag);
|
||||
break;
|
||||
case VMPTYPE_SUNMAP:
|
||||
r = unmap_memory(who_s, who, mem_s, mem, len, wrflag);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1201,13 +1201,6 @@ int map_writept(struct vmproc *vmp)
|
||||
while((ph = physr_get_iter(&ph_iter))) {
|
||||
physr_incr_iter(&ph_iter);
|
||||
|
||||
/* If this phys block is shared as SMAP, then do
|
||||
* not update the page table. */
|
||||
if(ph->ph->refcount > 1
|
||||
&& ph->ph->share_flag == PBSH_SMAP) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if((r=map_ph_writept(vmp, vr, ph)) != OK) {
|
||||
printf("VM: map_writept: failed\n");
|
||||
return r;
|
||||
@@ -1280,15 +1273,6 @@ struct vir_region *start_src_vr;
|
||||
pb = orig_ph->ph;
|
||||
assert(orig_ph->ph == new_ph->ph);
|
||||
|
||||
/* If the phys block has been shared as SMAP,
|
||||
* do the regular copy. */
|
||||
if(pb->refcount > 2 && pb->share_flag == PBSH_SMAP) {
|
||||
map_clone_ph_block(dst, newvr,new_ph,
|
||||
&iter_new);
|
||||
} else {
|
||||
USE(pb, pb->share_flag = PBSH_COW;);
|
||||
}
|
||||
|
||||
/* Get next new physregion */
|
||||
physr_incr_iter(&iter_orig);
|
||||
physr_incr_iter(&iter_new);
|
||||
@@ -1503,8 +1487,7 @@ void get_usage_info(struct vmproc *vmp, struct vm_usage_info *vui)
|
||||
vui->vui_common += VM_PAGE_SIZE;
|
||||
|
||||
/* Any common, non-COW page is shared. */
|
||||
if (vr->flags & VR_SHARED ||
|
||||
ph->ph->share_flag == PBSH_SMAP)
|
||||
if (vr->flags & VR_SHARED)
|
||||
vui->vui_shared += VM_PAGE_SIZE;
|
||||
}
|
||||
physr_incr_iter(&iter);
|
||||
@@ -1587,189 +1570,6 @@ void printregionstats(struct vmproc *vmp)
|
||||
return;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* do_map_memory *
|
||||
*===========================================================================*/
|
||||
static int do_map_memory(struct vmproc *vms, struct vmproc *vmd,
|
||||
struct vir_region *vrs, struct vir_region *vrd,
|
||||
vir_bytes offset_s, vir_bytes offset_d,
|
||||
vir_bytes length, int flag)
|
||||
{
|
||||
struct phys_region *prs;
|
||||
struct phys_region *newphysr;
|
||||
struct phys_block *pb;
|
||||
physr_iter iter;
|
||||
u32_t pt_flag = PTF_PRESENT | PTF_USER;
|
||||
vir_bytes end;
|
||||
|
||||
if(map_handle_memory(vms, vrs, offset_s, length, 0) != OK) {
|
||||
printf("do_map_memory: source cleaning up didn't work\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
/* Search for the first phys region in the source process. */
|
||||
physr_start_iter(vrs->phys, &iter, offset_s, AVL_EQUAL);
|
||||
prs = physr_get_iter(&iter);
|
||||
if(!prs)
|
||||
panic("do_map_memory: no aligned phys region");
|
||||
|
||||
/* flag: 0 -> read-only
|
||||
* 1 -> writable
|
||||
* -1 -> share as COW, so read-only
|
||||
*/
|
||||
if(flag > 0)
|
||||
pt_flag |= PTF_WRITE;
|
||||
else
|
||||
pt_flag |= PTF_READ;
|
||||
|
||||
/* Map phys blocks in the source process to the destination process. */
|
||||
end = offset_d + length;
|
||||
while((prs = physr_get_iter(&iter)) && offset_d < end) {
|
||||
/* If a SMAP share was requested but the phys block has already
|
||||
* been shared as COW, copy the block for the source phys region
|
||||
* first.
|
||||
*/
|
||||
pb = prs->ph;
|
||||
if(flag >= 0 && pb->refcount > 1
|
||||
&& pb->share_flag == PBSH_COW) {
|
||||
if(!(prs = map_clone_ph_block(vms, vrs, prs, &iter)))
|
||||
return ENOMEM;
|
||||
pb = prs->ph;
|
||||
}
|
||||
|
||||
/* Allocate a new phys region. */
|
||||
if(!(newphysr = pb_reference(pb, offset_d, vrd)))
|
||||
return ENOMEM;
|
||||
|
||||
/* If a COW share was requested but the phys block has already
|
||||
* been shared as SMAP, give up on COW and copy the block for
|
||||
* the destination phys region now.
|
||||
*/
|
||||
if(flag < 0 && pb->refcount > 1
|
||||
&& pb->share_flag == PBSH_SMAP) {
|
||||
if(!(newphysr = map_clone_ph_block(vmd, vrd,
|
||||
newphysr, NULL))) {
|
||||
return ENOMEM;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* See if this is a COW share or SMAP share. */
|
||||
if(flag < 0) { /* COW share */
|
||||
pb->share_flag = PBSH_COW;
|
||||
/* Update the page table for the src process. */
|
||||
pt_writemap(vms, &vms->vm_pt, offset_s + vrs->vaddr,
|
||||
pb->phys, VM_PAGE_SIZE,
|
||||
pt_flag, WMF_OVERWRITE);
|
||||
}
|
||||
else { /* SMAP share */
|
||||
pb->share_flag = PBSH_SMAP;
|
||||
}
|
||||
/* Update the page table for the destination process. */
|
||||
pt_writemap(vmd, &vmd->vm_pt, offset_d + vrd->vaddr,
|
||||
pb->phys, VM_PAGE_SIZE, pt_flag, WMF_OVERWRITE);
|
||||
}
|
||||
|
||||
physr_incr_iter(&iter);
|
||||
offset_d += VM_PAGE_SIZE;
|
||||
offset_s += VM_PAGE_SIZE;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* unmap_memory *
|
||||
*===========================================================================*/
|
||||
int unmap_memory(endpoint_t sour, endpoint_t dest,
|
||||
vir_bytes virt_s, vir_bytes virt_d, vir_bytes length, int flag)
|
||||
{
|
||||
struct vmproc *vmd;
|
||||
struct vir_region *vrd;
|
||||
struct phys_region *pr;
|
||||
struct phys_block *pb;
|
||||
physr_iter iter;
|
||||
vir_bytes off, end;
|
||||
int p;
|
||||
|
||||
/* Use information on the destination process to unmap. */
|
||||
if(vm_isokendpt(dest, &p) != OK)
|
||||
panic("unmap_memory: bad endpoint: %d", dest);
|
||||
vmd = &vmproc[p];
|
||||
|
||||
vrd = map_lookup(vmd, virt_d, NULL);
|
||||
assert(vrd);
|
||||
|
||||
/* Search for the first phys region in the destination process. */
|
||||
off = virt_d - vrd->vaddr;
|
||||
physr_start_iter(vrd->phys, &iter, off, AVL_EQUAL);
|
||||
pr = physr_get_iter(&iter);
|
||||
if(!pr)
|
||||
panic("unmap_memory: no aligned phys region");
|
||||
|
||||
/* Copy the phys block now rather than doing COW. */
|
||||
end = off + length;
|
||||
while((pr = physr_get_iter(&iter)) && off < end) {
|
||||
pb = pr->ph;
|
||||
assert(pb->refcount > 1);
|
||||
assert(pb->share_flag == PBSH_SMAP);
|
||||
|
||||
if(!(pr = map_clone_ph_block(vmd, vrd, pr, &iter)))
|
||||
return ENOMEM;
|
||||
|
||||
physr_incr_iter(&iter);
|
||||
off += VM_PAGE_SIZE;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* map_memory *
|
||||
*===========================================================================*/
|
||||
int map_memory(endpoint_t sour, endpoint_t dest,
|
||||
vir_bytes virt_s, vir_bytes virt_d, vir_bytes length, int flag)
|
||||
{
|
||||
/* This is the entry point. This function will be called by handle_memory() when
|
||||
* VM recieves a map-memory request.
|
||||
*/
|
||||
struct vmproc *vms, *vmd;
|
||||
struct vir_region *vrs, *vrd;
|
||||
vir_bytes offset_s, offset_d;
|
||||
int p;
|
||||
int r;
|
||||
|
||||
if(vm_isokendpt(sour, &p) != OK)
|
||||
panic("map_memory: bad endpoint: %d", sour);
|
||||
vms = &vmproc[p];
|
||||
if(vm_isokendpt(dest, &p) != OK)
|
||||
panic("map_memory: bad endpoint: %d", dest);
|
||||
vmd = &vmproc[p];
|
||||
|
||||
vrs = map_lookup(vms, virt_s, NULL);
|
||||
assert(vrs);
|
||||
vrd = map_lookup(vmd, virt_d, NULL);
|
||||
assert(vrd);
|
||||
|
||||
/* Linear address -> offset from start of vir region. */
|
||||
offset_s = virt_s - vrs->vaddr;
|
||||
offset_d = virt_d - vrd->vaddr;
|
||||
|
||||
/* Make sure that the range in the source process has been mapped
|
||||
* to physical memory.
|
||||
*/
|
||||
map_handle_memory(vms, vrs, offset_s, length, 0);
|
||||
|
||||
/* Prepare work. */
|
||||
|
||||
if((r=map_subfree(vrd, offset_d, length)) != OK) {
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Map memory. */
|
||||
r = do_map_memory(vms, vmd, vrs, vrd, offset_s, offset_d, length, flag);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* get_clean_phys_region *
|
||||
*===========================================================================*/
|
||||
|
||||
@@ -27,9 +27,6 @@ struct phys_block {
|
||||
#endif
|
||||
phys_bytes phys; /* physical memory */
|
||||
u8_t refcount; /* Refcount of these pages */
|
||||
#define PBSH_COW 1
|
||||
#define PBSH_SMAP 2
|
||||
u8_t share_flag; /* PBSH_COW or PBSH_SMAP */
|
||||
|
||||
/* what kind of memory is it? */
|
||||
mem_type_t *memtype;
|
||||
|
||||
Reference in New Issue
Block a user