Added vectored variant of sys_safecopy*.

This commit is contained in:
Ben Gras 2006-06-23 11:54:03 +00:00
parent 82855e9cf5
commit d402047222
7 changed files with 140 additions and 66 deletions

View file

@ -288,8 +288,9 @@
# define SYS_VM_MAP (KERNEL_CALL + 30) /* sys_vm_map() */ # define SYS_VM_MAP (KERNEL_CALL + 30) /* sys_vm_map() */
# define SYS_SAFECOPYFROM (KERNEL_CALL + 31) /* sys_safecopyfrom() */ # define SYS_SAFECOPYFROM (KERNEL_CALL + 31) /* sys_safecopyfrom() */
# define SYS_SAFECOPYTO (KERNEL_CALL + 32) /* sys_safecopyto() */ # define SYS_SAFECOPYTO (KERNEL_CALL + 32) /* sys_safecopyto() */
# define SYS_VSAFECOPY (KERNEL_CALL + 33) /* sys_vsafecopy() */
#define NR_SYS_CALLS 33 /* number of system calls */ #define NR_SYS_CALLS 34 /* number of system calls */
/* Pseudo call for use in kernel/table.c. */ /* Pseudo call for use in kernel/table.c. */
#define SYS_ALL_CALLS (NR_SYS_CALLS) #define SYS_ALL_CALLS (NR_SYS_CALLS)
@ -472,7 +473,7 @@
/* Field names for SYS_INT86 */ /* Field names for SYS_INT86 */
#define INT86_REG86 m1_p1 /* pointer to registers */ #define INT86_REG86 m1_p1 /* pointer to registers */
/* Field names for SYS_SAFECOPY */ /* Field names for SYS_SAFECOPY* */
#define SCP_FROM_TO m2_i1 /* from/to whom? */ #define SCP_FROM_TO m2_i1 /* from/to whom? */
#define SCP_INFO m2_i2 /* byte: DDDDSSSS Dest and Src seg */ #define SCP_INFO m2_i2 /* byte: DDDDSSSS Dest and Src seg */
#define SCP_GID m2_i3 /* grant id */ #define SCP_GID m2_i3 /* grant id */
@ -480,6 +481,10 @@
#define SCP_ADDRESS m2_p1 /* my own address */ #define SCP_ADDRESS m2_p1 /* my own address */
#define SCP_BYTES m2_l2 /* bytes from offset */ #define SCP_BYTES m2_l2 /* bytes from offset */
/* Field names for SYS_VSAFECOPY* */
#define VSCP_VEC_ADDR m2_p1 /* start of vector */
#define VSCP_VEC_SIZE m2_l2 /* elements in vector */
/* For the SCP_INFO field: encoding and decoding. */ /* For the SCP_INFO field: encoding and decoding. */
#define SCP_MAKEINFO(seg) ((seg) & 0xffff) #define SCP_MAKEINFO(seg) ((seg) & 0xffff)
#define SCP_INFO2SEG(info) ((info) & 0xffff) #define SCP_INFO2SEG(info) ((info) & 0xffff)

View file

@ -18,6 +18,7 @@
#define NULL ((void *)0) /* null pointer */ #define NULL ((void *)0) /* null pointer */
#define CPVEC_NR 16 /* max # of entries in a SYS_VCOPY request */ #define CPVEC_NR 16 /* max # of entries in a SYS_VCOPY request */
#define CPVVEC_NR 64 /* max # of entries in a SYS_VCOPY request */ #define CPVVEC_NR 64 /* max # of entries in a SYS_VCOPY request */
#define SCPVEC_NR 64 /* max # of entries in a SYS_VSAFECOPY* request */
#define NR_IOREQS MIN(NR_BUFS, 64) #define NR_IOREQS MIN(NR_BUFS, 64)
/* maximum number of entries in an iorequest */ /* maximum number of entries in an iorequest */

View file

@ -37,6 +37,18 @@ typedef struct {
char cp_reserved[8]; /* future use */ char cp_reserved[8]; /* future use */
} cp_grant_t; } cp_grant_t;
/* Vectored safecopy. */
struct vscp_vec {
/* Exactly one of the following must be SELF. */
endpoint_t v_from; /* source */
endpoint_t v_to; /* destination */
cp_grant_id_t v_gid; /* grant id of other process */
size_t v_offset; /* offset in other grant */
vir_bytes v_addr; /* address in copier's space */
size_t v_bytes; /* no. of bytes */
};
/* Invalid grant number. */ /* Invalid grant number. */
#define GRANT_INVALID -1 #define GRANT_INVALID -1
#define GRANT_VALID(g) ((g) > GRANT_INVALID) #define GRANT_VALID(g) ((g) > GRANT_INVALID)

View file

@ -97,10 +97,12 @@ _PROTOTYPE(int sys_physcopy, (endpoint_t src_proc, int src_seg, vir_bytes src_vi
endpoint_t dst_proc, int dst_seg, vir_bytes dst_vir, phys_bytes bytes)); endpoint_t dst_proc, int dst_seg, vir_bytes dst_vir, phys_bytes bytes));
_PROTOTYPE(int sys_safecopyfrom, (endpoint_t, cp_grant_id_t, /* Grant-based copy functions. */
vir_bytes, vir_bytes, size_t, int)); _PROTOTYPE(int sys_safecopyfrom, (endpoint_t source, cp_grant_id_t grant,
_PROTOTYPE(int sys_safecopyto, (endpoint_t, cp_grant_id_t, vir_bytes grant_offset, vir_bytes my_address, size_t bytes, int my_seg));
vir_bytes, vir_bytes, size_t, int)); _PROTOTYPE(int sys_safecopyto, (endpoint_t dest, cp_grant_id_t grant,
vir_bytes grant_offset, vir_bytes my_address, size_t bytes, int my_seg));
_PROTOTYPE(int sys_vsafecopy, (struct vscp_vec *copyvec, int elements));
_PROTOTYPE(int sys_memset, (unsigned long pattern, _PROTOTYPE(int sys_memset, (unsigned long pattern,
phys_bytes base, phys_bytes bytes)); phys_bytes base, phys_bytes bytes));

View file

@ -178,6 +178,7 @@ PRIVATE void initialize(void)
map(SYS_PHYSVCOPY, do_physvcopy); /* vector with copy requests */ map(SYS_PHYSVCOPY, do_physvcopy); /* vector with copy requests */
map(SYS_SAFECOPYFROM, do_safecopy); /* copy with pre-granted permission */ map(SYS_SAFECOPYFROM, do_safecopy); /* copy with pre-granted permission */
map(SYS_SAFECOPYTO, do_safecopy); /* copy with pre-granted permission */ map(SYS_SAFECOPYTO, do_safecopy); /* copy with pre-granted permission */
map(SYS_VSAFECOPY, do_vsafecopy); /* vectored safecopy */
/* Clock functionality. */ /* Clock functionality. */
map(SYS_TIMES, do_times); /* get uptime and process times */ map(SYS_TIMES, do_times); /* get uptime and process times */

View file

@ -174,6 +174,7 @@ _PROTOTYPE( int do_setalarm, (message *m_ptr) );
#endif #endif
_PROTOTYPE( int do_safecopy, (message *m_ptr) ); _PROTOTYPE( int do_safecopy, (message *m_ptr) );
_PROTOTYPE( int do_vsafecopy, (message *m_ptr) );
_PROTOTYPE( int do_iopenable, (message *m_ptr) ); _PROTOTYPE( int do_iopenable, (message *m_ptr) );
#endif /* SYSTEM_H */ #endif /* SYSTEM_H */

View file

@ -8,6 +8,10 @@
* SCP_OFFSET offset within granted space * SCP_OFFSET offset within granted space
* SCP_ADDRESS address in own address space * SCP_ADDRESS address in own address space
* SCP_BYTES bytes to be copied * SCP_BYTES bytes to be copied
*
* For the vectored variant (do_vsafecopy):
* VSCP_VEC_ADDR address of vector
* VSCP_VEC_SIZE number of significant elements in vector
*/ */
#include "../system.h" #include "../system.h"
@ -16,6 +20,8 @@
#define MEM_TOP 0xFFFFFFFFUL #define MEM_TOP 0xFFFFFFFFUL
FORWARD _PROTOTYPE(int safecopy, (endpoint_t, endpoint_t, cp_grant_id_t, int, int, size_t, vir_bytes, vir_bytes, int));
/*===========================================================================* /*===========================================================================*
* verify_grant * * verify_grant *
*===========================================================================*/ *===========================================================================*/
@ -129,9 +135,6 @@ endpoint_t *e_granter; /* new granter (magic grants) */
/* Currently, it is hardcoded that only FS may do /* Currently, it is hardcoded that only FS may do
* magic grants. * magic grants.
*/ */
#if 0
kprintf("magic grant ..\n");
#endif
if(granter != FS_PROC_NR) { if(granter != FS_PROC_NR) {
kprintf("magic grant verify failed: granter (%d) " kprintf("magic grant verify failed: granter (%d) "
"is not FS (%d)\n", granter, FS_PROC_NR); "is not FS (%d)\n", granter, FS_PROC_NR);
@ -171,58 +174,42 @@ endpoint_t *e_granter; /* new granter (magic grants) */
return EPERM; return EPERM;
} }
#if 0
kprintf("grant verify successful %d -> %d (grant %d): %d bytes\n",
granter, grantee, grant, bytes);
#endif
return OK; return OK;
} }
/*===========================================================================* /*===========================================================================*
* do_safecopy * * safecopy *
*===========================================================================*/ *===========================================================================*/
PUBLIC int do_safecopy(m_ptr) PRIVATE int safecopy(granter, grantee, grantid, src_seg, dst_seg, bytes,
register message *m_ptr; /* pointer to request message */ g_offset, addr, access)
{ endpoint_t granter, grantee;
static endpoint_t granter, grantee, *src, *dst, new_granter; cp_grant_id_t grantid;
static int access, r, src_seg, dst_seg; int src_seg, dst_seg;
static struct vir_addr v_src, v_dst; size_t bytes;
static vir_bytes offset, bytes; vir_bytes g_offset, addr;
int access; /* CPF_READ for a copy from granter to grantee, CPF_WRITE
granter = m_ptr->SCP_FROM_TO; * for a copy from grantee to granter.
grantee = who_e;
/* Set src and dst. One of these is always the caller (who_e),
* depending on whether the call was SYS_SAFECOPYFROM or
* SYS_SAFECOPYTO. The caller's seg is encoded in the SCP_INFO
* field.
*/ */
if(sys_call_code == SYS_SAFECOPYFROM) { {
static struct vir_addr v_src, v_dst;
static vir_bytes v_offset;
int r;
endpoint_t new_granter, *src, *dst;
/* Decide who is src and who is dst. */
if(access & CPF_READ) {
src = &granter; src = &granter;
dst = &grantee; dst = &grantee;
src_seg = D; } else {
dst_seg = SCP_INFO2SEG(m_ptr->SCP_INFO);
access = CPF_READ;
} else if(sys_call_code == SYS_SAFECOPYTO) {
src = &grantee; src = &grantee;
dst = &granter; dst = &granter;
src_seg = SCP_INFO2SEG(m_ptr->SCP_INFO); }
dst_seg = D;
access = CPF_WRITE;
} else panic("Impossible system call nr. ", sys_call_code);
#if 0
kprintf("safecopy: %d -> %d\n", *src, *dst);
#endif
bytes = m_ptr->SCP_BYTES;
/* Verify permission exists. */ /* Verify permission exists. */
if((r=verify_grant(granter, grantee, m_ptr->SCP_GID, bytes, access, if((r=verify_grant(granter, grantee, grantid, bytes, access,
m_ptr->SCP_OFFSET, &offset, &new_granter)) != OK) { g_offset, &v_offset, &new_granter)) != OK) {
kprintf("grant %d verify to copy %d->%d by %d failed: err %d\n", kprintf("grant %d verify to copy %d->%d by %d failed: err %d\n",
m_ptr->SCP_GID, *src, *dst, grantee, r); grantid, *src, *dst, grantee, r);
return r; return r;
} }
@ -230,9 +217,6 @@ register message *m_ptr; /* pointer to request message */
* meaning the source or destination changes. * meaning the source or destination changes.
*/ */
granter = new_granter; granter = new_granter;
#if 0
kprintf("verified safecopy: %d -> %d\n", *src, *dst);
#endif
/* Now it's a regular copy. */ /* Now it's a regular copy. */
v_src.segment = src_seg; v_src.segment = src_seg;
@ -241,29 +225,97 @@ register message *m_ptr; /* pointer to request message */
v_dst.proc_nr_e = *dst; v_dst.proc_nr_e = *dst;
/* Now the offset in virtual addressing is known in 'offset'. /* Now the offset in virtual addressing is known in 'offset'.
* Depending on the call, this is the source or destination * Depending on the access, this is the source or destination
* address. * address.
*/ */
if(sys_call_code == SYS_SAFECOPYFROM) { if(access & CPF_READ) {
v_src.offset = offset; v_src.offset = v_offset;
v_dst.offset = (vir_bytes) m_ptr->SCP_ADDRESS; v_dst.offset = (vir_bytes) addr;
} else { } else {
v_src.offset = (vir_bytes) m_ptr->SCP_ADDRESS; v_src.offset = (vir_bytes) addr;
v_dst.offset = offset; v_dst.offset = v_offset;
} }
#if 0
kprintf("copy 0x%lx (%d) in %d to 0x%lx (%d) in %d (%d bytes)\n",
v_src.offset, v_src.segment, *src,
v_dst.offset, v_dst.segment, *dst,
bytes);
#endif
#if DEBUG_SAFE_COUNT
unsafe_copy_log(0,0);
#endif
/* Do the regular copy. */ /* Do the regular copy. */
return virtual_copy(&v_src, &v_dst, bytes); return virtual_copy(&v_src, &v_dst, bytes);
}
/*===========================================================================*
* do_safecopy *
*===========================================================================*/
PUBLIC int do_safecopy(m_ptr)
register message *m_ptr; /* pointer to request message */
{
static endpoint_t new_granter;
static int access, src_seg, dst_seg;
/* Set src and dst parameters.
* The caller's seg is encoded in the SCP_INFO field.
*/
if(sys_call_code == SYS_SAFECOPYFROM) {
src_seg = D;
dst_seg = SCP_INFO2SEG(m_ptr->SCP_INFO);
access = CPF_READ;
} else if(sys_call_code == SYS_SAFECOPYTO) {
src_seg = SCP_INFO2SEG(m_ptr->SCP_INFO);
dst_seg = D;
access = CPF_WRITE;
} else panic("Impossible system call nr. ", sys_call_code);
return safecopy(m_ptr->SCP_FROM_TO, who_e, m_ptr->SCP_GID,
src_seg, dst_seg, m_ptr->SCP_BYTES, m_ptr->SCP_OFFSET,
(vir_bytes) m_ptr->SCP_ADDRESS, access);
}
/*===========================================================================*
* do_vsafecopy *
*===========================================================================*/
PUBLIC int do_vsafecopy(m_ptr)
register message *m_ptr; /* pointer to request message */
{
static struct vscp_vec vec[SCPVEC_NR];
static struct vir_addr src, dst;
int r, i, els;
/* Set vector copy parameters. */
src.proc_nr_e = who_e;
src.offset = (vir_bytes) m_ptr->VSCP_VEC_ADDR;
src.segment = dst.segment = D;
dst.proc_nr_e = SYSTEM;
dst.offset = (vir_bytes) vec;
/* No. of vector elements. */
els = m_ptr->VSCP_VEC_SIZE;
/* Obtain vector of copies. */
if((r=virtual_copy(&src, &dst, els * sizeof(struct vscp_vec))) != OK)
return r;
/* Perform safecopies. */
for(i = 0; i < els; i++) {
int access;
endpoint_t granter;
if(vec[i].v_from == SELF) {
access = CPF_WRITE;
granter = vec[i].v_to;
} else if(vec[i].v_to == SELF) {
access = CPF_READ;
granter = vec[i].v_from;
} else {
kprintf("vsafecopy: %d: element %d/%d: no SELF found\n",
who_e, i, els);
return EINVAL;
}
/* Do safecopy for this element. */
if((r=safecopy(granter, who_e, vec[i].v_gid, D, D,
vec[i].v_bytes, vec[i].v_offset,
vec[i].v_addr, access)) != OK) {
return r;
}
}
return OK;
} }