]> Zhao Yanbai Git Server - minix.git/commitdiff
Added vectored variant of sys_safecopy*.
authorBen Gras <ben@minix3.org>
Fri, 23 Jun 2006 11:54:03 +0000 (11:54 +0000)
committerBen Gras <ben@minix3.org>
Fri, 23 Jun 2006 11:54:03 +0000 (11:54 +0000)
include/minix/com.h
include/minix/const.h
include/minix/safecopies.h
include/minix/syslib.h
kernel/system.c
kernel/system.h
kernel/system/do_safecopy.c

index 21029691c140b206a15fd0f8d497cf804b20da52..05468f3966eac09168e6098a8c6a1464790cb650 100755 (executable)
 #  define SYS_VM_MAP    (KERNEL_CALL + 30)     /* sys_vm_map() */
 #  define SYS_SAFECOPYFROM  (KERNEL_CALL + 31) /* sys_safecopyfrom() */
 #  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. */
 #define SYS_ALL_CALLS (NR_SYS_CALLS)
 /* Field names for SYS_INT86 */
 #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_INFO       m2_i2   /* byte: DDDDSSSS Dest and Src seg */
 #define SCP_GID                m2_i3   /* grant id */
 #define        SCP_ADDRESS     m2_p1   /* my own address */
 #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. */
 #define SCP_MAKEINFO(seg)  ((seg) & 0xffff)
 #define SCP_INFO2SEG(info) ((info) & 0xffff)
index bc31f82eb3799dd53fdeed325214aa765c4717bf..4e18ead18964f9a750b06c4197aed5d4b1d81818 100755 (executable)
@@ -18,6 +18,7 @@
 #define NULL     ((void *)0)   /* null pointer */
 #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 SCPVEC_NR        64    /* max # of entries in a SYS_VSAFECOPY* request */
 #define NR_IOREQS      MIN(NR_BUFS, 64)
                                /* maximum number of entries in an iorequest */
 
index 3a79cffdccf1afc4429b02588c40f75d7ad9cf27..ae1a603489ae7b976befda912cd7b3e15aa58249 100644 (file)
@@ -37,6 +37,18 @@ typedef struct {
        char cp_reserved[8];                            /* future use */
 } 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. */
 #define GRANT_INVALID  -1
 #define GRANT_VALID(g) ((g) > GRANT_INVALID)
index 1d63366457a026982ecec7af18cc2322b6cfe97f..b72d81474b66887d13bf8fb00e42bc8e21d4866c 100755 (executable)
@@ -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));
 
 
-_PROTOTYPE(int sys_safecopyfrom, (endpoint_t, cp_grant_id_t,
-       vir_bytes, vir_bytes, size_t, int));
-_PROTOTYPE(int sys_safecopyto, (endpoint_t, cp_grant_id_t,
-       vir_bytes, vir_bytes, size_t, int));
+/* Grant-based copy functions. */
+_PROTOTYPE(int sys_safecopyfrom, (endpoint_t source, cp_grant_id_t grant,
+       vir_bytes grant_offset, vir_bytes my_address, size_t bytes, int my_seg));
+_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, 
                phys_bytes base, phys_bytes bytes));
index 61b226504c41ac6e2a25742433adb45033fb3bae..c28ed3717cc8b1f1ddcdb009e4fab0a34e35dddf 100755 (executable)
@@ -178,6 +178,7 @@ PRIVATE void initialize(void)
   map(SYS_PHYSVCOPY, do_physvcopy);    /* vector with copy requests */
   map(SYS_SAFECOPYFROM, 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. */
   map(SYS_TIMES, do_times);            /* get uptime and process times */
index 0935495ccf715ad65828ef78956b8fcdcb416eac..74c6906adce2f52c681fa91888eb89c02b359cba 100644 (file)
@@ -174,6 +174,7 @@ _PROTOTYPE( int do_setalarm, (message *m_ptr) );
 #endif
 
 _PROTOTYPE( int do_safecopy, (message *m_ptr) );       
+_PROTOTYPE( int do_vsafecopy, (message *m_ptr) );      
 _PROTOTYPE( int do_iopenable, (message *m_ptr) );      
 
 #endif /* SYSTEM_H */
index 154192809bc5638c46fb17ee4bbef844a876e6f0..4b0e26b24c8742c83d60759fe5275b1e5149fe46 100644 (file)
@@ -8,6 +8,10 @@
  *     SCP_OFFSET      offset within granted space
  *     SCP_ADDRESS     address in own address space
  *     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"
@@ -16,6 +20,8 @@
 
 #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                                 *
  *===========================================================================*/
@@ -129,9 +135,6 @@ endpoint_t *e_granter;              /* new granter (magic grants) */
                /* Currently, it is hardcoded that only FS may do
                 * magic grants.
                 */
-#if 0
-               kprintf("magic grant ..\n");
-#endif
                if(granter != FS_PROC_NR) {
                        kprintf("magic grant verify failed: granter (%d) "
                                "is not FS (%d)\n", granter, FS_PROC_NR);
@@ -171,58 +174,42 @@ endpoint_t *e_granter;            /* new granter (magic grants) */
                return EPERM;
        }
 
-#if 0
-       kprintf("grant verify successful %d -> %d (grant %d): %d bytes\n",
-               granter, grantee, grant, bytes);
-#endif
-
        return OK;
 }
 
 /*===========================================================================*
- *                             do_safecopy                                  *
+ *                             safecopy                                     *
  *===========================================================================*/
-PUBLIC int do_safecopy(m_ptr)
-register message *m_ptr;       /* pointer to request message */
+PRIVATE int safecopy(granter, grantee, grantid, src_seg, dst_seg, bytes,
+       g_offset, addr, access)
+endpoint_t granter, grantee;
+cp_grant_id_t grantid;
+int src_seg, dst_seg;
+size_t bytes;
+vir_bytes g_offset, addr;
+int access;                    /* CPF_READ for a copy from granter to grantee, CPF_WRITE
+                                * for a copy from grantee to granter.
+                                */
 {
-       static endpoint_t granter, grantee, *src, *dst, new_granter;
-       static int access, r, src_seg, dst_seg;
        static struct vir_addr v_src, v_dst;
-       static vir_bytes offset, bytes;
+       static vir_bytes v_offset;
+       int r;
+       endpoint_t new_granter, *src, *dst;
 
-       granter = m_ptr->SCP_FROM_TO;
-       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) {
+       /* Decide who is src and who is dst. */
+       if(access & CPF_READ) {
                src = &granter;
                dst = &grantee;
-               src_seg = D;
-               dst_seg = SCP_INFO2SEG(m_ptr->SCP_INFO);
-               access = CPF_READ;
-       } else if(sys_call_code == SYS_SAFECOPYTO) {
+       } else {
                src = &grantee;
                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. */
-       if((r=verify_grant(granter, grantee, m_ptr->SCP_GID, bytes, access,
-           m_ptr->SCP_OFFSET, &offset, &new_granter)) != OK) {
+       if((r=verify_grant(granter, grantee, grantid, bytes, access,
+           g_offset, &v_offset, &new_granter)) != OK) {
                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;
        }
 
@@ -230,9 +217,6 @@ register message *m_ptr;    /* pointer to request message */
         * meaning the source or destination changes.
         */
        granter = new_granter;
-#if 0
-       kprintf("verified safecopy: %d -> %d\n", *src, *dst);
-#endif
 
        /* Now it's a regular copy. */
        v_src.segment = src_seg;
@@ -241,29 +225,97 @@ register message *m_ptr;  /* pointer to request message */
        v_dst.proc_nr_e = *dst;
 
        /* 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.
         */
-       if(sys_call_code == SYS_SAFECOPYFROM) {
-               v_src.offset = offset;
-               v_dst.offset = (vir_bytes) m_ptr->SCP_ADDRESS;
+       if(access & CPF_READ) {
+               v_src.offset = v_offset;
+               v_dst.offset = (vir_bytes) addr;
        } else {
-               v_src.offset = (vir_bytes) m_ptr->SCP_ADDRESS;
-               v_dst.offset = offset;
+               v_src.offset = (vir_bytes) addr;
+               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. */
        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;
 }