Example #1
0
/*===========================================================================*
 *				do_readbios				     *
 *===========================================================================*/
int do_readbios(struct proc * caller, message * m_ptr)
{
  struct vir_addr src, dst;     
        
  src.segment = BIOS_SEG;
  dst.segment = D;
  src.offset = m_ptr->RDB_ADDR;
  dst.offset = (vir_bytes) m_ptr->RDB_BUF;
  src.proc_nr_e = NONE;
  dst.proc_nr_e = m_ptr->m_source;      

  return virtual_copy_vmcheck(caller, &src, &dst, m_ptr->RDB_SIZE);
}
Example #2
0
/*===========================================================================*
 *				do_readbios				     *
 *===========================================================================*/
int do_readbios(struct proc * caller, message * m_ptr)
{
  struct vir_addr src, dst;
  size_t len = m_ptr->m_lsys_krn_readbios.size;
  vir_bytes limit;

  src.offset = m_ptr->m_lsys_krn_readbios.addr;
  dst.offset = m_ptr->m_lsys_krn_readbios.buf;
  src.proc_nr_e = NONE;
  dst.proc_nr_e = m_ptr->m_source;      

  limit = src.offset + len - 1;

#define VINRANGE(v, a, b) ((a) <= (v) && (v) <= (b))
#define SUBRANGE(a,b,c,d) (VINRANGE((a), (c), (d)) && VINRANGE((b),(c),(d)))
#define USERRANGE(a, b) SUBRANGE(src.offset, limit, (a), (b))

  if(!USERRANGE(BIOS_MEM_BEGIN, BIOS_MEM_END) &&
     !USERRANGE(BASE_MEM_TOP, UPPER_MEM_END))
  	return EPERM;

  return virtual_copy_vmcheck(caller, &src, &dst, m_ptr->m_lsys_krn_readbios.size);
}
Example #3
0
/*===========================================================================*
 *				do_copy					     *
 *===========================================================================*/
PUBLIC int do_copy(struct proc * caller, message * m_ptr)
{
/* Handle sys_vircopy() and sys_physcopy().  Copy data using virtual or
 * physical addressing. Although a single handler function is used, there 
 * are two different kernel calls so that permissions can be checked. 
 */
  struct vir_addr vir_addr[2];	/* virtual source and destination address */
  phys_bytes bytes;		/* number of bytes to copy */
  int i;

#if 0
  if (caller->p_endpoint != PM_PROC_NR && caller->p_endpoint != VFS_PROC_NR &&
	caller->p_endpoint != RS_PROC_NR && caller->p_endpoint != MEM_PROC_NR &&
	caller->p_endpoint != VM_PROC_NR)
  {
	static int first=1;
	if (first)
	{
		first= 0;
		printf(
"do_copy: got request from %d (source %d, seg %d, destination %d, seg %d)\n",
			caller->p_endpoint,
			m_ptr->CP_SRC_ENDPT,
			m_ptr->CP_SRC_SPACE,
			m_ptr->CP_DST_ENDPT,
			m_ptr->CP_DST_SPACE);
	}
  }
#endif

  /* Dismember the command message. */
  vir_addr[_SRC_].proc_nr_e = m_ptr->CP_SRC_ENDPT;
  vir_addr[_SRC_].segment = m_ptr->CP_SRC_SPACE;
  vir_addr[_SRC_].offset = (vir_bytes) m_ptr->CP_SRC_ADDR;
  vir_addr[_DST_].proc_nr_e = m_ptr->CP_DST_ENDPT;
  vir_addr[_DST_].segment = m_ptr->CP_DST_SPACE;
  vir_addr[_DST_].offset = (vir_bytes) m_ptr->CP_DST_ADDR;
  bytes = (phys_bytes) m_ptr->CP_NR_BYTES;

  /* Now do some checks for both the source and destination virtual address.
   * This is done once for _SRC_, then once for _DST_. 
   */
  for (i=_SRC_; i<=_DST_; i++) {
	int p;
      /* Check if process number was given implictly with SELF and is valid. */
      if (vir_addr[i].proc_nr_e == SELF)
	vir_addr[i].proc_nr_e = caller->p_endpoint;
      if (vir_addr[i].segment != PHYS_SEG) {
	if(! isokendpt(vir_addr[i].proc_nr_e, &p)) {
	  printf("do_copy: %d: seg 0x%x, %d not ok endpoint\n",
		i, vir_addr[i].segment, vir_addr[i].proc_nr_e);
          return(EINVAL); 
        }
      }
  }

  /* Check for overflow. This would happen for 64K segments and 16-bit 
   * vir_bytes. Especially copying by the PM on do_fork() is affected. 
   */
  if (bytes != (phys_bytes) (vir_bytes) bytes) return(E2BIG);

  /* Now try to make the actual virtual copy. */
  return( virtual_copy_vmcheck(caller, &vir_addr[_SRC_],
			  	&vir_addr[_DST_], bytes) );
}