Removal of the system task
* Userspace change to use the new kernel calls - _taskcall(SYSTASK...) changed to _kernel_call(...) - int 32 reused for the kernel calls - _do_kernel_call() to make the trap to kernel - kernel_call() to make the actuall kernel call from C using _do_kernel_call() - unlike ipc call the kernel call always succeeds as kernel is always available, however, kernel may return an error * Kernel side implementation of kernel calls - the SYSTEm task does not run, only the proc table entry is preserved - every data_copy(SYSTEM is no data_copy(KERNEL - "locking" is an empty operation now as everything runs in kernel - sys_task() is replaced by kernel_call() which copies the message into kernel, dispatches the call to its handler and finishes by either copying the results back to userspace (if need be) or by suspending the process because of VM - suspended processes are later made runnable once the memory issue is resolved, picked up by the scheduler and only at this time the call is resumed (in fact restarted) which does not need to copy the message from userspace as the message is already saved in the process structure. - no ned for the vmrestart queue, the scheduler will restart the system calls - no special case in do_vmctl(), all requests remove the RTS_VMREQUEST flag
This commit is contained in:
@@ -30,9 +30,8 @@ PUBLIC int do_abort(struct proc * caller, message * m_ptr)
|
||||
int len;
|
||||
len = MIN(m_ptr->ABRT_MON_LEN, sizeof(paramsbuffer)-1);
|
||||
|
||||
if((p=data_copy(m_ptr->ABRT_MON_ENDPT,
|
||||
(vir_bytes) m_ptr->ABRT_MON_ADDR,
|
||||
SYSTEM, (vir_bytes) paramsbuffer, len)) != OK) {
|
||||
if((p=data_copy(m_ptr->ABRT_MON_ENDPT, (vir_bytes) m_ptr->ABRT_MON_ADDR,
|
||||
KERNEL, (vir_bytes) paramsbuffer, len)) != OK) {
|
||||
return p;
|
||||
}
|
||||
paramsbuffer[len] = '\0';
|
||||
|
||||
@@ -47,7 +47,7 @@ PUBLIC int do_cprofile(struct proc * caller, message * m_ptr)
|
||||
}
|
||||
|
||||
/* Set reset flag. */
|
||||
data_copy(SYSTEM, (vir_bytes) &cprof_ctl_inst.reset,
|
||||
data_copy(KERNEL, (vir_bytes) &cprof_ctl_inst.reset,
|
||||
cprof_proc_info[i].endpt, cprof_proc_info[i].ctl_v,
|
||||
sizeof(cprof_ctl_inst.reset));
|
||||
}
|
||||
@@ -90,7 +90,7 @@ PUBLIC int do_cprofile(struct proc * caller, message * m_ptr)
|
||||
|
||||
/* Copy control struct from proc to local variable. */
|
||||
data_copy(cprof_proc_info[i].endpt, cprof_proc_info[i].ctl_v,
|
||||
SYSTEM, (vir_bytes) &cprof_ctl_inst,
|
||||
KERNEL, (vir_bytes) &cprof_ctl_inst,
|
||||
sizeof(cprof_ctl_inst));
|
||||
|
||||
/* Calculate memory used. */
|
||||
@@ -108,7 +108,7 @@ PUBLIC int do_cprofile(struct proc * caller, message * m_ptr)
|
||||
if (cprof_mem_size < cprof_info.mem_used) cprof_info.mem_used = -1;
|
||||
|
||||
/* Copy the info struct to the user process. */
|
||||
data_copy(SYSTEM, (vir_bytes) &cprof_info,
|
||||
data_copy(KERNEL, (vir_bytes) &cprof_info,
|
||||
m_ptr->PROF_ENDPT, (vir_bytes) m_ptr->PROF_CTL_PTR,
|
||||
sizeof(cprof_info));
|
||||
|
||||
@@ -120,7 +120,7 @@ PUBLIC int do_cprofile(struct proc * caller, message * m_ptr)
|
||||
vir_dst = (vir_bytes) m_ptr->PROF_MEM_PTR;
|
||||
for (i=0; i<cprof_procs_no; i++) {
|
||||
len = (phys_bytes) strlen(cprof_proc_info[i].name);
|
||||
data_copy(SYSTEM, (vir_bytes) cprof_proc_info[i].name,
|
||||
data_copy(KERNEL, (vir_bytes) cprof_proc_info[i].name,
|
||||
m_ptr->PROF_ENDPT, vir_dst, len);
|
||||
vir_dst += CPROF_PROCNAME_LEN;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ PUBLIC int do_exec(struct proc * caller, message * m_ptr)
|
||||
|
||||
/* Save command name for debugging, ps(1) output, etc. */
|
||||
if(data_copy(caller->p_endpoint, (vir_bytes) m_ptr->PR_NAME_PTR,
|
||||
SYSTEM, (vir_bytes) rp->p_name, (phys_bytes) P_NAME_LEN - 1) != OK)
|
||||
KERNEL, (vir_bytes) rp->p_name, (phys_bytes) P_NAME_LEN - 1) != OK)
|
||||
strncpy(rp->p_name, "<unset>", P_NAME_LEN);
|
||||
|
||||
/* Do architecture-specific exec() stuff. */
|
||||
|
||||
@@ -184,7 +184,7 @@ PUBLIC int do_getinfo(struct proc * caller, message * m_ptr)
|
||||
|
||||
/* Try to make the actual copy for the requested data. */
|
||||
if (m_ptr->I_VAL_LEN > 0 && length > m_ptr->I_VAL_LEN) return (E2BIG);
|
||||
r = data_copy_vmcheck(caller, SYSTEM, src_vir, caller->p_endpoint,
|
||||
r = data_copy_vmcheck(caller, KERNEL, src_vir, caller->p_endpoint,
|
||||
(vir_bytes) m_ptr->I_VAL_PTR, length);
|
||||
|
||||
if(r != OK) return r;
|
||||
|
||||
@@ -37,7 +37,7 @@ PUBLIC int newmap(struct proc *caller, struct proc *rp, struct mem_map *map_ptr)
|
||||
int r;
|
||||
/* Fetch the memory map. */
|
||||
if((r=data_copy(caller->p_endpoint, (vir_bytes) map_ptr,
|
||||
SYSTEM, (vir_bytes) rp->p_memmap, sizeof(rp->p_memmap))) != OK) {
|
||||
KERNEL, (vir_bytes) rp->p_memmap, sizeof(rp->p_memmap))) != OK) {
|
||||
kprintf("newmap: data_copy failed! (%d)\n", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ PUBLIC int do_privctl(struct proc * caller, message * m_ptr)
|
||||
{
|
||||
/* Copy privilege structure from caller */
|
||||
if((r=data_copy(caller->p_endpoint, (vir_bytes) m_ptr->CTL_ARG_PTR,
|
||||
SYSTEM, (vir_bytes) &priv, sizeof(priv))) != OK)
|
||||
KERNEL, (vir_bytes) &priv, sizeof(priv))) != OK)
|
||||
return r;
|
||||
|
||||
/* See if the caller wants to assign a static privilege id. */
|
||||
@@ -226,7 +226,7 @@ PUBLIC int do_privctl(struct proc * caller, message * m_ptr)
|
||||
|
||||
/* Get the I/O range */
|
||||
data_copy(caller->p_endpoint, (vir_bytes) m_ptr->CTL_ARG_PTR,
|
||||
SYSTEM, (vir_bytes) &io_range, sizeof(io_range));
|
||||
KERNEL, (vir_bytes) &io_range, sizeof(io_range));
|
||||
priv(rp)->s_flags |= CHECK_IO_PORT; /* Check I/O accesses */
|
||||
i= priv(rp)->s_nr_io_range;
|
||||
if (i >= NR_IO_RANGE)
|
||||
@@ -248,7 +248,7 @@ PUBLIC int do_privctl(struct proc * caller, message * m_ptr)
|
||||
|
||||
/* Get the memory range */
|
||||
if((r=data_copy(caller->p_endpoint, (vir_bytes) m_ptr->CTL_ARG_PTR,
|
||||
SYSTEM, (vir_bytes) &mem_range, sizeof(mem_range))) != OK)
|
||||
KERNEL, (vir_bytes) &mem_range, sizeof(mem_range))) != OK)
|
||||
return r;
|
||||
priv(rp)->s_flags |= CHECK_MEM; /* Check memory mappings */
|
||||
i= priv(rp)->s_nr_mem_range;
|
||||
@@ -270,7 +270,7 @@ PUBLIC int do_privctl(struct proc * caller, message * m_ptr)
|
||||
return EPERM;
|
||||
|
||||
data_copy(caller->p_endpoint, (vir_bytes) m_ptr->CTL_ARG_PTR,
|
||||
SYSTEM, (vir_bytes) &irq, sizeof(irq));
|
||||
KERNEL, (vir_bytes) &irq, sizeof(irq));
|
||||
priv(rp)->s_flags |= CHECK_IRQ; /* Check IRQs */
|
||||
|
||||
i= priv(rp)->s_nr_irq;
|
||||
|
||||
@@ -83,7 +83,7 @@ endpoint_t *e_granter; /* new granter (magic grants) */
|
||||
*/
|
||||
if((r=data_copy(granter,
|
||||
priv(granter_proc)->s_grant_table + sizeof(g)*grant,
|
||||
SYSTEM, (vir_bytes) &g, sizeof(g))) != OK) {
|
||||
KERNEL, (vir_bytes) &g, sizeof(g))) != OK) {
|
||||
kprintf(
|
||||
"verify_grant: grant verify: data_copy failed\n");
|
||||
return EPERM;
|
||||
@@ -366,7 +366,7 @@ PUBLIC int do_vsafecopy(struct proc * caller, message * m_ptr)
|
||||
src.proc_nr_e = caller->p_endpoint;
|
||||
src.offset = (vir_bytes) m_ptr->VSCP_VEC_ADDR;
|
||||
src.segment = dst.segment = D;
|
||||
dst.proc_nr_e = SYSTEM;
|
||||
dst.proc_nr_e = KERNEL;
|
||||
dst.offset = (vir_bytes) vec;
|
||||
|
||||
/* No. of vector elements. */
|
||||
|
||||
@@ -32,7 +32,7 @@ PUBLIC int do_sigreturn(struct proc * caller, message * m_ptr)
|
||||
|
||||
/* Copy in the sigcontext structure. */
|
||||
if((r=data_copy(m_ptr->SIG_ENDPT, (vir_bytes) m_ptr->SIG_CTXT_PTR,
|
||||
SYSTEM, (vir_bytes) &sc, sizeof(struct sigcontext))) != OK)
|
||||
KERNEL, (vir_bytes) &sc, sizeof(struct sigcontext))) != OK)
|
||||
return r;
|
||||
|
||||
/* Restore user bits of psw from sc, maintain system bits from proc. */
|
||||
|
||||
@@ -37,7 +37,7 @@ PUBLIC int do_sigsend(struct proc * caller, message * m_ptr)
|
||||
|
||||
/* Get the sigmsg structure into our address space. */
|
||||
if((r=data_copy_vmcheck(caller, caller->p_endpoint,
|
||||
(vir_bytes) m_ptr->SIG_CTXT_PTR, SYSTEM, (vir_bytes) &smsg,
|
||||
(vir_bytes) m_ptr->SIG_CTXT_PTR, KERNEL, (vir_bytes) &smsg,
|
||||
(phys_bytes) sizeof(struct sigmsg))) != OK)
|
||||
return r;
|
||||
|
||||
@@ -57,7 +57,7 @@ PUBLIC int do_sigsend(struct proc * caller, message * m_ptr)
|
||||
sc.sc_flags = 0 | rp->p_misc_flags & MF_FPU_INITIALIZED;
|
||||
|
||||
/* Copy the sigcontext structure to the user's stack. */
|
||||
if((r=data_copy_vmcheck(caller, SYSTEM, (vir_bytes) &sc, m_ptr->SIG_ENDPT,
|
||||
if((r=data_copy_vmcheck(caller, KERNEL, (vir_bytes) &sc, m_ptr->SIG_ENDPT,
|
||||
(vir_bytes) scp, (vir_bytes) sizeof(struct sigcontext))) != OK)
|
||||
return r;
|
||||
|
||||
@@ -106,7 +106,7 @@ PUBLIC int do_sigsend(struct proc * caller, message * m_ptr)
|
||||
fr.sf_retadr = (void (*)()) smsg.sm_sigreturn;
|
||||
|
||||
/* Copy the sigframe structure to the user's stack. */
|
||||
if((r=data_copy_vmcheck(caller, SYSTEM, (vir_bytes) &fr,
|
||||
if((r=data_copy_vmcheck(caller, KERNEL, (vir_bytes) &fr,
|
||||
m_ptr->SIG_ENDPT, (vir_bytes) frp,
|
||||
(vir_bytes) sizeof(struct sigframe))) != OK)
|
||||
return r;
|
||||
|
||||
@@ -79,7 +79,7 @@ PUBLIC int do_sprofile(struct proc * caller, message * m_ptr)
|
||||
|
||||
stop_profile_clock();
|
||||
|
||||
data_copy(SYSTEM, (vir_bytes) &sprof_info,
|
||||
data_copy(KERNEL, (vir_bytes) &sprof_info,
|
||||
sprof_ep, sprof_info_addr_vir, sizeof(sprof_info));
|
||||
|
||||
return OK;
|
||||
|
||||
@@ -27,7 +27,7 @@ PUBLIC int do_sysctl(struct proc * caller, message * m_ptr)
|
||||
caller->p_endpoint, len);
|
||||
return EINVAL;
|
||||
}
|
||||
if((s=data_copy_vmcheck(caller, caller->p_endpoint, buf, SYSTEM,
|
||||
if((s=data_copy_vmcheck(caller, caller->p_endpoint, buf, KERNEL,
|
||||
(vir_bytes) mybuf, len)) != OK) {
|
||||
kprintf("do_sysctl: diag for %d: len %d: copy failed: %d\n",
|
||||
caller->p_endpoint, len, s);
|
||||
|
||||
@@ -54,7 +54,7 @@ PUBLIC int do_trace(struct proc * caller, message * m_ptr)
|
||||
#define COPYTOPROC(seg, addr, myaddr, length) { \
|
||||
struct vir_addr fromaddr, toaddr; \
|
||||
int r; \
|
||||
fromaddr.proc_nr_e = SYSTEM; \
|
||||
fromaddr.proc_nr_e = KERNEL; \
|
||||
toaddr.proc_nr_e = tr_proc_nr_e; \
|
||||
fromaddr.offset = (myaddr); \
|
||||
toaddr.offset = (addr); \
|
||||
@@ -71,7 +71,7 @@ PUBLIC int do_trace(struct proc * caller, message * m_ptr)
|
||||
struct vir_addr fromaddr, toaddr; \
|
||||
int r; \
|
||||
fromaddr.proc_nr_e = tr_proc_nr_e; \
|
||||
toaddr.proc_nr_e = SYSTEM; \
|
||||
toaddr.proc_nr_e = KERNEL; \
|
||||
fromaddr.offset = (addr); \
|
||||
toaddr.offset = (myaddr); \
|
||||
fromaddr.segment = (seg); \
|
||||
|
||||
@@ -67,7 +67,7 @@ PUBLIC int do_vdevio(struct proc * caller, message * m_ptr)
|
||||
|
||||
/* Copy (port,value)-pairs from user. */
|
||||
if((r=data_copy(caller->p_endpoint, (vir_bytes) m_ptr->DIO_VEC_ADDR,
|
||||
SYSTEM, (vir_bytes) vdevio_buf, bytes)) != OK)
|
||||
KERNEL, (vir_bytes) vdevio_buf, bytes)) != OK)
|
||||
return r;
|
||||
|
||||
privp= priv(caller);
|
||||
@@ -104,19 +104,6 @@ PUBLIC int do_vdevio(struct proc * caller, message * m_ptr)
|
||||
* the entire switch is wrapped in lock() and unlock() to prevent the I/O
|
||||
* batch from being interrupted.
|
||||
*/
|
||||
#if 0
|
||||
if(who_e == 71091) {
|
||||
static int vd = 0;
|
||||
if(vd++ < 100) {
|
||||
kprintf("proc %d does vdevio no %d; type %d, direction %s\n",
|
||||
who_e, vd, io_type, io_in ? "input" : "output");
|
||||
kprintf("(");
|
||||
for (i=0; i<vec_size; i++)
|
||||
kprintf("%2d:0x%x,0x%x ", i, pvb[i].port, pvb[i].value);
|
||||
kprintf(")\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
lock;
|
||||
switch (io_type) {
|
||||
case _DIO_BYTE: /* byte values */
|
||||
@@ -169,7 +156,7 @@ PUBLIC int do_vdevio(struct proc * caller, message * m_ptr)
|
||||
|
||||
/* Almost done, copy back results for input requests. */
|
||||
if (io_in)
|
||||
if((r=data_copy(SYSTEM, (vir_bytes) vdevio_buf,
|
||||
if((r=data_copy(KERNEL, (vir_bytes) vdevio_buf,
|
||||
caller->p_endpoint, (vir_bytes) m_ptr->DIO_VEC_ADDR,
|
||||
(phys_bytes) bytes)) != OK)
|
||||
return r;
|
||||
|
||||
@@ -129,19 +129,19 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr)
|
||||
|
||||
switch(p->p_vmrequest.type) {
|
||||
case VMSTYPE_KERNELCALL:
|
||||
/* Put on restart chain. */
|
||||
p->p_vmrequest.nextrestart = vmrestart;
|
||||
vmrestart = p;
|
||||
/*
|
||||
* we will have to resume execution of the kernel call
|
||||
* as soon the scheduler picks up this process again
|
||||
*/
|
||||
p->p_misc_flags |= MF_KCALL_RESUME;
|
||||
break;
|
||||
case VMSTYPE_DELIVERMSG:
|
||||
vmassert(p->p_misc_flags & MF_DELIVERMSG);
|
||||
vmassert(p == target);
|
||||
vmassert(RTS_ISSET(p, RTS_VMREQUEST));
|
||||
RTS_LOCK_UNSET(p, RTS_VMREQUEST);
|
||||
break;
|
||||
case VMSTYPE_MAP:
|
||||
vmassert(RTS_ISSET(p, RTS_VMREQUEST));
|
||||
RTS_LOCK_UNSET(p, RTS_VMREQUEST);
|
||||
break;
|
||||
default:
|
||||
#if DEBUG_VMASSERT
|
||||
@@ -152,7 +152,9 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr)
|
||||
p->p_vmrequest.type);
|
||||
}
|
||||
|
||||
RTS_LOCK_UNSET(p, RTS_VMREQUEST);
|
||||
return OK;
|
||||
|
||||
case VMCTL_ENABLE_PAGING:
|
||||
/*
|
||||
* system task must not get preempted while switching to paging,
|
||||
|
||||
Reference in New Issue
Block a user