# 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() */
/* 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 */
#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. */
#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. */
#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 */
/* 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. */
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);
/* 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 */
#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 */
+++ /dev/null
-#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 */
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;
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 *);
/* 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 */
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
do_privctl.c \
do_safecopy.c \
do_safememset.c \
- do_safemap.c \
do_sysctl.c \
do_getksig.c \
do_endksig.c \
}
/* 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
}
/*===========================================================================*
+++ /dev/null
-/* 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;
-}
-
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");
}
sys_profbuf.c \
sys_runctl.c \
sys_safecopy.c \
- sys_safemap.c \
sys_safememset.c \
sys_schedctl.c \
sys_schedule.c \
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;
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;
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;
#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; \
} \
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.
*/
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;
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;
+++ /dev/null
-
-#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, ©_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, ©_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, ©_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, ©_mess));
-}
-
case DS_CHECK:
result = do_check(&m);
break;
- case DS_SNAPSHOT:
- result = do_snapshot(&m);
- break;
case COMMON_GETSYSINFO:
result = do_getsysinfo(&m);
break;
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 *
*===========================================================================*/
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;
((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;
}
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)
}
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;
}
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);
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;
}
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 *
*===========================================================================*/
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;
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;
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;
}
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;
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);
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);
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 *
*===========================================================================*/
#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;
+++ /dev/null
-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
-
+++ /dev/null
-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.
-
+++ /dev/null
-#!/bin/sh
-
-service down grantor
-service down requestor
+++ /dev/null
-#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();
-}
-
+++ /dev/null
-#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
-
+++ /dev/null
-#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();
-}
-
+++ /dev/null
-#!/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
+++ /dev/null
-
-service requestor
-{
- system
- PRIVCTL # 4
- UMAP # 14
- ;
- uid 0;
-};
-
-service grantor
-{
- system
- PRIVCTL # 4
- UMAP # 14
- ;
- uid 0;
-};
+++ /dev/null
-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
-
+++ /dev/null
-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.
-
+++ /dev/null
-#!/bin/sh
-
-service down grantor
-service down requestor
-
+++ /dev/null
-#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();
-}
-
+++ /dev/null
-#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
-
+++ /dev/null
-#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();
-}
-
+++ /dev/null
-#!/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
-
+++ /dev/null
-
-service requestor
-{
- system
- PRIVCTL # 4
- UMAP # 14
- ;
- uid 0;
-};
-
-service grantor
-{
- system
- PRIVCTL # 4
- UMAP # 14
- ;
- uid 0;
-};