Exemple #1
0
/*===========================================================================*
 *				do_reboot				     *
 *===========================================================================*/
int do_reboot()
{
    message m;

    /* Check permission to abort the system. */
    if (mp->mp_effuid != SUPER_USER) return(EPERM);

    /* See how the system should be aborted. */
    abort_flag = m_in.m_lc_pm_reboot.how;

    /* notify readclock (some arm systems power off via RTC alarms) */
    if (abort_flag & RB_POWERDOWN) {
        endpoint_t readclock_ep;
        if (ds_retrieve_label_endpt("readclock.drv", &readclock_ep) == OK) {
            message m; /* no params to set, nothing we can do if it fails */
            _taskcall(readclock_ep, RTCDEV_PWR_OFF, &m);
        }
    }

    /* Order matters here. When VFS is told to reboot, it exits all its
     * processes, and then would be confused if they're exited again by
     * SIGKILL. So first kill, then reboot.
     */

    check_sig(-1, SIGKILL, FALSE /* ksig*/); /* kill all users except init */
    sys_stop(INIT_PROC_NR);		   /* stop init, but keep it around */

    /* Tell VFS to reboot */
    memset(&m, 0, sizeof(m));
    m.m_type = VFS_PM_REBOOT;

    tell_vfs(&mproc[VFS_PROC_NR], &m);

    return(SUSPEND);			/* don't reply to caller */
}
Exemple #2
0
int vm_cachecall(message *m, int call, void *addr, u32_t dev, u64_t dev_offset,
	u64_t ino, u64_t ino_offset, u32_t *flags, int blocksize)
{
    if(blocksize % PAGE_SIZE)
    	panic("blocksize %d should be a multiple of pagesize %d\n",
		blocksize, PAGE_SIZE);

    if(ino_offset % PAGE_SIZE)
    	panic("inode offset %d should be a multiple of pagesize %d\n",
		ino_offset, PAGE_SIZE);

    if(dev_offset % PAGE_SIZE)
    	panic("dev offset offset %d should be a multiple of pagesize %d\n",
		dev_offset, PAGE_SIZE);

    memset(m, 0, sizeof(*m));

    assert(dev != NO_DEV);

    m->m_u.m_vmmcp.dev_offset_pages = dev_offset/PAGE_SIZE;
    m->m_u.m_vmmcp.ino_offset_pages = ino_offset/PAGE_SIZE;
    m->m_u.m_vmmcp.ino = ino;
    m->m_u.m_vmmcp.block = addr;
    m->m_u.m_vmmcp.flags_ptr = flags;
    m->m_u.m_vmmcp.dev = dev;
    m->m_u.m_vmmcp.pages = blocksize / PAGE_SIZE;
    m->m_u.m_vmmcp.flags = 0;

    return _taskcall(VM_PROC_NR, call, m);
}
Exemple #3
0
/*===========================================================================*
 *				sched_inherit				     *
 *===========================================================================*/
PUBLIC int sched_inherit(endpoint_t scheduler_e, 
	endpoint_t schedulee_e, endpoint_t parent_e, unsigned maxprio, 
	endpoint_t *newscheduler_e)
{
	int rv;
	message m;

	assert(_ENDPOINT_P(scheduler_e) >= 0);
	assert(_ENDPOINT_P(schedulee_e) >= 0);
	assert(_ENDPOINT_P(parent_e) >= 0);
	assert(maxprio >= 0);
	assert(maxprio < NR_SCHED_QUEUES);
	assert(newscheduler_e);
	
	m.SCHEDULING_ENDPOINT	= schedulee_e;
	m.SCHEDULING_PARENT	= parent_e;
	m.SCHEDULING_MAXPRIO	= (int) maxprio;

	/* Send the request to the scheduler */
	if ((rv = _taskcall(scheduler_e, SCHEDULING_INHERIT, &m))) {
		return rv;
	}

	/* Store the process' scheduler. Note that this might not be the
	 * scheduler we sent the SCHEDULING_INHERIT message to. That scheduler
	 * might have forwarded the scheduling message on to another scheduler
	 * before returning the message.
	 */
	*newscheduler_e = m.SCHEDULING_SCHEDULER;
	return (OK);
}
Exemple #4
0
PRIVATE int do_invoke_ds(int type, const char *ds_name)
{
	cp_grant_id_t g_key;
	size_t len_key;
	int access, r;

	if(type == DS_CHECK || type == DS_RETRIEVE_LABEL) {
		len_key = DS_MAX_KEYLEN;
		access = CPF_WRITE;
	} else {
		len_key = strlen(ds_name)+1;
		access = CPF_READ;
	}

	/* Grant for key. */
	g_key = cpf_grant_direct(DS_PROC_NR, (vir_bytes) ds_name,
		len_key, access);
	if(!GRANT_VALID(g_key)) 
		return errno;

	m.DS_KEY_GRANT = g_key;
	m.DS_KEY_LEN = len_key;

	r = _taskcall(DS_PROC_NR, type, &m);

	cpf_revoke(g_key);
	return r;
}
PUBLIC int sys_setscheduler(int proc, int policy)
{
  message m;

  m.m1_i1 = proc;
  m.m1_i2 = policy;
  return(_taskcall(SYSTASK, SYS_SETSCHEDULER, &m));
}
Exemple #6
0
/*===========================================================================*
 *                                sys_nice			     	     *
 *===========================================================================*/
PUBLIC int sys_nice(int proc, int prio)
{
  message m;

  m.m1_i1 = proc;
  m.m1_i2 = prio;
  return(_taskcall(SYSTASK, SYS_NICE, &m));
}
Exemple #7
0
PUBLIC int sys_vmctl_enable_paging(struct mem_map *map)
{
	message m;
	m.SVMCTL_WHO = SELF;
	m.SVMCTL_PARAM = VMCTL_ENABLE_PAGING;
	m.SVMCTL_VALUE = (int) map;
	return _taskcall(SYSTASK, SYS_VMCTL, &m);
}
Exemple #8
0
/*===========================================================================*
 *                                vm_brk				     *
 *===========================================================================*/
int vm_brk(endpoint_t ep, char *addr)
{
    message m;

    m.VMB_ENDPOINT = ep;
    m.VMB_ADDR = (void *) addr;

    return _taskcall(VM_PROC_NR, VM_BRK, &m);
}
Exemple #9
0
/*===========================================================================*
 *                                vm_umap				     *
 *===========================================================================*/
PUBLIC int vm_ctl(int what, int param)
{
    message m;
    int result;

    m.VCTL_WHAT = what;
    m.VCTL_PARAM = param;
    return _taskcall(VM_PROC_NR, VM_CTL, &m);
}
Exemple #10
0
/*===========================================================================*
 *				do_gcov_flush				*
 *===========================================================================*/
PUBLIC int do_gcov_flush()
{
/* A userland tool has requested the gcov data from another
 * process (possibly vfs itself). Grant the target process
 * access to the supplied buffer, and perform the call that
 * makes the target copy its buffer to the caller (incl vfs
 * itself).
 */
  struct fproc *rfp;
  ssize_t size;
  cp_grant_id_t grantid;
  int r, n;
  pid_t target;
  message m;

  size = m_in.GCOV_BUFF_SZ;
  target = m_in.GCOV_PID;

  /* If the wrong process is sent to, the system hangs; so make this root-only.
   */

  if (!super_user) return(EPERM);

  /* Find target gcov process. */
  for(n = 0; n < NR_PROCS; n++) {
	if(fproc[n].fp_endpoint != NONE && fproc[n].fp_pid == target)
		 break;
  }
  if(n >= NR_PROCS) {
	printf("VFS: gcov process %d not found\n", target);
	return(ESRCH);
  }
  rfp = &fproc[n];

  /* Grant target process to requestor's buffer. */
  if ((grantid = cpf_grant_magic(rfp->fp_endpoint, who_e,
				 (vir_bytes) m_in.GCOV_BUFF_P, size,
				 CPF_WRITE)) < 0) {
	printf("VFS: gcov_flush: grant failed\n");
	return(ENOMEM);
  }

  if(rfp->fp_endpoint == VFS_PROC_NR) {
	/* Request is for VFS itself. */
	r = gcov_flush(grantid, size);
  } else {
	/* Perform generic GCOV request. */
	m.GCOV_GRANT = grantid;
	m.GCOV_BUFF_SZ = size;
	r = _taskcall(rfp->fp_endpoint, COMMON_REQ_GCOV_DATA, &m);
  }

  cpf_revoke(grantid);

  return(r);
}
Exemple #11
0
/*===========================================================================*
 *                                sys_runctl			     	     *
 *===========================================================================*/
PUBLIC int sys_runctl(endpoint_t proc_ep, int action, int flags)
{
  message m;

  m.RC_ENDPT = proc_ep;
  m.RC_ACTION = action;
  m.RC_FLAGS = flags;

  return(_taskcall(SYSTASK, SYS_RUNCTL, &m));
}
int sys_klog_copy(int endpoint, void *data_ptr)
{
  message m; /* message we use for the kernel call */
  
  m.KLOG_ENDPT = endpoint; /* endpoint of user program */
  m.KLOG_PTR = data_ptr; /* pointer to kernel log in user program */
  
  /* do the kernel call and return the result */
  return (_taskcall(SYSTASK, SYS_KLOG_COPY, &m));
} 
Exemple #13
0
int
vm_update(endpoint_t src_e, endpoint_t dst_e)
{
	message m;

	memset(&m, 0, sizeof(m));
	m.m_lsys_vm_update.src = src_e;
	m.m_lsys_vm_update.dst = dst_e;

	return _taskcall(VM_PROC_NR, VM_RS_UPDATE, &m);
}
int sys_privctl(int proc, int request, int i, void *p)
{
  message m;

  m.CTL_ENDPT = proc;
  m.CTL_REQUEST = request;
  m.CTL_MM_PRIV = i;
  m.CTL_ARG_PTR = p;

  return _taskcall(SYSTASK, SYS_PRIVCTL, &m);
}
Exemple #15
0
PUBLIC int sys_vmctl(endpoint_t who, int param, u32_t value)
{
  message m;
  int r;

  m.SVMCTL_WHO = who;
  m.SVMCTL_PARAM = param;
  m.SVMCTL_VALUE = value;
  r = _taskcall(SYSTASK, SYS_VMCTL, &m);
  return(r);
}
Exemple #16
0
PUBLIC int sys_vsafecopy(struct vscp_vec *vec, int els)
{
/* Vectored variant of sys_safecopy*. */

  message copy_mess;

  copy_mess.VSCP_VEC_ADDR = (char *) vec;
  copy_mess.VSCP_VEC_SIZE = els;

  return(_taskcall(SYSTASK, SYS_VSAFECOPY, &copy_mess));

}
Exemple #17
0
/*===========================================================================*
 *                                vm_allocmem				     *
 *===========================================================================*/
PUBLIC int vm_allocmem(phys_clicks bytes, phys_clicks *retmembase)
{
    message m;
    int result;

    m.VMAM_BYTES = (char *) bytes;
    result = _taskcall(VM_PROC_NR, VM_ALLOCMEM, &m);
    if(result == OK)
	    *retmembase = m.VMAM_MEMBASE;

    return result;
}
Exemple #18
0
/*===========================================================================*
 *				sched_start				     *
 *===========================================================================*/
PUBLIC int sched_start(endpoint_t scheduler_e,
			endpoint_t schedulee_e, 
			endpoint_t parent_e,
			int maxprio,
			int quantum,
			int cpu,
			endpoint_t *newscheduler_e)
{
	int rv;
	message m;

	/* No scheduler given? We are done. */
	if(scheduler_e == NONE) {
		return OK;
	}

	assert(_ENDPOINT_P(schedulee_e) >= 0);
	assert(_ENDPOINT_P(parent_e) >= 0);
	assert(maxprio >= 0);
	assert(maxprio < NR_SCHED_QUEUES);
	assert(quantum > 0);
	assert(newscheduler_e);

	/* The KERNEL must schedule this process. */
	if(scheduler_e == KERNEL) {
		if ((rv = sys_schedctl(SCHEDCTL_FLAG_KERNEL, 
			schedulee_e, maxprio, quantum, cpu)) != OK) {
			return rv;
		}
		*newscheduler_e = scheduler_e;
		return OK;
	}

	/* A user-space scheduler must schedule this process. */
	m.SCHEDULING_ENDPOINT	= schedulee_e;
	m.SCHEDULING_PARENT	= parent_e;
	m.SCHEDULING_MAXPRIO	= (int) maxprio;
	m.SCHEDULING_QUANTUM	= (int) quantum;

	/* Send the request to the scheduler */
	if ((rv = _taskcall(scheduler_e, SCHEDULING_START, &m))) {
		return rv;
	}

	/* Store the process' scheduler. Note that this might not be the
	 * scheduler we sent the SCHEDULING_START message to. That scheduler
	 * might have forwarded the scheduling message on to another scheduler
	 * before returning the message.
	 */
	*newscheduler_e = m.SCHEDULING_SCHEDULER;
	return (OK);
}
Exemple #19
0
/*===========================================================================*
 *                                vm_umap				     *
 *===========================================================================*/
int vm_umap(int seg, vir_bytes offset, vir_bytes len, phys_bytes *addr)
{
    message m;
    int result;

    m.VMU_SEG = seg;
    m.VMU_OFFSET = (char *) offset;
    m.VMU_LENGTH = (char *) len;
    result = _taskcall(VM_PROC_NR, VM_UMAP, &m);
    *addr = (phys_bytes) m.VMU_RETADDR;

    return result;
}
Exemple #20
0
PUBLIC int sys_vmctl_get_cr3_i386(endpoint_t who, u32_t *cr3)
{
  message m;
  int r;

  m.SVMCTL_WHO = who;
  m.SVMCTL_PARAM = VMCTL_I386_GETCR3;
  r = _taskcall(SYSTASK, SYS_VMCTL, &m);
  if(r == OK) {
	*cr3 = m.SVMCTL_VALUE;
  }
  return(r);
}
Exemple #21
0
PUBLIC int sys_vmctl_get_pagefault_i386(endpoint_t *who, u32_t *cr2, u32_t *err)
{
  message m;
  int r;

  m.SVMCTL_WHO = SELF;
  m.SVMCTL_PARAM = VMCTL_GET_PAGEFAULT;
  r = _taskcall(SYSTASK, SYS_VMCTL, &m);
  if(r == OK) {
	*who = m.SVMCTL_PF_WHO;
	*cr2 = m.SVMCTL_PF_I386_CR2;
	*err = m.SVMCTL_PF_I386_ERR;
  }
  return(r);
}
Exemple #22
0
PUBLIC int sys_vmctl_get_memreq(endpoint_t *who, vir_bytes *mem,
	vir_bytes *len, int *wrflag, endpoint_t *requestor)
{
  message m;
  int r;

  m.SVMCTL_WHO = SELF;
  m.SVMCTL_PARAM = VMCTL_MEMREQ_GET;
  r = _taskcall(SYSTASK, SYS_VMCTL, &m);
  if(r == OK) {
	*who = m.SVMCTL_MRG_EP;
	*mem = (vir_bytes) m.SVMCTL_MRG_ADDR;
	*len = m.SVMCTL_MRG_LEN;
	*wrflag = m.SVMCTL_MRG_WRITE;
	*requestor = (endpoint_t) m.SVMCTL_MRG_REQUESTOR;
  }
  return r;
}
/*===========================================================================*
 *				sched_nice				     *
 *===========================================================================*/
PUBLIC int sched_nice(struct mproc *rmp, int nice)
{
	int rv;
	message m;

	/* If the kernel is the scheduler, we don't allow messing with the
	 * priority. If you want to control process priority, assign the process
	 * to a user-space scheduler */
	if (rmp->mp_scheduler == KERNEL || rmp->mp_scheduler == NONE)
		return (EINVAL);

	m.SCHEDULING_ENDPOINT	= rmp->mp_endpoint;
	m.SCHEDULING_NICE	= nice;
	if ((rv = _taskcall(rmp->mp_scheduler, SCHEDULING_SET_NICE, &m))) {
		return rv;
	}

	return (OK);
}
Exemple #24
0
int mini_ds_retrieve_u32(char *ds_name, u32_t *value)
{
	int r;
	message m;
	size_t len_key;

	len_key = strlen(ds_name)+1;

	m.DS_KEY_GRANT = ds_name;
	m.DS_KEY_LEN = len_key;
	m.DS_FLAGS = DS_TYPE_U32;

	r = _taskcall(DS_PROC_NR, DS_RETRIEVE_LIBC, &m);

	if(r == OK) {
		/* Assign u32 value. */
		*value = m.DS_VAL;
	}

	return r;
}
Exemple #25
0
/*===========================================================================*
 *				sched_stop				     *
 *===========================================================================*/
int sched_stop(endpoint_t scheduler_e, endpoint_t schedulee_e)
{
	int rv;
	message m;
	
	/* If the kernel is the scheduler, it will implicitly stop scheduling
	 * once another process takes over or the process terminates */
	if (scheduler_e == KERNEL || scheduler_e == NONE)
		return(OK);

	/* User-scheduled, perform the call */
	assert(_ENDPOINT_P(scheduler_e) >= 0);
	assert(_ENDPOINT_P(schedulee_e) >= 0);

	m.SCHEDULING_ENDPOINT	= schedulee_e;
	if ((rv = _taskcall(scheduler_e, SCHEDULING_STOP, &m))) {
		return rv;
	}

	return (OK);
}
Exemple #26
0
int
checkperms(endpoint_t endpt, char *path, size_t size)
{
	cp_grant_id_t grant;
	message m;
	int r;

	if ((grant = cpf_grant_direct(VFS_PROC_NR, (vir_bytes) path, size,
	    CPF_READ | CPF_WRITE)) == GRANT_INVALID)
		return ENOMEM;

	memset(&m, 0, sizeof(m));
	m.m_lsys_vfs_checkperms.endpt = endpt;
	m.m_lsys_vfs_checkperms.grant = grant;
	m.m_lsys_vfs_checkperms.count = size;

	r = _taskcall(VFS_PROC_NR, VFS_CHECKPERMS, &m);

	cpf_revoke(grant);

	return r;
}
/*===========================================================================*
 *				sched_stop				     *
 *===========================================================================*/
PUBLIC int sched_stop(struct mproc *rmp)
{
	int rv;
	message m;

	/* If the kernel is the scheduler, it will implicitly stop scheduling
	 * once another process takes over or the process terminates */
	if (rmp->mp_scheduler == KERNEL || rmp->mp_scheduler == NONE)
		return(OK);

	m.SCHEDULING_ENDPOINT	= rmp->mp_endpoint;
	if ((rv = _taskcall(rmp->mp_scheduler, SCHEDULING_STOP, &m))) {
		return rv;
	}

	/* sched_stop is either called when the process is exiting or it is
	 * being moved between schedulers. If it is being moved between
	 * schedulers, we need to set the mp_scheduler to NONE so that PM
	 * doesn't forward messages to the process' scheduler while being moved
	 * (such as sched_nice). */
	rmp->mp_scheduler = NONE;
	return (OK);
}
/*===========================================================================*
 *				sched_start				     *
 *===========================================================================*/
PUBLIC int sched_start(endpoint_t ep, struct mproc *rmp, int flags)
{
	int rv;
	message m;

	/*printf("-------------------sched_start() of pm\n");*/

	m.SCHEDULING_ENDPOINT	= rmp->mp_endpoint;
	m.SCHEDULING_PARENT	= mproc[rmp->mp_parent].mp_endpoint;
	m.SCHEDULING_NICE	= rmp->mp_nice;

	/* Send the request to the scheduler */
	if ((rv = _taskcall(ep, SCHEDULING_START, &m))) {
		return rv;
	}

	/* Store the process' scheduler. Note that this might not be the
	 * scheduler we sent the SCHEDULING_START message to. That scheduler
	 * might have forwarded the scheduling message on to another scheduler
	 * before returning the message.
	 */
	rmp->mp_scheduler = m.SCHEDULING_SCHEDULER;
	return (OK);
}