drop safemap code

This commit is contained in:
Ben Gras 2012-10-25 16:38:38 +02:00
parent f1b9e8249b
commit 196021cd82
42 changed files with 6 additions and 1670 deletions

View file

@ -340,9 +340,6 @@
# define SYS_VTIMER (KERNEL_CALL + 45) /* sys_vtimer() */
# define SYS_RUNCTL (KERNEL_CALL + 46) /* sys_runctl() */
# define SYS_SAFEMAP (KERNEL_CALL + 47) /* sys_safemap() */
# define SYS_SAFEREVMAP (KERNEL_CALL + 48) /* sys_saferevmap() sys_saferevmap2() */
# define SYS_SAFEUNMAP (KERNEL_CALL + 49) /* sys_safeunmap() */
# define SYS_GETMCONTEXT (KERNEL_CALL + 50) /* sys_getmcontext() */
# define SYS_SETMCONTEXT (KERNEL_CALL + 51) /* sys_setmcontext() */
@ -362,8 +359,8 @@
/* Basic kernel calls allowed to every system process. */
#define SYS_BASIC_CALLS \
SYS_EXIT, SYS_SAFECOPYFROM, SYS_SAFECOPYTO, SYS_VSAFECOPY, SYS_GETINFO, \
SYS_TIMES, SYS_SETALARM, SYS_SETGRANT, SYS_SAFEMAP, SYS_SAFEREVMAP, \
SYS_SAFEUNMAP, SYS_PROFBUF, SYS_SYSCTL, SYS_STATECTL, SYS_SAFEMEMSET
SYS_TIMES, SYS_SETALARM, SYS_SETGRANT, \
SYS_PROFBUF, SYS_SYSCTL, SYS_STATECTL, SYS_SAFEMEMSET
/* Field names for SYS_MEMSET. */
#define MEM_PTR m2_p1 /* base */
@ -574,14 +571,6 @@
#define VSCP_VEC_ADDR m2_p1 /* start of vector */
#define VSCP_VEC_SIZE m2_l2 /* elements in vector */
/* Field names for SYS_SAFEMAPs */
#define SMAP_EP m2_i1
#define SMAP_GID m2_i2
#define SMAP_OFFSET m2_i3
#define SMAP_ADDRESS m2_l1
#define SMAP_BYTES m2_l2
#define SMAP_FLAG m2_s1
#define SMAP_SEG_OBSOLETE m2_p1
/* Field names for SYS_SPROF, _CPROF, _PROFBUF. */

View file

@ -15,7 +15,6 @@
#define DSF_TYPE_U32 0x010 /* u32 data type */
#define DSF_TYPE_STR 0x020 /* string data type */
#define DSF_TYPE_MEM 0x040 /* memory range data type */
#define DSF_TYPE_MAP 0x080 /* mapped memory range data type */
#define DSF_TYPE_LABEL 0x100 /* label data type */
#define DSF_MASK_TYPE 0xFF0 /* mask for type flags. */
@ -24,7 +23,6 @@
#define DSF_OVERWRITE 0x01000 /* overwrite if entry exists */
#define DSF_INITIAL 0x02000 /* check subscriptions immediately */
#define DSMF_MAP_MAPPED 0x10000 /* map mapped memory range */
#define DSMF_COPY_MAPPED 0x20000 /* copy mapped memory range */
#define DSMF_COPY_SNAPSHOT 0x40000 /* copy snapshot */

View file

@ -55,7 +55,6 @@ struct vscp_vec {
/* Operations: any combination is ok. */
#define CPF_READ 0x000001 /* Granted process may read. */
#define CPF_WRITE 0x000002 /* Granted process may write. */
#define CPF_MAP 0x000004 /* Granted process may map. */
/* Internal flags. */
#define CPF_USED 0x000100 /* Grant slot in use. */

View file

@ -153,13 +153,6 @@ int sys_safememset(endpoint_t source, cp_grant_id_t grant, vir_bytes
int sys_memset(endpoint_t who, unsigned long pattern,
phys_bytes base, phys_bytes bytes);
/* Grant-based map functions. */
int sys_safemap(endpoint_t grantor, cp_grant_id_t grant, vir_bytes
grant_offset, vir_bytes my_address, size_t bytes, int writable);
int sys_saferevmap_gid(cp_grant_id_t grant);
int sys_saferevmap_addr(vir_bytes addr);
int sys_safeunmap(vir_bytes my_address);
int sys_vumap(endpoint_t endpt, struct vumap_vir *vvec,
int vcount, size_t offset, int access, struct vumap_phys *pvec,
int *pcount);

View file

@ -35,9 +35,6 @@ int vm_yield_block_get_block(u64_t yieldid, u64_t getid, void *mem,
/* VM kernel request types. */
#define VMPTYPE_NONE 0
#define VMPTYPE_CHECK 1
#define VMPTYPE_COWMAP 2
#define VMPTYPE_SMAP 3
#define VMPTYPE_SUNMAP 4
struct vm_stats_info {
unsigned int vsi_pagesize; /* page size */

View file

@ -44,7 +44,6 @@
#include "glo.h" /* global variables */
#include "ipc.h" /* IPC constants */
#include "profile.h" /* system profiling */
#include "perf.h" /* performance-related definitions */
#include "proc.h" /* process table */
#include "cpulocals.h" /* CPU-local variables */
#include "debug.h" /* debugging, MUST be last kernel header */

View file

@ -1,9 +0,0 @@
#ifndef PERF_H
#define PERF_H
/* This header file defines all performance-related constants and macros. */
/* Enable copy-on-write optimization for safecopy. */
#define PERF_USE_COW_SAFECOPY 0
#endif /* PERF_H */

View file

@ -109,12 +109,6 @@ struct proc {
vir_bytes start, length; /* memory range */
u8_t writeflag; /* nonzero for write access */
} check;
struct {
char writeflag;
endpoint_t ep_s;
vir_bytes vir_s, vir_d;
vir_bytes length;
} map;
} params;
/* VM result when available */
int vmresult;

View file

@ -130,11 +130,6 @@ void hook_ipc_msgkresult(message *msg, struct proc *proc);
void hook_ipc_clear(struct proc *proc);
#endif
/* system/do_safemap.c */
int map_invoke_vm(struct proc * caller, int req_type, endpoint_t end_d,
vir_bytes off_d, endpoint_t end_s, vir_bytes
off_s, size_t size, int flag);
/* system/do_safecopy.c */
int verify_grant(endpoint_t, endpoint_t, cp_grant_id_t, vir_bytes, int,
vir_bytes, vir_bytes *, endpoint_t *);

View file

@ -231,11 +231,6 @@ void system_init(void)
/* safe memset */
map(SYS_SAFEMEMSET, do_safememset); /* safememset */
/* Mapping. */
map(SYS_SAFEMAP, do_safemap); /* map pages from other process */
map(SYS_SAFEREVMAP, do_saferevmap); /* grantor revokes the map grant */
map(SYS_SAFEUNMAP, do_safeunmap); /* requestor unmaps the mapped pages */
/* Clock functionality. */
map(SYS_TIMES, do_times); /* get uptime and process times */
map(SYS_SETALARM, do_setalarm); /* schedule a synchronous alarm */

View file

@ -180,10 +180,6 @@ int do_readbios(struct proc * caller, message *m_ptr);
int do_safememset(struct proc * caller, message *m_ptr);
int do_safemap(struct proc * caller, message *m_ptr);
int do_saferevmap(struct proc * caller, message *m_ptr);
int do_safeunmap(struct proc * caller, message *m_ptr);
int do_sprofile(struct proc * caller, message *m_ptr);
#if ! SPROFILE
#define do_sprofile NULL

View file

@ -24,7 +24,6 @@ SRCS+= \
do_privctl.c \
do_safecopy.c \
do_safememset.c \
do_safemap.c \
do_sysctl.c \
do_getksig.c \
do_endksig.c \

View file

@ -298,48 +298,7 @@ int access; /* CPF_READ for a copy from granter to grantee, CPF_WRITE
}
/* Do the regular copy. */
#if PERF_USE_COW_SAFECOPY
if(v_offset % CLICK_SIZE != addr % CLICK_SIZE || bytes < CLICK_SIZE) {
/* Give up on COW immediately when offsets are not aligned
* or we are copying less than a page.
*/
return virtual_copy_vmcheck(caller, &v_src, &v_dst, bytes);
}
if((size = v_offset % CLICK_SIZE) != 0) {
/* Normal copy for everything before the first page boundary. */
size = CLICK_SIZE - size;
r = virtual_copy_vmcheck(caller, &v_src, &v_dst, size);
if(r != OK)
return r;
v_src.offset += size;
v_dst.offset += size;
bytes -= size;
}
if((size = bytes / CLICK_SIZE) != 0) {
/* Use COW optimization when copying entire pages. */
size *= CLICK_SIZE;
r = map_invoke_vm(VMPTYPE_COWMAP,
v_dst.proc_nr_e, v_dst.segment, v_dst.offset,
v_src.proc_nr_e, v_src.segment, v_src.offset,
size, 0);
if(r != OK)
return r;
v_src.offset += size;
v_dst.offset += size;
bytes -= size;
}
if(bytes != 0) {
/* Normal copy for everything after the last page boundary. */
r = virtual_copy_vmcheck(caller, &v_src, &v_dst, bytes);
if(r != OK)
return r;
}
return OK;
#else
return virtual_copy_vmcheck(caller, &v_src, &v_dst, bytes);
#endif
}
/*===========================================================================*

View file

@ -1,267 +0,0 @@
/* The kernel call implemented in this file:
* m_type: SYS_SAFEMAP or SYS_SAFEREVMAP or SYS_SAFEUNMAP
*
* The parameters for this kernel call are:
* SMAP_EP endpoint of the grantor
* SMAP_GID grant id
* SMAP_OFFSET offset of the grant space
* SMAP_ADDRESS address
* SMAP_BYTES bytes to be copied
* SMAP_FLAG access, writable map or not?
*/
#include <assert.h>
#include "kernel/system.h"
#include "kernel.h"
#include <minix/safecopies.h>
#include <signal.h>
struct map_info_s {
int flag;
/* Grantor. */
endpoint_t grantor;
cp_grant_id_t gid;
vir_bytes offset;
vir_bytes address_Dseg; /* seg always is D */
/* Grantee. */
endpoint_t grantee;
vir_bytes address;
/* Length. */
vir_bytes bytes;
};
#define MAX_MAP_INFO 20
static struct map_info_s map_info[MAX_MAP_INFO];
/*===========================================================================*
* add_info *
*===========================================================================*/
static int add_info(endpoint_t grantor, endpoint_t grantee, cp_grant_id_t gid,
vir_bytes offset, vir_bytes address_Dseg,
vir_bytes address, vir_bytes bytes)
{
int i;
for(i = 0; i < MAX_MAP_INFO; i++) {
if(map_info[i].flag == 0)
break;
}
if(i == MAX_MAP_INFO)
return EBUSY;
map_info[i].flag = 1;
map_info[i].grantor = grantor;
map_info[i].grantee = grantee;
map_info[i].gid = gid;
map_info[i].address_Dseg = address_Dseg;
map_info[i].offset = offset;
map_info[i].address = address;
map_info[i].bytes = bytes;
return OK;
}
/*===========================================================================*
* get_revoke_info *
*===========================================================================*/
static struct map_info_s *get_revoke_info(endpoint_t grantor, int flag, int arg)
{
int i;
for(i = 0; i < MAX_MAP_INFO; i++) {
if(map_info[i].flag == 1
&& map_info[i].grantor == grantor
&& (flag ? (map_info[i].gid == arg)
: (map_info[i].address_Dseg == arg)))
return &map_info[i];
}
return NULL;
}
/*===========================================================================*
* get_unmap_info *
*===========================================================================*/
static struct map_info_s *get_unmap_info(endpoint_t grantee,
vir_bytes address)
{
int i;
for(i = 0; i < MAX_MAP_INFO; i++) {
if(map_info[i].flag == 1
&& map_info[i].grantee == grantee
&& map_info[i].address == address)
return &map_info[i];
}
return NULL;
}
/*===========================================================================*
* clear_info *
*===========================================================================*/
static void clear_info(struct map_info_s *p)
{
p->flag = 0;
}
/*===========================================================================*
* map_invoke_vm *
*===========================================================================*/
int map_invoke_vm(struct proc * caller,
int req_type, /* VMPTYPE_... COWMAP, SMAP, SUNMAP */
endpoint_t end_d, vir_bytes off_d,
endpoint_t end_s, vir_bytes off_s,
size_t size, int flag)
{
struct proc *dst;
dst = endpoint_lookup(end_d);
/* Make sure the linear addresses are both page aligned. */
if(off_s % CLICK_SIZE != 0 || off_d % CLICK_SIZE != 0) {
printf("map_invoke_vm: linear addresses not page aligned.\n");
return EINVAL;
}
assert(!RTS_ISSET(caller, RTS_VMREQUEST));
assert(!RTS_ISSET(caller, RTS_VMREQTARGET));
assert(!RTS_ISSET(dst, RTS_VMREQUEST));
assert(!RTS_ISSET(dst, RTS_VMREQTARGET));
RTS_SET(caller, RTS_VMREQUEST);
RTS_SET(dst, RTS_VMREQTARGET);
/* Map to the destination. */
caller->p_vmrequest.req_type = req_type;
caller->p_vmrequest.target = end_d; /* destination proc */
caller->p_vmrequest.params.map.vir_d = off_d; /* destination addr */
caller->p_vmrequest.params.map.ep_s = end_s; /* source process */
caller->p_vmrequest.params.map.vir_s = off_s; /* source address */
caller->p_vmrequest.params.map.length = (vir_bytes) size;
caller->p_vmrequest.params.map.writeflag = flag;
caller->p_vmrequest.type = VMSTYPE_MAP;
/* Connect caller on vmrequest wait queue. */
if(!(caller->p_vmrequest.nextrequestor = vmrequest))
if(OK != send_sig(VM_PROC_NR, SIGKMEM))
panic("send_sig failed");
vmrequest = caller;
return OK;
}
/*===========================================================================*
* do_safemap *
*===========================================================================*/
int do_safemap(struct proc * caller, message * m_ptr)
{
endpoint_t grantor = m_ptr->SMAP_EP;
cp_grant_id_t gid = (cp_grant_id_t) m_ptr->SMAP_GID;
vir_bytes offset = (vir_bytes) m_ptr->SMAP_OFFSET;
vir_bytes address = (vir_bytes) m_ptr->SMAP_ADDRESS;
vir_bytes bytes = (vir_bytes) m_ptr->SMAP_BYTES;
int flag = m_ptr->SMAP_FLAG;
vir_bytes offset_result;
endpoint_t new_grantor;
int r;
int access = CPF_MAP | CPF_READ;
/* Check the grant. We currently support safemap with both direct and
* indirect grants, as verify_grant() stores the original grantor
* transparently in new_grantor below. However, we maintain the original
* semantics associated to indirect grants only here at safemap time.
* After the mapping has been set up, if a process part of the chain
* of trust crashes or exits without revoking the mapping, the mapping
* can no longer be manually or automatically revoked for any of the
* processes lower in the chain. This solution reduces complexity but
* could be improved if we make the assumption that only one process in
* the chain of trust can effectively map the original memory region.
*/
if(flag != 0)
access |= CPF_WRITE;
r = verify_grant(grantor, caller->p_endpoint, gid, bytes, access,
offset, &offset_result, &new_grantor);
if(r != OK) {
printf("verify_grant for gid %d from %d to %d failed: %d\n",
gid, grantor, caller->p_endpoint, r);
return r;
}
/* Add map info. */
r = add_info(new_grantor, caller->p_endpoint, gid, offset,
offset_result, address, bytes);
if(r != OK)
return r;
/* Invoke VM. */
return map_invoke_vm(caller, VMPTYPE_SMAP,
caller->p_endpoint, address, new_grantor, offset_result, bytes,flag);
}
/*===========================================================================*
* safeunmap *
*===========================================================================*/
static int safeunmap(struct proc * caller, struct map_info_s *p)
{
vir_bytes offset_result;
endpoint_t new_grantor;
int r;
r = verify_grant(p->grantor, p->grantee, p->gid, p->bytes,
CPF_MAP, p->offset, &offset_result, &new_grantor);
if(r != OK) {
printf("safeunmap: error in verify_grant.\n");
return r;
}
r = map_invoke_vm(caller, VMPTYPE_SUNMAP,
p->grantee, p->address,
new_grantor, offset_result,
p->bytes, 0);
clear_info(p);
if(r != OK) {
printf("safeunmap: error in map_invoke_vm.\n");
return r;
}
return OK;
}
/*===========================================================================*
* do_saferevmap *
*===========================================================================*/
int do_saferevmap(struct proc * caller, message * m_ptr)
{
struct map_info_s *p;
int flag = m_ptr->SMAP_FLAG;
int arg = m_ptr->SMAP_GID; /* gid or address_Dseg */
int r;
while((p = get_revoke_info(caller->p_endpoint, flag, arg)) != NULL) {
if((r = safeunmap(caller, p)) != OK)
return r;
}
return OK;
}
/*===========================================================================*
* do_safeunmap *
*===========================================================================*/
int do_safeunmap(struct proc * caller, message * m_ptr)
{
vir_bytes address = (vir_bytes) m_ptr->SMAP_ADDRESS;
struct map_info_s *p;
int r;
while((p = get_unmap_info(caller->p_endpoint, address)) != NULL) {
if((r = safeunmap(caller, p)) != OK)
return r;
}
return OK;
}

View file

@ -59,26 +59,6 @@ int do_vmctl(struct proc * caller, message * m_ptr)
m_ptr->SVMCTL_MRG_REQUESTOR =
(void *) rp->p_endpoint;
break;
case VMPTYPE_SMAP:
case VMPTYPE_SUNMAP:
case VMPTYPE_COWMAP:
assert(RTS_ISSET(target,RTS_VMREQTARGET));
RTS_UNSET(target, RTS_VMREQTARGET);
m_ptr->SVMCTL_MRG_TARGET =
rp->p_vmrequest.target;
m_ptr->SVMCTL_MRG_ADDR =
rp->p_vmrequest.params.map.vir_d;
m_ptr->SVMCTL_MRG_EP2 =
rp->p_vmrequest.params.map.ep_s;
m_ptr->SVMCTL_MRG_ADDR2 =
rp->p_vmrequest.params.map.vir_s;
m_ptr->SVMCTL_MRG_LENGTH =
rp->p_vmrequest.params.map.length;
m_ptr->SVMCTL_MRG_FLAG =
rp->p_vmrequest.params.map.writeflag;
m_ptr->SVMCTL_MRG_REQUESTOR =
(void *) rp->p_endpoint;
break;
default:
panic("VMREQUEST wrong type");
}

View file

@ -52,7 +52,6 @@ SRCS= \
sys_profbuf.c \
sys_runctl.c \
sys_safecopy.c \
sys_safemap.c \
sys_safememset.c \
sys_schedctl.c \
sys_schedule.c \

View file

@ -83,29 +83,6 @@ int ds_publish_mem(const char *ds_name, void *vaddr, size_t length, int flags)
return ds_publish_raw(ds_name, vaddr, length, flags | DSF_TYPE_MEM);
}
int ds_publish_map(const char *ds_name, void *vaddr, size_t length, int flags)
{
cp_grant_id_t gid;
int r;
if(((vir_bytes)vaddr % CLICK_SIZE != 0) || (length % CLICK_SIZE != 0))
return EINVAL;
/* Grant for mapped memory range. */
gid = cpf_grant_direct(DS_PROC_NR, (vir_bytes)vaddr, length,
CPF_READ | CPF_MAP);
if(!GRANT_VALID(gid))
return errno;
m.DS_VAL = gid;
m.DS_VAL_LEN = length;
m.DS_FLAGS = DSF_TYPE_MAP | flags;
r = do_invoke_ds(DS_PUBLISH, ds_name);
return r;
}
int ds_snapshot_map(const char *ds_name, int *nr_snapshot)
{
int r;
@ -175,55 +152,6 @@ int ds_retrieve_mem(const char *ds_name, char *vaddr, size_t *length)
return ds_retrieve_raw(ds_name, vaddr, length, DSF_TYPE_MEM);
}
int ds_retrieve_map(const char *ds_name, char *vaddr, size_t *length,
int nr_snapshot, int flags)
{
cp_grant_id_t gid;
int r;
/* Map a mapped memory range. */
if(flags & DSMF_MAP_MAPPED) {
/* Request DS to grant. */
m.DS_FLAGS = DSF_TYPE_MAP | DSMF_MAP_MAPPED;
r = do_invoke_ds(DS_RETRIEVE, ds_name);
if(r != OK)
return r;
/* Do the safemap. */
if(*length > (size_t) m.DS_VAL_LEN)
*length = (size_t) m.DS_VAL_LEN;
*length = (size_t) CLICK_FLOOR(*length);
r = sys_safemap(DS_PROC_NR, m.DS_VAL, 0,
(vir_bytes)vaddr, *length, 0);
/* Copy mapped memory range or a snapshot. */
} else if(flags & (DSMF_COPY_MAPPED|DSMF_COPY_SNAPSHOT)) {
/* Grant for memory range first. */
gid = cpf_grant_direct(DS_PROC_NR, (vir_bytes)vaddr,
*length, CPF_WRITE);
if(!GRANT_VALID(gid))
return errno;
m.DS_VAL = gid;
m.DS_VAL_LEN = *length;
if(flags & DSMF_COPY_MAPPED) {
m.DS_FLAGS = DSF_TYPE_MAP | DSMF_COPY_MAPPED;
}
else {
m.DS_NR_SNAPSHOT = nr_snapshot;
m.DS_FLAGS = DSF_TYPE_MAP | DSMF_COPY_SNAPSHOT;
}
r = do_invoke_ds(DS_RETRIEVE, ds_name);
*length = m.DS_VAL_LEN;
cpf_revoke(gid);
}
else {
return EINVAL;
}
return r;
}
int ds_delete_u32(const char *ds_name)
{
m.DS_FLAGS = DSF_TYPE_U32;
@ -242,12 +170,6 @@ int ds_delete_mem(const char *ds_name)
return do_invoke_ds(DS_DELETE, ds_name);
}
int ds_delete_map(const char *ds_name)
{
m.DS_FLAGS = DSF_TYPE_MAP;
return do_invoke_ds(DS_DELETE, ds_name);
}
int ds_delete_label(const char *ds_name)
{
m.DS_FLAGS = DSF_TYPE_LABEL;

View file

@ -16,7 +16,7 @@
#include <string.h>
#define ACCESS_CHECK(a) { \
if((a) & ~(CPF_READ|CPF_WRITE|CPF_MAP)) { \
if((a) & ~(CPF_READ|CPF_WRITE)) { \
errno = EINVAL; \
return -1; \
} \
@ -213,16 +213,8 @@ int
cpf_revoke(cp_grant_id_t g)
{
/* Revoke previously granted access, identified by grant id. */
int r;
GID_CHECK_USED(g);
/* If this grant is for memory mapping, revoke the mapping first. */
if(grants[g].cp_flags & CPF_MAP) {
r = sys_saferevmap_gid(g);
if(r != 0)
return r;
}
/* Make grant invalid by setting flags to 0, clearing CPF_USED.
* This invalidates the grant.
*/
@ -274,11 +266,6 @@ int access;
GID_CHECK(gid);
ACCESS_CHECK(access);
/* Check click alignment in case of memory mapping grant. */
if(access & CPF_MAP) {
CLICK_ALIGNMENT_CHECK(addr, bytes);
}
/* Fill in new slot data. */
grants[gid].cp_flags = access | CPF_DIRECT | CPF_USED | CPF_VALID;
grants[gid].cp_u.cp_direct.cp_who_to = who;
@ -316,11 +303,6 @@ int access;
GID_CHECK(gid);
ACCESS_CHECK(access);
/* Check click alignment in case of memory mapping grant. */
if(access & CPF_MAP) {
CLICK_ALIGNMENT_CHECK(addr, bytes);
}
/* Fill in new slot data. */
grants[gid].cp_flags = CPF_USED | CPF_MAGIC | CPF_VALID | access;
grants[gid].cp_u.cp_magic.cp_who_to = who_to;

View file

@ -1,74 +0,0 @@
#include "syslib.h"
#include <minix/safecopies.h>
/*===========================================================================*
* sys_safemap *
*===========================================================================*/
int sys_safemap(endpoint_t grantor, cp_grant_id_t grant,
vir_bytes grant_offset, vir_bytes my_address,
size_t bytes, int writable)
{
/* Map a block of data for which the other process has previously
* granted permission.
*/
message copy_mess;
copy_mess.SMAP_EP = grantor;
copy_mess.SMAP_GID = grant;
copy_mess.SMAP_OFFSET = grant_offset;
copy_mess.SMAP_ADDRESS = my_address;
copy_mess.SMAP_BYTES = bytes;
copy_mess.SMAP_FLAG = writable;
copy_mess.SMAP_SEG_OBSOLETE = (void *) D_OBSOLETE;
return(_kernel_call(SYS_SAFEMAP, &copy_mess));
}
/*===========================================================================*
* sys_saferevmap_gid *
*===========================================================================*/
int sys_saferevmap_gid(cp_grant_id_t grant)
{
/* Grantor revokes safemap by grant id. */
message copy_mess;
copy_mess.SMAP_FLAG = 1;
copy_mess.SMAP_GID = grant;
return(_kernel_call(SYS_SAFEREVMAP, &copy_mess));
}
/*===========================================================================*
* sys_saferevmap_addr *
*===========================================================================*/
int sys_saferevmap_addr(vir_bytes addr)
{
/* Grantor revokes safemap by address. */
message copy_mess;
copy_mess.SMAP_FLAG = 0;
copy_mess.SMAP_GID = addr;
return(_kernel_call(SYS_SAFEREVMAP, &copy_mess));
}
/*===========================================================================*
* sys_safeunmap *
*===========================================================================*/
int sys_safeunmap(vir_bytes my_address)
{
/* Requestor unmaps safemap. */
message copy_mess;
copy_mess.SMAP_ADDRESS = my_address;
copy_mess.SMAP_SEG_OBSOLETE = (void *) D_OBSOLETE;
return(_kernel_call(SYS_SAFEUNMAP, &copy_mess));
}

View file

@ -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;

View file

@ -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 *
*===========================================================================*/

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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 *
*===========================================================================*/

View file

@ -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;

View file

@ -1,21 +0,0 @@
all: requestor grantor 1fifo 2fifo
chmod +x down run
requestor: requestor.c inc.h
cc -static -o $@ $< -lsys -lminlib -lcompat_minix
grantor: grantor.c inc.h
cc -static -o $@ $< -lsys -lminlib -lcompat_minix
1fifo 2fifo:
mkfifo $@
run: all
sh run
kill:
sh down
clean:
rm -f grantor requestor 1fifo 2fifo

View file

@ -1,8 +0,0 @@
Test Program for Safemap
How to run
==========
1. Type `make run` to prepare and run test.
2. When done testing, type `make clean` to clean up.

View file

@ -1,4 +0,0 @@
#!/bin/sh
service down grantor
service down requestor

View file

@ -1,129 +0,0 @@
#include "inc.h"
char buf_buf[BUF_SIZE + CLICK_SIZE];
int fid_send, fid_get;
/* SEF functions and variables. */
static void sef_local_startup(void);
/*===========================================================================*
* main *
*===========================================================================*/
int main(int argc, char **argv)
{
endpoint_t ep_self, ep_requestor, ep_child;
cp_grant_id_t gid;
int i, r, pid;
char *buf;
int status;
/* SEF local startup. */
env_setargs(argc, argv);
sef_local_startup();
/* Prepare work. */
buf = (char*) CLICK_CEIL(buf_buf);
fid_send = open(FIFO_GRANTOR, O_WRONLY);
fid_get = open(FIFO_REQUESTOR, O_RDONLY);
if(fid_get < 0 || fid_send < 0) {
printf("GRANTOR: can't open fifo files.\n");
return 1;
}
/* Get the requestor's endpoint. */
read(fid_get, &ep_requestor, sizeof(ep_requestor));
dprint("GRANTOR: getting requestor's endpoint: %d\n", ep_requestor);
/* Grant. */
gid = cpf_grant_direct(ep_requestor, (long)buf, BUF_SIZE,
CPF_READ | CPF_WRITE | CPF_MAP);
ep_self = getprocnr();
dprint("GRANTOR: sending my endpoint %d and gid %d\n", ep_self, gid);
write(fid_send, &ep_self, sizeof(ep_self));
write(fid_send, &gid, sizeof(gid));
/* Test MAP. */
buf[0] = BUF_START_GRANTOR;
FIFO_NOTIFY(fid_send);
FIFO_WAIT(fid_get);
CHECK_TEST("GRANTOR", buf[0], BUF_START_REQUESTOR, "MAP");
/* Test UNMAP. */
buf[0] = BUF_START_GRANTOR;
FIFO_NOTIFY(fid_send);
FIFO_WAIT(fid_get);
CHECK_TEST("GRANTOR", buf[0], BUF_START_GRANTOR, "UNMAP");
/* Test REVOKE. */
r = sys_saferevmap_gid(gid);
if(r != OK) {
printf("GRANTOR: error in sys_saferevmap_gid: %d\n", r);
return 1;
}
buf[0] = BUF_START_GRANTOR+1;
FIFO_NOTIFY(fid_send);
FIFO_WAIT(fid_get);
CHECK_TEST("GRANTOR", buf[0], BUF_START_GRANTOR+1, "REVOKE");
/* Test SMAP_COW. */
FIFO_NOTIFY(fid_send);
FIFO_WAIT(fid_get);
buf[0] = BUF_START_GRANTOR;
FIFO_NOTIFY(fid_send);
FIFO_WAIT(fid_get);
CHECK_TEST("GRANTOR", buf[0], BUF_START_GRANTOR, "SMAP_COW");
/* Test COW_SMAP. */
r = sys_saferevmap_gid(gid);
if(r != OK) {
printf("GRANTOR: error in sys_saferevmap_gid: %d\n", r);
return 1;
}
buf[0] = BUF_START_GRANTOR+1;
pid = fork();
if(pid < 0) {
printf("GRANTOR: error in fork.\n");
return 1;
}
if(pid == 0) {
buf[0] = BUF_START_GRANTOR+2;
exit(0);
}
FIFO_NOTIFY(fid_send);
FIFO_WAIT(fid_get);
ep_child = getnprocnr(pid);
if ((r = sys_privctl(ep_child, SYS_PRIV_SET_USER, NULL)) != OK) {
printf("GRANTOR: unable to set privileges: %d\n", r);
return 1;
}
if ((r = sys_privctl(ep_child, SYS_PRIV_ALLOW, NULL)) != OK) {
printf("GRANTOR: child process can't run: %d\n", r);
return 1;
}
wait(&status);
FIFO_NOTIFY(fid_send);
CHECK_TEST("GRANTOR", buf[0], BUF_START_GRANTOR+1, "COW_SMAP");
/* Test COW_SMAP2 (with COW safecopy). */
r = sys_saferevmap_gid(gid);
if(r != OK) {
printf("GRANTOR: error in sys_saferevmap_gid: %d\n", r);
return 1;
}
FIFO_NOTIFY(fid_send);
FIFO_WAIT(fid_get);
CHECK_TEST("GRANTOR", buf[0], BUF_START_REQUESTOR, "COW_SMAP2");
return 0;
}
/*===========================================================================*
* sef_local_startup *
*===========================================================================*/
static void sef_local_startup()
{
/* Let SEF perform startup. */
sef_startup();
}

View file

@ -1,54 +0,0 @@
#define _SYSTEM
#define _MINIX
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <minix/config.h>
#include <minix/com.h>
#include <minix/type.h>
#include <minix/const.h>
#include <minix/endpoint.h>
#include <minix/safecopies.h>
#include <minix/syslib.h>
#include <minix/sysutil.h>
#include <errno.h>
#define TEST_PAGE_NUM 4
#define BUF_SIZE (TEST_PAGE_NUM * CLICK_SIZE)
#define BUF_START_REQUESTOR 10
#define BUF_START_GRANTOR 20
#define FIFO_REQUESTOR "/usr/src/test/safemap/1fifo"
#define FIFO_GRANTOR "/usr/src/test/safemap/2fifo"
#define FIFO_WAIT(fid) { \
int a; \
if(read(fid, &a, sizeof(a)) != sizeof(a)) \
panic( "FIFO_WAIT failed"); \
}
#define FIFO_NOTIFY(fid) { \
int a = 1; \
if(write(fid, &a, sizeof(a)) != sizeof(a)) \
panic( "FIFO_NOTIFY failed"); \
}
#define CHECK_TEST(who, result, expected, test_name) { \
printf("%-9s: test %s %s\n", who, test_name, \
(expected == result ? "succeeded" : "failed")); \
if(expected != result) { \
exit(1); \
} \
}
#define DEBUG 0
#if DEBUG
# define dprint printf
#else
# define dprint (void)
#endif

View file

@ -1,153 +0,0 @@
#include "inc.h"
char buf_buf[BUF_SIZE + CLICK_SIZE];
endpoint_t ep_granter;
cp_grant_id_t gid;
char *buf;
int fid_send, fid_get;
/* SEF functions and variables. */
static void sef_local_startup(void);
/*===========================================================================*
* main *
*===========================================================================*/
int main(int argc, char **argv)
{
endpoint_t ep_self, ep_child;
size_t size = BUF_SIZE;
int i, r, pid;
int status;
/* SEF local startup. */
env_setargs(argc, argv);
sef_local_startup();
/* Prepare work. */
buf = (char*) CLICK_CEIL(buf_buf);
fid_get = open(FIFO_GRANTOR, O_RDONLY);
fid_send = open(FIFO_REQUESTOR, O_WRONLY);
if(fid_get < 0 || fid_send < 0) {
printf("REQUESTOR: can't open fifo files.\n");
return 1;
}
/* Send the endpoint to the granter, in order to let him to
* create the grant.
*/
ep_self = getprocnr();
write(fid_send, &ep_self, sizeof(ep_self));
dprint("REQUESTOR: sending my endpoint: %d\n", ep_self);
/* Get the granter's endpoint and gid. */
read(fid_get, &ep_granter, sizeof(ep_granter));
read(fid_get, &gid, sizeof(gid));
dprint("REQUESTOR: getting granter's endpoint %d and gid %d\n",
ep_granter, gid);
/* Test MAP. */
FIFO_WAIT(fid_get);
r = sys_safemap(ep_granter, gid, 0, (long)buf, size, 1);
if(r != OK) {
printf("REQUESTOR: error in sys_safemap: %d\n", r);
return 1;
}
CHECK_TEST("REQUESTOR", buf[0], BUF_START_GRANTOR, "MAP");
buf[0] = BUF_START_REQUESTOR;
r = sys_safeunmap((long)buf);
if(r != OK) {
printf("REQUESTOR: error in sys_safeunmap: %d\n", r);
return 1;
}
FIFO_NOTIFY(fid_send);
/* Test UNMAP. */
FIFO_WAIT(fid_get);
CHECK_TEST("REQUESTOR", buf[0], BUF_START_REQUESTOR, "UNMAP");
r = sys_safemap(ep_granter, gid, 0, (long)buf, size, 1);
if(r != 0) {
printf("REQUESTOR: error in sys_safemap: %d\n", r);
return 1;
}
FIFO_NOTIFY(fid_send);
/* Test REVOKE. */
FIFO_WAIT(fid_get);
CHECK_TEST("REQUESTOR", buf[0], BUF_START_GRANTOR, "REVOKE");
buf[0] = BUF_START_REQUESTOR;
FIFO_NOTIFY(fid_send);
/* Test SMAP_COW. */
FIFO_WAIT(fid_get);
r = sys_safemap(ep_granter, gid, 0, (long)buf, size, 1);
if(r != OK) {
printf("REQUESTOR: error in sys_safemap: %d\n", r);
return 1;
}
buf[0] = BUF_START_REQUESTOR;
pid = fork();
if(pid < 0) {
printf("REQUESTOR: error in fork\n");
return 1;
}
if(pid == 0) {
exit(buf[0] != BUF_START_REQUESTOR);
}
FIFO_NOTIFY(fid_send);
FIFO_WAIT(fid_get);
ep_child = getnprocnr(pid);
if ((r = sys_privctl(ep_child, SYS_PRIV_SET_USER, NULL)) != OK) {
printf("REQUESTOR: unable to set privileges: %d\n", r);
return 1;
}
if ((r = sys_privctl(ep_child, SYS_PRIV_ALLOW, NULL)) != OK) {
printf("REQUESTOR: child process can't run: %d\n", r);
return 1;
}
wait(&status);
FIFO_NOTIFY(fid_send);
CHECK_TEST("REQUESTOR", buf[0], BUF_START_GRANTOR, "SMAP_COW");
CHECK_TEST("REQUESTOR", 1, WIFEXITED(status)
&& (WEXITSTATUS(status) == 0), "SMAP_COW child");
/* Test COW_SMAP. */
FIFO_WAIT(fid_get);
buf[0] = BUF_START_REQUESTOR;
r = sys_safemap(ep_granter, gid, 0, (long)buf, size, 1);
if(r != OK) {
printf("REQUESTOR: error in sys_safemap: %d\n", r);
return 1;
}
FIFO_NOTIFY(fid_send);
FIFO_WAIT(fid_get);
CHECK_TEST("REQUESTOR", buf[0], BUF_START_GRANTOR+1, "COW_SMAP");
/* Test COW_SMAP2 (with COW safecopy). */
FIFO_WAIT(fid_get);
buf[0] = BUF_START_REQUESTOR;
r = sys_safecopyto(ep_granter, gid, 0, (long)buf, size);
if(r != OK) {
printf("REQUESTOR: error in sys_safecopyto: %d\n", r);
return 1;
}
r = sys_safemap(ep_granter, gid, 0, (long)buf, size, 1);
if(r != OK) {
printf("REQUESTOR: error in sys_safemap: %d\n", r);
return 1;
}
FIFO_NOTIFY(fid_send);
CHECK_TEST("REQUESTOR", buf[0], BUF_START_REQUESTOR, "COW_SMAP2");
return 0;
}
/*===========================================================================*
* sef_local_startup *
*===========================================================================*/
static void sef_local_startup()
{
/* Let SEF perform startup. */
sef_startup();
}

View file

@ -1,6 +0,0 @@
#!/bin/sh
PWD=`pwd`
service up ${PWD}/grantor -config ${PWD}/system.conf -script ${PWD}/down
service up ${PWD}/requestor -config ${PWD}/system.conf -script ${PWD}/down

View file

@ -1,18 +0,0 @@
service requestor
{
system
PRIVCTL # 4
UMAP # 14
;
uid 0;
};
service grantor
{
system
PRIVCTL # 4
UMAP # 14
;
uid 0;
};

View file

@ -1,21 +0,0 @@
all: requestor grantor 1fifo 2fifo
chmod +x down run
requestor: requestor.c inc.h
cc -o $@ $< -lsys
grantor: grantor.c inc.h
cc -o $@ $< -lsys
1fifo 2fifo:
mkfifo $@
run: all
sh run
kill:
sh down
clean:
rm -f grantor requestor 1fifo 2fifo

View file

@ -1,11 +0,0 @@
Performance Test Program for Safecopy and Safemap
How to run
==========
1. Set USE_COW_SAFECOPY to 1 or 0 in kernel/system/do_safecopy.c
to run safecopy tests with or without COW optimization.
2. Type `make run` to prepare and run tests. Configuration parameters
for performance tests are in ./run.
3. When done testing, type `make clean` to clean up.

View file

@ -1,5 +0,0 @@
#!/bin/sh
service down grantor
service down requestor

View file

@ -1,62 +0,0 @@
#include "inc.h"
char buf_buf[BUF_SIZE + CLICK_SIZE];
int fid_send, fid_get;
/* SEF functions and variables. */
static void sef_local_startup(void);
/*===========================================================================*
* main *
*===========================================================================*/
int main(int argc, char **argv)
{
endpoint_t ep_self, ep_requestor, ep_child;
cp_grant_id_t gid;
int i, r, pid;
char *buf;
int status;
/* SEF local startup. */
env_setargs(argc, argv);
sef_local_startup();
/* Prepare work. */
buf = (char*) CLICK_CEIL(buf_buf);
fid_send = open(FIFO_GRANTOR, O_WRONLY);
fid_get = open(FIFO_REQUESTOR, O_RDONLY);
if(fid_get < 0 || fid_send < 0) {
printf("GRANTOR: can't open fifo files.\n");
return 1;
}
/* Get the requestor's endpoint. */
read(fid_get, &ep_requestor, sizeof(ep_requestor));
dprint("GRANTOR: getting requestor's endpoint: %d\n", ep_requestor);
/* Grant. */
gid = cpf_grant_direct(ep_requestor, (long)buf, BUF_SIZE,
CPF_READ | CPF_WRITE | CPF_MAP);
ep_self = getprocnr();
dprint("GRANTOR: sending my endpoint %d and gid %d\n", ep_self, gid);
write(fid_send, &ep_self, sizeof(ep_self));
write(fid_send, &gid, sizeof(gid));
/* Test safemap. */
buf[0] = 0;
FIFO_NOTIFY(fid_send);
FIFO_WAIT(fid_get);
return 0;
}
/*===========================================================================*
* sef_local_startup *
*===========================================================================*/
static void sef_local_startup()
{
/* Let SEF perform startup. */
sef_startup();
}

View file

@ -1,51 +0,0 @@
#define _SYSTEM
#define _MINIX
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <minix/config.h>
#include <minix/com.h>
#include <minix/type.h>
#include <minix/const.h>
#include <minix/endpoint.h>
#include <minix/safecopies.h>
#include <minix/syslib.h>
#include <minix/sysutil.h>
#include <errno.h>
#define TEST_PAGE_NUM 50
#define BUF_SIZE (TEST_PAGE_NUM * CLICK_SIZE)
#define NR_TEST_ITERATIONS 100
#define FIFO_REQUESTOR "/usr/src/test/safeperf/1fifo"
#define FIFO_GRANTOR "/usr/src/test/safeperf/2fifo"
#define FIFO_WAIT(fid) { \
int a; \
if(read(fid, &a, sizeof(a)) != sizeof(a)) \
panic( "FIFO_WAIT failed"); \
}
#define FIFO_NOTIFY(fid) { \
int a = 1; \
if(write(fid, &a, sizeof(a)) != sizeof(a)) \
panic( "FIFO_NOTIFY failed"); \
}
#define REPORT_TEST(who, test_name, diff) { \
printf("%-9s: test %s took an average of %d.%dus per page\n", \
who, test_name, (int)diff, ((int)(diff*1000))%1000); \
}
#define DEBUG 0
#if DEBUG
# define dprint printf
#else
# define dprint (void)
#endif

View file

@ -1,166 +0,0 @@
#include "inc.h"
char buf_buf[BUF_SIZE + CLICK_SIZE];
endpoint_t ep_granter;
cp_grant_id_t gid;
char *buf;
int fid_send, fid_get;
/* SEF functions and variables. */
static void sef_local_startup(void);
/*===========================================================================*
* read_write_buff *
*===========================================================================*/
void read_write_buff(char* buff, int size, int is_write)
{
int i;
char c;
if(size % CLICK_SIZE != 0) {
panic("buff_size not page aligned");
}
if(is_write) {
for(i=0;i<size;i+=CLICK_SIZE) buff[i] = 1;
}
else {
for(i=0;i<size;i+=CLICK_SIZE) c = buff[i];
}
}
/*===========================================================================*
* exit_usage *
*===========================================================================*/
void exit_usage(void)
{
printf("Usage: requestor pages=<nr_pages> map=<0|1> write=<0|1>\n");
exit(1);
}
/*===========================================================================*
* main *
*===========================================================================*/
int main(int argc, char **argv)
{
endpoint_t ep_self, ep_child;
size_t size = BUF_SIZE;
int i, r, pid;
int status;
u64_t start, end, diff;
double micros;
char nr_pages_str[10], is_map_str[2], is_write_str[2];
int nr_pages, is_map, is_write;
/* SEF local startup. */
env_setargs(argc, argv);
sef_local_startup();
/* Parse the command line. */
r = env_get_param("pages", nr_pages_str, sizeof(nr_pages_str));
errno = 0;
nr_pages = atoi(nr_pages_str);
if (r != OK || errno || nr_pages <=0) {
exit_usage();
}
if(nr_pages > TEST_PAGE_NUM) {
printf("REQUESTOR: too many pages. Max allowed: %d\n",
TEST_PAGE_NUM);
exit_usage();
}
r = env_get_param("map", is_map_str, sizeof(is_map_str));
errno = 0;
is_map = atoi(is_map_str);
if (r != OK || errno || (is_map!=0 && is_map!=1)) {
exit_usage();
}
r = env_get_param("write", is_write_str, sizeof(is_write_str));
errno = 0;
is_write = atoi(is_write_str);
if (r != OK || errno || (is_write!=0 && is_write!=1)) {
exit_usage();
}
printf("REQUESTOR: Running tests with pages=%d map=%d write=%d...\n",
nr_pages, is_map, is_write);
/* Prepare work. */
buf = (char*) CLICK_CEIL(buf_buf);
fid_get = open(FIFO_GRANTOR, O_RDONLY);
fid_send = open(FIFO_REQUESTOR, O_WRONLY);
if(fid_get < 0 || fid_send < 0) {
printf("REQUESTOR: can't open fifo files.\n");
return 1;
}
/* Send the endpoint to the granter, in order to let him to
* create the grant.
*/
ep_self = getprocnr();
write(fid_send, &ep_self, sizeof(ep_self));
dprint("REQUESTOR: sending my endpoint: %d\n", ep_self);
/* Get the granter's endpoint and gid. */
read(fid_get, &ep_granter, sizeof(ep_granter));
read(fid_get, &gid, sizeof(gid));
dprint("REQUESTOR: getting granter's endpoint %d and gid %d\n",
ep_granter, gid);
FIFO_WAIT(fid_get);
diff = make64(0, 0);
if(is_map) {
/* Test safemap. */
for(i=0;i<NR_TEST_ITERATIONS;i++) {
read_tsc_64(&start);
r = sys_safemap(ep_granter, gid, 0, (long)buf,
nr_pages*CLICK_SIZE, D, 1);
if(r != OK) {
printf("REQUESTOR: safemap error: %d\n", r);
return 1;
}
read_write_buff(buf, nr_pages*CLICK_SIZE, is_write);
read_tsc_64(&end);
diff = add64(diff, (sub64(end, start)));
r = sys_safeunmap(D, (long)buf);
if(r != OK) {
printf("REQUESTOR: safeunmap error: %d\n", r);
return 1;
}
}
micros = ((double)tsc_64_to_micros(diff))
/ (NR_TEST_ITERATIONS*nr_pages);
REPORT_TEST("REQUESTOR", "SAFEMAP", micros);
}
else {
/* Test safecopy. */
for(i=0;i<NR_TEST_ITERATIONS;i++) {
read_tsc_64(&start);
r = sys_safecopyfrom(ep_granter, gid, 0, (long)buf,
nr_pages*CLICK_SIZE);
if(r != OK) {
printf("REQUESTOR: safecopy error: %d\n", r);
return 1;
}
read_write_buff(buf, nr_pages*CLICK_SIZE, is_write);
read_tsc_64(&end);
diff = add64(diff, (sub64(end, start)));
}
micros = ((double)tsc_64_to_micros(diff))
/ (NR_TEST_ITERATIONS*nr_pages);
REPORT_TEST("REQUESTOR", "SAFECOPY", micros);
}
FIFO_NOTIFY(fid_send);
return 0;
}
/*===========================================================================*
* sef_local_startup *
*===========================================================================*/
static void sef_local_startup()
{
/* Let SEF perform startup. */
sef_startup();
}

View file

@ -1,16 +0,0 @@
#!/bin/sh
PAGES="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50"
MAP=0
WRITE=1
PWD=`pwd`
for P in `echo $PAGES`
do
service up ${PWD}/grantor -config ${PWD}/system.conf -script ${PWD}/down
service up ${PWD}/requestor -config ${PWD}/system.conf -script ${PWD}/down \
-args pages=${P}\ map=${MAP}\ write=${WRITE}
sleep 2
done

View file

@ -1,18 +0,0 @@
service requestor
{
system
PRIVCTL # 4
UMAP # 14
;
uid 0;
};
service grantor
{
system
PRIVCTL # 4
UMAP # 14
;
uid 0;
};