drop safemap code
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user