Added vectored variant of sys_safecopy*.
This commit is contained in:
parent
82855e9cf5
commit
d402047222
7 changed files with 140 additions and 66 deletions
|
@ -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)
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue