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