This patch removes the global variables who_p and who_e from the

kernel (sys task).  The main reason is that these would have to become
cpu local variables on SMP.  Once the system task is not a task but a
genuine part of the kernel there is even less reason to have these
extra variables as proc_ptr will already contain all neccessary
information. In addition converting who_e to the process pointer and
back again all the time will be avoided.

Although proc_ptr will contain all important information, accessing it
as a cpu local variable will be fairly expensive, hence the value
would be assigned to some on stack local variable. Therefore it is
better to add the 'caller' argument to the syscall handlers to pass
the value on stack anyway. It also clearly denotes on who's behalf is
the syscall being executed.

This patch also ANSIfies the syscall function headers.

Last but not least, it also fixes a potential bug in virtual_copy_f()
in case the check is disabled. So far the function in case of a
failure could possible reuse an old who_p in case this function had
not been called from the system task.

virtual_copy_f() takes the caller as a parameter too. In case the
checking is disabled, the caller must be NULL and non NULL if it is
enabled as we must be able to suspend the caller.
This commit is contained in:
Tomas Hruby
2010-02-03 09:04:48 +00:00
parent 144de8a7b3
commit cca24d06d8
44 changed files with 232 additions and 284 deletions
+3 -3
View File
@@ -16,8 +16,7 @@
/*===========================================================================*
* do_abort *
*===========================================================================*/
PUBLIC int do_abort(m_ptr)
message *m_ptr; /* pointer to request message */
PUBLIC int do_abort(struct proc * caller, message * m_ptr)
{
/* Handle sys_abort. MINIX is unable to continue. This can originate e.g.
* in the PM (normal abort or panic) or TTY (after CTRL-ALT-DEL).
@@ -31,7 +30,8 @@ message *m_ptr; /* pointer to request message */
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,
if((p=data_copy(m_ptr->ABRT_MON_ENDPT,
(vir_bytes) m_ptr->ABRT_MON_ADDR,
SYSTEM, (vir_bytes) paramsbuffer, len)) != OK) {
return p;
}
+3 -3
View File
@@ -19,8 +19,7 @@
/*===========================================================================*
* do_copy *
*===========================================================================*/
PUBLIC int do_copy(m_ptr)
register message *m_ptr; /* pointer to request message */
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
@@ -86,7 +85,8 @@ register message *m_ptr; /* pointer to request message */
if (bytes != (phys_bytes) (vir_bytes) bytes) return(E2BIG);
/* Now try to make the actual virtual copy. */
return( virtual_copy_vmcheck(&vir_addr[_SRC_], &vir_addr[_DST_], bytes) );
return( virtual_copy_vmcheck(caller, &vir_addr[_SRC_],
&vir_addr[_DST_], bytes) );
}
#endif /* (USE_VIRCOPY || USE_PHYSCOPY) */
+1 -2
View File
@@ -19,8 +19,7 @@
/*===========================================================================*
* do_cprofile *
*===========================================================================*/
PUBLIC int do_cprofile(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_cprofile(struct proc * caller, message * m_ptr)
{
int proc_nr, i;
phys_bytes len;
+2 -6
View File
@@ -17,11 +17,8 @@
/*===========================================================================*
* do_devio *
*===========================================================================*/
PUBLIC int do_devio(
register message *m_ptr /* pointer to request message */
)
PUBLIC int do_devio(struct proc * caller, message * m_ptr)
{
struct proc *rp;
struct priv *privp;
port_t port;
struct io_range *iorp;
@@ -39,8 +36,7 @@ PUBLIC int do_devio(
default: size= 4; break; /* Be conservative */
}
rp= proc_addr(who_p);
privp= priv(rp);
privp= priv(caller);
if (!privp)
{
kprintf("no priv structure!\n");
+1 -2
View File
@@ -13,8 +13,7 @@
/*===========================================================================*
* do_endksig *
*===========================================================================*/
PUBLIC int do_endksig(m_ptr)
message *m_ptr; /* pointer to request message */
PUBLIC int do_endksig(struct proc * caller, message * m_ptr)
{
/* Finish up after a kernel type signal, caused by a SYS_KILL message or a
* call to cause_sig by a task. This is called by the PM after processing a
+2 -3
View File
@@ -16,8 +16,7 @@
/*===========================================================================*
* do_exec *
*===========================================================================*/
PUBLIC int do_exec(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_exec(struct proc * caller, message * m_ptr)
{
/* Handle sys_exec(). A process has done a successful EXEC. Patch it up. */
register struct proc *rp;
@@ -34,7 +33,7 @@ register message *m_ptr; /* pointer to request message */
}
/* Save command name for debugging, ps(1) output, etc. */
if(data_copy(who_e, (vir_bytes) m_ptr->PR_NAME_PTR,
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)
strncpy(rp->p_name, "<unset>", P_NAME_LEN);
+3 -4
View File
@@ -16,8 +16,7 @@ FORWARD _PROTOTYPE( void clear_proc, (register struct proc *rc));
/*===========================================================================*
* do_exit *
*===========================================================================*/
PUBLIC int do_exit(m_ptr)
message *m_ptr; /* pointer to request message */
PUBLIC int do_exit(struct proc * caller, message * m_ptr)
{
/* Handle sys_exit. A user process has exited or a system process requests
* to exit. Only the PM can request other process slots to be cleared.
@@ -28,7 +27,7 @@ message *m_ptr; /* pointer to request message */
int exit_e;
/* Determine what process exited. User processes are handled here. */
if (PM_PROC_NR == who_p) {
if (PM_PROC_NR == caller->p_endpoint) {
if (m_ptr->PR_ENDPT != SELF) { /* PM tries to exit self */
if(!isokendpt(m_ptr->PR_ENDPT, &exit_e)) /* get exiting process */
return EINVAL;
@@ -38,7 +37,7 @@ message *m_ptr; /* pointer to request message */
}
/* The PM or some other system process requested to be exited. */
clear_proc(proc_addr(who_p));
clear_proc(caller);
return(EDONTREPLY);
}
+2 -3
View File
@@ -20,8 +20,7 @@
/*===========================================================================*
* do_fork *
*===========================================================================*/
PUBLIC int do_fork(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_fork(struct proc * caller, message * m_ptr)
{
/* Handle sys_fork(). PR_ENDPT has forked. The child is PR_SLOT. */
#if (_MINIX_CHIP == _CHIP_INTEL)
@@ -101,7 +100,7 @@ register message *m_ptr; /* pointer to request message */
m_ptr->PR_FORK_MSGADDR = (char *) rpp->p_delivermsg_vir;
/* Install new map */
r = newmap(rpc, map_ptr);
r = newmap(caller, rpc, map_ptr);
FIXLINMSG(rpc);
/* Don't schedule process in VM mode until it has a new pagetable. */
+4 -8
View File
@@ -20,8 +20,7 @@
/*===========================================================================*
* do_getinfo *
*===========================================================================*/
PUBLIC int do_getinfo(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_getinfo(struct proc * caller, message * m_ptr)
{
/* Request system information to be copied to caller's address space. This
* call simply copies entire data structures to the caller.
@@ -29,12 +28,9 @@ register message *m_ptr; /* pointer to request message */
size_t length;
vir_bytes src_vir;
int nr_e, nr, r;
struct proc *caller;
int wipe_rnd_bin = -1;
struct exec e_hdr;
caller = proc_addr(who_p);
/* Set source address and length based on request type. */
switch (m_ptr->I_REQUEST) {
case GET_MACHINE: {
@@ -79,7 +75,7 @@ register message *m_ptr; /* pointer to request message */
}
case GET_PROC: {
nr_e = (m_ptr->I_VAL_LEN2_E == SELF) ?
who_e : m_ptr->I_VAL_LEN2_E;
caller->p_endpoint : m_ptr->I_VAL_LEN2_E;
if(!isokendpt(nr_e, &nr)) return EINVAL; /* validate request */
length = sizeof(struct proc);
src_vir = (vir_bytes) proc_addr(nr);
@@ -87,7 +83,7 @@ register message *m_ptr; /* pointer to request message */
}
case GET_PRIV: {
nr_e = (m_ptr->I_VAL_LEN2_E == SELF) ?
who_e : m_ptr->I_VAL_LEN2_E;
caller->p_endpoint : m_ptr->I_VAL_LEN2_E;
if(!isokendpt(nr_e, &nr)) return EINVAL; /* validate request */
length = sizeof(struct priv);
src_vir = (vir_bytes) priv_addr(nr_to_id(nr));
@@ -188,7 +184,7 @@ register message *m_ptr; /* pointer to request message */
/* 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(SYSTEM, src_vir, who_e,
r = data_copy_vmcheck(caller, SYSTEM, src_vir, caller->p_endpoint,
(vir_bytes) m_ptr->I_VAL_PTR, length);
if(r != OK) return r;
+1 -2
View File
@@ -15,8 +15,7 @@
/*===========================================================================*
* do_getksig *
*===========================================================================*/
PUBLIC int do_getksig(m_ptr)
message *m_ptr; /* pointer to request message */
PUBLIC int do_getksig(struct proc * caller, message * m_ptr)
{
/* PM is ready to accept signals and repeatedly does a kernel call to get
* one. Find a process with pending signals. If no signals are available,
+2 -5
View File
@@ -20,8 +20,7 @@ FORWARD _PROTOTYPE(int generic_handler, (irq_hook_t *hook));
/*===========================================================================*
* do_irqctl *
*===========================================================================*/
PUBLIC int do_irqctl(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_irqctl(struct proc * caller, message * m_ptr)
{
/* Dismember the request message. */
int irq_vec;
@@ -30,7 +29,6 @@ register message *m_ptr; /* pointer to request message */
int r = OK;
int i;
irq_hook_t *hook_ptr;
struct proc *rp;
struct priv *privp;
/* Hook identifiers start at 1 and end at NR_IRQ_HOOKS. */
@@ -61,8 +59,7 @@ register message *m_ptr; /* pointer to request message */
/* Check if IRQ line is acceptable. */
if (irq_vec < 0 || irq_vec >= NR_IRQ_VECTORS) return(EINVAL);
rp= proc_addr(who_p);
privp= priv(rp);
privp= priv(caller);
if (!privp)
{
kprintf("do_irqctl: no priv structure!\n");
+1 -2
View File
@@ -14,8 +14,7 @@
/*===========================================================================*
* do_kill *
*===========================================================================*/
PUBLIC int do_kill(m_ptr)
message *m_ptr; /* pointer to request message */
PUBLIC int do_kill(struct proc * caller, message * m_ptr)
{
/* Handle sys_kill(). Cause a signal to be sent to a process. The PM is the
* central server where all signals are processed and handler policies can
+1 -2
View File
@@ -14,8 +14,7 @@
/*===========================================================================*
* do_memset *
*===========================================================================*/
PUBLIC int do_memset(m_ptr)
register message *m_ptr;
PUBLIC int do_memset(struct proc * caller, message * m_ptr)
{
/* Handle sys_memset(). This writes a pattern into the specified memory. */
unsigned char c = m_ptr->MEM_PATTERN;
+5 -8
View File
@@ -13,11 +13,10 @@
/*===========================================================================*
* do_newmap *
*===========================================================================*/
PUBLIC int do_newmap(m_ptr)
message *m_ptr; /* pointer to request message */
PUBLIC int do_newmap(struct proc * caller, message * m_ptr)
{
/* Handle sys_newmap(). Fetch the memory map. */
register struct proc *rp; /* process whose map is to be loaded */
struct proc *rp; /* process whose map is to be loaded */
struct mem_map *map_ptr; /* virtual address of map inside caller */
int proc_nr;
@@ -26,20 +25,18 @@ message *m_ptr; /* pointer to request message */
if (iskerneln(proc_nr)) return(EPERM);
rp = proc_addr(proc_nr);
return newmap(rp, map_ptr);
return newmap(caller, rp, map_ptr);
}
/*===========================================================================*
* newmap *
*===========================================================================*/
PUBLIC int newmap(rp, map_ptr)
struct proc *rp; /* process whose map is to be loaded */
struct mem_map *map_ptr; /* virtual address of map inside caller */
PUBLIC int newmap(struct proc *caller, struct proc *rp, struct mem_map *map_ptr)
{
int r;
/* Fetch the memory map. */
if((r=data_copy(who_e, (vir_bytes) map_ptr,
if((r=data_copy(caller->p_endpoint, (vir_bytes) map_ptr,
SYSTEM, (vir_bytes) rp->p_memmap, sizeof(rp->p_memmap))) != OK) {
kprintf("newmap: data_copy failed! (%d)\n", r);
return r;
+1 -1
View File
@@ -14,7 +14,7 @@
/*===========================================================================*
* do_nice *
*===========================================================================*/
PUBLIC int do_nice(message *m_ptr)
PUBLIC int do_nice(struct proc * caller, message * m_ptr)
{
/* Change process priority or stop the process. */
int proc_nr, pri, new_q ;
+10 -12
View File
@@ -11,20 +11,19 @@
#include "../ipc.h"
#include <signal.h>
#include <string.h>
#include <minix/endpoint.h>
#if USE_PRIVCTL
/*===========================================================================*
* do_privctl *
*===========================================================================*/
PUBLIC int do_privctl(m_ptr)
message *m_ptr; /* pointer to request message */
PUBLIC int do_privctl(struct proc * caller, message * m_ptr)
{
/* Handle sys_privctl(). Update a process' privileges. If the process is not
* yet a system process, make sure it gets its own privilege structure.
*/
register struct proc *caller_ptr;
register struct proc *rp;
struct proc *rp;
int proc_nr;
int priv_id;
int ipc_to_m, kcalls;
@@ -39,9 +38,8 @@ message *m_ptr; /* pointer to request message */
* running by the RTS_NO_PRIV flag. This flag is set when a privileged process
* forks.
*/
caller_ptr = proc_addr(who_p);
if (! (priv(caller_ptr)->s_flags & SYS_PROC)) return(EPERM);
if(m_ptr->CTL_ENDPT == SELF) proc_nr = who_p;
if (! (priv(caller)->s_flags & SYS_PROC)) return(EPERM);
if(m_ptr->CTL_ENDPT == SELF) proc_nr = _ENDPOINT_P(caller->p_endpoint);
else if(!isokendpt(m_ptr->CTL_ENDPT, &proc_nr)) return(EINVAL);
rp = proc_addr(proc_nr);
@@ -72,7 +70,7 @@ message *m_ptr; /* pointer to request message */
if (m_ptr->CTL_ARG_PTR)
{
/* Copy privilege structure from caller */
if((r=data_copy(who_e, (vir_bytes) m_ptr->CTL_ARG_PTR,
if((r=data_copy(caller->p_endpoint, (vir_bytes) m_ptr->CTL_ARG_PTR,
SYSTEM, (vir_bytes) &priv, sizeof(priv))) != OK)
return r;
@@ -93,7 +91,7 @@ message *m_ptr; /* pointer to request message */
return(i);
}
priv_id = priv(rp)->s_id; /* backup privilege id */
*priv(rp) = *priv(caller_ptr); /* copy from caller */
*priv(rp) = *priv(caller); /* copy from caller */
priv(rp)->s_id = priv_id; /* restore privilege id */
priv(rp)->s_proc_nr = proc_nr; /* reassociate process nr */
@@ -227,7 +225,7 @@ message *m_ptr; /* pointer to request message */
#endif
/* Get the I/O range */
data_copy(who_e, (vir_bytes) m_ptr->CTL_ARG_PTR,
data_copy(caller->p_endpoint, (vir_bytes) m_ptr->CTL_ARG_PTR,
SYSTEM, (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;
@@ -249,7 +247,7 @@ message *m_ptr; /* pointer to request message */
return EPERM;
/* Get the memory range */
if((r=data_copy(who_e, (vir_bytes) m_ptr->CTL_ARG_PTR,
if((r=data_copy(caller->p_endpoint, (vir_bytes) m_ptr->CTL_ARG_PTR,
SYSTEM, (vir_bytes) &mem_range, sizeof(mem_range))) != OK)
return r;
priv(rp)->s_flags |= CHECK_MEM; /* Check memory mappings */
@@ -271,7 +269,7 @@ message *m_ptr; /* pointer to request message */
if (!(priv(rp)->s_flags & SYS_PROC))
return EPERM;
data_copy(who_e, (vir_bytes) m_ptr->CTL_ARG_PTR,
data_copy(caller->p_endpoint, (vir_bytes) m_ptr->CTL_ARG_PTR,
SYSTEM, (vir_bytes) &irq, sizeof(irq));
priv(rp)->s_flags |= CHECK_IRQ; /* Check IRQs */
+2 -3
View File
@@ -14,8 +14,7 @@
/*===========================================================================*
* do_profbuf *
*===========================================================================*/
PUBLIC int do_profbuf(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_profbuf(struct proc * caller, message * m_ptr)
{
/* This kernel call is used by profiled system processes when Call
* Profiling is enabled. It is called on the first execution of procentry.
@@ -35,7 +34,7 @@ register message *m_ptr; /* pointer to request message */
rp = proc_addr(proc_nr);
cprof_proc_info[cprof_procs_no].endpt = who_e;
cprof_proc_info[cprof_procs_no].endpt = caller->p_endpoint;
cprof_proc_info[cprof_procs_no].name = rp->p_name;
cprof_proc_info[cprof_procs_no].ctl_v = (vir_bytes) m_ptr->PROF_CTL_PTR;
+1 -1
View File
@@ -14,7 +14,7 @@
/*===========================================================================*
* do_runctl *
*===========================================================================*/
PUBLIC int do_runctl(message *m_ptr)
PUBLIC int do_runctl(struct proc * caller, message * m_ptr)
{
/* Control a process's RTS_PROC_STOP flag. Used for process management.
* If the process is queued sending a message or stopped for system call
+21 -18
View File
@@ -25,7 +25,8 @@
#define USE_COW_SAFECOPY 0
FORWARD _PROTOTYPE(int safecopy, (endpoint_t, endpoint_t, cp_grant_id_t, int, int, size_t, vir_bytes, vir_bytes, int));
FORWARD _PROTOTYPE(int safecopy, (struct proc *, endpoint_t, endpoint_t,
cp_grant_id_t, int, int, size_t, vir_bytes, vir_bytes, int));
#define HASGRANTTABLE(gr) \
(!RTS_ISSET(gr, RTS_NO_PRIV) && priv(gr) && priv(gr)->s_grant_table > 0)
@@ -217,8 +218,9 @@ endpoint_t *e_granter; /* new granter (magic grants) */
/*===========================================================================*
* safecopy *
*===========================================================================*/
PRIVATE int safecopy(granter, grantee, grantid, src_seg, dst_seg, bytes,
PRIVATE int safecopy(caller, granter, grantee, grantid, src_seg, dst_seg, bytes,
g_offset, addr, access)
struct proc * caller;
endpoint_t granter, grantee;
cp_grant_id_t grantid;
int src_seg, dst_seg;
@@ -232,8 +234,10 @@ int access; /* CPF_READ for a copy from granter to grantee, CPF_WRITE
static vir_bytes v_offset;
endpoint_t new_granter, *src, *dst;
struct proc *granter_p;
vir_bytes size;
int r;
#if USE_COW_SAFECOPY
vir_bytes size;
#endif
/* See if there is a reasonable grant table. */
if(!(granter_p = endpoint_lookup(granter))) return EINVAL;
@@ -286,13 +290,13 @@ int access; /* CPF_READ for a copy from granter to grantee, CPF_WRITE
/* Give up on COW immediately when offsets are not aligned
* or we are copying less than a page.
*/
return virtual_copy_vmcheck(&v_src, &v_dst, bytes);
return virtual_copy_vmcheck(caller, &v_src, &v_dst, bytes);
}
if((size = v_offset % CLICK_SIZE) != 0) {
/* Normal copy for everything before the first page boundary. */
size = CLICK_SIZE - size;
r = virtual_copy_vmcheck(&v_src, &v_dst, size);
r = virtual_copy_vmcheck(caller, &v_src, &v_dst, size);
if(r != OK)
return r;
v_src.offset += size;
@@ -314,22 +318,21 @@ int access; /* CPF_READ for a copy from granter to grantee, CPF_WRITE
}
if(bytes != 0) {
/* Normal copy for everything after the last page boundary. */
r = virtual_copy_vmcheck(&v_src, &v_dst, bytes);
r = virtual_copy_vmcheck(caller, &v_src, &v_dst, bytes);
if(r != OK)
return r;
}
return OK;
#else
return virtual_copy_vmcheck(&v_src, &v_dst, bytes);
return virtual_copy_vmcheck(caller, &v_src, &v_dst, bytes);
#endif
}
/*===========================================================================*
* do_safecopy *
*===========================================================================*/
PUBLIC int do_safecopy(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_safecopy(struct proc * caller, message * m_ptr)
{
static int access, src_seg, dst_seg;
@@ -344,16 +347,15 @@ register message *m_ptr; /* pointer to request message */
access = CPF_WRITE;
} else minix_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);
return safecopy(caller, m_ptr->SCP_FROM_TO, caller->p_endpoint,
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 */
PUBLIC int do_vsafecopy(struct proc * caller, message * m_ptr)
{
static struct vscp_vec vec[SCPVEC_NR];
static struct vir_addr src, dst;
@@ -361,7 +363,7 @@ register message *m_ptr; /* pointer to request message */
size_t bytes;
/* Set vector copy parameters. */
src.proc_nr_e = who_e;
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;
@@ -372,7 +374,7 @@ register message *m_ptr; /* pointer to request message */
bytes = els * sizeof(struct vscp_vec);
/* Obtain vector of copies. */
if((r=virtual_copy_vmcheck(&src, &dst, bytes)) != OK)
if((r=virtual_copy_vmcheck(caller, &src, &dst, bytes)) != OK)
return r;
/* Perform safecopies. */
@@ -387,12 +389,13 @@ register message *m_ptr; /* pointer to request message */
granter = vec[i].v_from;
} else {
kprintf("vsafecopy: %d: element %d/%d: no SELF found\n",
who_e, i, els);
caller->p_endpoint, i, els);
return EINVAL;
}
/* Do safecopy for this element. */
if((r=safecopy(granter, who_e, vec[i].v_gid, D, D,
if((r=safecopy(caller, granter, caller->p_endpoint,
vec[i].v_gid, D, D,
vec[i].v_bytes, vec[i].v_offset,
vec[i].v_addr, access)) != OK) {
return r;
+23 -26
View File
@@ -115,17 +115,17 @@ static int clear_info(struct map_info_s *p)
/*===========================================================================*
* map_invoke_vm *
*===========================================================================*/
PUBLIC int map_invoke_vm(int req_type, /* VMPTYPE_... COWMAP, SMAP, SUNMAP */
endpoint_t end_d, int seg_d, vir_bytes off_d,
endpoint_t end_s, int seg_s, vir_bytes off_s,
size_t size, int flag)
PUBLIC int map_invoke_vm(struct proc * caller,
int req_type, /* VMPTYPE_... COWMAP, SMAP, SUNMAP */
endpoint_t end_d, int seg_d, vir_bytes off_d,
endpoint_t end_s, int seg_s, vir_bytes off_s,
size_t size, int flag)
{
struct proc *caller, *src, *dst;
struct proc *src, *dst;
phys_bytes lin_src, lin_dst;
src = endpoint_lookup(end_s);
dst = endpoint_lookup(end_d);
caller = endpoint_lookup(who_e);
lin_src = umap_local(src, seg_s, off_s, size);
lin_dst = umap_local(dst, seg_d, off_d, size);
@@ -170,8 +170,7 @@ PUBLIC int map_invoke_vm(int req_type, /* VMPTYPE_... COWMAP, SMAP, SUNMAP */
/*===========================================================================*
* do_safemap *
*===========================================================================*/
PUBLIC int do_safemap(m_ptr)
register message *m_ptr;
PUBLIC int do_safemap(struct proc * caller, message * m_ptr)
{
endpoint_t grantor = m_ptr->SMAP_EP;
cp_grant_id_t gid = m_ptr->SMAP_GID;
@@ -199,42 +198,42 @@ register message *m_ptr;
*/
if(flag != 0)
access |= CPF_WRITE;
r = verify_grant(grantor, who_e, gid, bytes, access,
r = verify_grant(grantor, caller->p_endpoint, gid, bytes, access,
offset, &offset_result, &new_grantor);
if(r != OK) {
kprintf("verify_grant for gid %d from %d to %d failed: %d\n",
gid, grantor, who_e, r);
gid, grantor, caller->p_endpoint, r);
return r;
}
/* Add map info. */
r = add_info(new_grantor, who_e, gid, offset, offset_result, seg,
address, bytes);
r = add_info(new_grantor, caller->p_endpoint, gid, offset,
offset_result, seg, address, bytes);
if(r != OK)
return r;
/* Invoke VM. */
return map_invoke_vm(VMPTYPE_SMAP,
who_e, seg, address, new_grantor, D, offset_result, bytes,flag);
return map_invoke_vm(caller, VMPTYPE_SMAP,
caller->p_endpoint, seg, address, new_grantor, D, offset_result, bytes,flag);
}
/*===========================================================================*
* safeunmap *
*===========================================================================*/
PRIVATE int safeunmap(struct map_info_s *p)
PRIVATE int safeunmap(struct proc * caller, struct map_info_s *p)
{
vir_bytes offset_result;
endpoint_t new_grantor;
int r;
r = verify_grant(p->grantor, p->grantee, p->gid, p->bytes, CPF_MAP,
p->offset, &offset_result, &new_grantor);
r = verify_grant(p->grantor, p->grantee, p->gid, p->bytes,
CPF_MAP, p->offset, &offset_result, &new_grantor);
if(r != OK) {
kprintf("safeunmap: error in verify_grant.\n");
return r;
}
r = map_invoke_vm(VMPTYPE_SUNMAP,
r = map_invoke_vm(caller, VMPTYPE_SUNMAP,
p->grantee, p->seg, p->address,
new_grantor, D, offset_result,
p->bytes, 0);
@@ -249,16 +248,15 @@ PRIVATE int safeunmap(struct map_info_s *p)
/*===========================================================================*
* do_saferevmap *
*===========================================================================*/
PUBLIC int do_saferevmap(m_ptr)
register message *m_ptr;
PUBLIC int do_saferevmap(struct proc * caller, message * m_ptr)
{
struct map_info_s *p;
int flag = m_ptr->SMAP_FLAG;
int arg = m_ptr->SMAP_GID; /* gid or address_Dseg */
int r;
while((p = get_revoke_info(who_e, flag, arg)) != NULL) {
if((r = safeunmap(p)) != OK)
while((p = get_revoke_info(caller->p_endpoint, flag, arg)) != NULL) {
if((r = safeunmap(caller, p)) != OK)
return r;
}
return OK;
@@ -267,16 +265,15 @@ register message *m_ptr;
/*===========================================================================*
* do_safeunmap *
*===========================================================================*/
PUBLIC int do_safeunmap(m_ptr)
register message *m_ptr;
PUBLIC int do_safeunmap(struct proc * caller, message * m_ptr)
{
vir_bytes address = m_ptr->SMAP_ADDRESS;
int seg = (int)m_ptr->SMAP_SEG;
struct map_info_s *p;
int r;
while((p = get_unmap_info(who_e, seg, address)) != NULL) {
if((r = safeunmap(p)) != OK)
while((p = get_unmap_info(caller->p_endpoint, seg, address)) != NULL) {
if((r = safeunmap(caller, p)) != OK)
return r;
}
return OK;
+6 -9
View File
@@ -15,8 +15,7 @@
/*===========================================================================*
* do_segctl *
*===========================================================================*/
PUBLIC int do_segctl(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_segctl(struct proc * caller, message * m_ptr)
{
/* Return a segment selector and offset that can be used to reach a physical
* address, for use by a driver doing memory I/O in the A0000 - DFFFF range.
@@ -24,26 +23,24 @@ register message *m_ptr; /* pointer to request message */
u32_t selector;
vir_bytes offset;
int i, index;
register struct proc *rp;
phys_bytes phys = (phys_bytes) m_ptr->SEG_PHYS;
vir_bytes size = (vir_bytes) m_ptr->SEG_SIZE;
int result;
/* First check if there is a slot available for this segment. */
rp = proc_addr(who_p);
index = -1;
for (i=0; i < NR_REMOTE_SEGS; i++) {
if (! rp->p_priv->s_farmem[i].in_use) {
if (! caller->p_priv->s_farmem[i].in_use) {
index = i;
rp->p_priv->s_farmem[i].in_use = TRUE;
rp->p_priv->s_farmem[i].mem_phys = phys;
rp->p_priv->s_farmem[i].mem_len = size;
caller->p_priv->s_farmem[i].in_use = TRUE;
caller->p_priv->s_farmem[i].mem_phys = phys;
caller->p_priv->s_farmem[i].mem_len = size;
break;
}
}
if (index < 0) return(ENOSPC);
offset = alloc_remote_segment(&selector, &rp->p_seg,
offset = alloc_remote_segment(&selector, &caller->p_seg,
i, phys, size, USER_PRIVILEGE);
result = OK;
+3 -6
View File
@@ -18,11 +18,9 @@ FORWARD _PROTOTYPE( void cause_alarm, (timer_t *tp) );
/*===========================================================================*
* do_setalarm *
*===========================================================================*/
PUBLIC int do_setalarm(m_ptr)
message *m_ptr; /* pointer to request message */
PUBLIC int do_setalarm(struct proc * caller, message * m_ptr)
{
/* A process requests a synchronous alarm, or wants to cancel its alarm. */
register struct proc *rp; /* pointer to requesting process */
long exp_time; /* expiration time for this alarm */
int use_abs_time; /* use absolute or relative time */
timer_t *tp; /* the process' timer structure */
@@ -31,11 +29,10 @@ message *m_ptr; /* pointer to request message */
/* Extract shared parameters from the request message. */
exp_time = m_ptr->ALRM_EXP_TIME; /* alarm's expiration time */
use_abs_time = m_ptr->ALRM_ABS_TIME; /* flag for absolute time */
rp = proc_addr(who_p);
if (! (priv(rp)->s_flags & SYS_PROC)) return(EPERM);
if (! (priv(caller)->s_flags & SYS_PROC)) return(EPERM);
/* Get the timer structure and set the parameters for this alarm. */
tp = &(priv(rp)->s_alarm_timer);
tp = &(priv(caller)->s_alarm_timer);
tmr_arg(tp)->ta_int = m_ptr->m_source;
tp->tmr_func = cause_alarm;
+3 -8
View File
@@ -12,20 +12,15 @@
/*===========================================================================*
* do_setgrant *
*===========================================================================*/
PUBLIC int do_setgrant(m_ptr)
message *m_ptr;
PUBLIC int do_setgrant(struct proc * caller, message * m_ptr)
{
struct proc *rp;
int r;
/* Who wants to set a parameter? */
rp = proc_addr(who_p);
/* Copy grant table set in priv. struct. */
if (RTS_ISSET(rp, RTS_NO_PRIV) || !(priv(rp))) {
if (RTS_ISSET(caller, RTS_NO_PRIV) || !(priv(caller))) {
r = EPERM;
} else {
_K_SET_GRANT_TABLE(rp,
_K_SET_GRANT_TABLE(caller,
(vir_bytes) m_ptr->SG_ADDR,
m_ptr->SG_SIZE);
r = OK;
+1 -2
View File
@@ -17,8 +17,7 @@
/*===========================================================================*
* do_sigreturn *
*===========================================================================*/
PUBLIC int do_sigreturn(m_ptr)
message *m_ptr; /* pointer to request message */
PUBLIC int do_sigreturn(struct proc * caller, message * m_ptr)
{
/* POSIX style signals require sys_sigreturn to put things in order before
* the signalled process can resume execution
+6 -8
View File
@@ -18,8 +18,7 @@
/*===========================================================================*
* do_sigsend *
*===========================================================================*/
PUBLIC int do_sigsend(m_ptr)
message *m_ptr; /* pointer to request message */
PUBLIC int do_sigsend(struct proc * caller, message * m_ptr)
{
/* Handle sys_sigsend, POSIX-style signal handling. */
@@ -37,8 +36,9 @@ message *m_ptr; /* pointer to request message */
rp = proc_addr(proc_nr);
/* Get the sigmsg structure into our address space. */
if((r=data_copy_vmcheck(who_e, (vir_bytes) m_ptr->SIG_CTXT_PTR,
SYSTEM, (vir_bytes) &smsg, (phys_bytes) sizeof(struct sigmsg))) != OK)
if((r=data_copy_vmcheck(caller, caller->p_endpoint,
(vir_bytes) m_ptr->SIG_CTXT_PTR, SYSTEM, (vir_bytes) &smsg,
(phys_bytes) sizeof(struct sigmsg))) != OK)
return r;
/* Compute the user stack pointer where sigcontext will be stored. */
@@ -57,7 +57,7 @@ message *m_ptr; /* pointer to request message */
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(SYSTEM, (vir_bytes) &sc, m_ptr->SIG_ENDPT,
if((r=data_copy_vmcheck(caller, SYSTEM, (vir_bytes) &sc, m_ptr->SIG_ENDPT,
(vir_bytes) scp, (vir_bytes) sizeof(struct sigcontext))) != OK)
return r;
@@ -106,7 +106,7 @@ message *m_ptr; /* pointer to request message */
fr.sf_retadr = (void (*)()) smsg.sm_sigreturn;
/* Copy the sigframe structure to the user's stack. */
if((r=data_copy_vmcheck(SYSTEM, (vir_bytes) &fr,
if((r=data_copy_vmcheck(caller, SYSTEM, (vir_bytes) &fr,
m_ptr->SIG_ENDPT, (vir_bytes) frp,
(vir_bytes) sizeof(struct sigframe))) != OK)
return r;
@@ -119,8 +119,6 @@ message *m_ptr; /* pointer to request message */
rp->p_misc_flags &= ~MF_FPU_INITIALIZED;
if(!RTS_ISSET(rp, RTS_PROC_STOP)) {
struct proc *caller;
caller = proc_addr(who_p);
kprintf("system: warning: sigsend a running process\n");
kprintf("caller stack: ");
proc_stacktrace(caller);
+1 -2
View File
@@ -23,8 +23,7 @@ PRIVATE vir_bytes sprof_info_addr_vir;
/*===========================================================================*
* do_sprofile *
*===========================================================================*/
PUBLIC int do_sprofile(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_sprofile(struct proc * caller, message * m_ptr)
{
int proc_nr;
+1 -2
View File
@@ -12,8 +12,7 @@
/*===========================================================================*
* do_stime *
*===========================================================================*/
PUBLIC int do_stime(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_stime(struct proc * caller, message * m_ptr)
{
boottime= m_ptr->T_BOOTTIME;
return(OK);
+3 -6
View File
@@ -12,16 +12,12 @@
/*===========================================================================*
* do_sysctl *
*===========================================================================*/
PUBLIC int do_sysctl(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_sysctl(struct proc * caller, message * m_ptr)
{
vir_bytes len, buf;
static char mybuf[DIAG_BUFSIZE];
struct proc *caller;
int s, i, proc_nr;
caller = proc_addr(who_p);
switch (m_ptr->SYSCTL_CODE) {
case SYSCTL_CODE_DIAG:
buf = (vir_bytes) m_ptr->SYSCTL_ARG1;
@@ -31,7 +27,8 @@ register message *m_ptr; /* pointer to request message */
caller->p_endpoint, len);
return EINVAL;
}
if((s=data_copy_vmcheck(who_e, buf, SYSTEM, (vir_bytes) mybuf, len)) != OK) {
if((s=data_copy_vmcheck(caller, caller->p_endpoint, buf, SYSTEM,
(vir_bytes) mybuf, len)) != OK) {
kprintf("do_sysctl: diag for %d: len %d: copy failed: %d\n",
caller->p_endpoint, len, s);
return s;
+1 -2
View File
@@ -18,8 +18,7 @@
/*===========================================================================*
* do_times *
*===========================================================================*/
PUBLIC int do_times(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_times(struct proc * caller, message * m_ptr)
{
/* Handle sys_times(). Retrieve the accounting information. */
register struct proc *rp;
+5 -4
View File
@@ -16,8 +16,7 @@
/*==========================================================================*
* do_trace *
*==========================================================================*/
PUBLIC int do_trace(m_ptr)
register message *m_ptr;
PUBLIC int do_trace(struct proc * caller, message * m_ptr)
{
/* Handle the debugging commands supported by the ptrace system call
* The commands are:
@@ -61,7 +60,8 @@ register message *m_ptr;
toaddr.offset = (addr); \
fromaddr.segment = D; \
toaddr.segment = (seg); \
if((r=virtual_copy_vmcheck(&fromaddr, &toaddr, length)) != OK) { \
if((r=virtual_copy_vmcheck(caller, &fromaddr, \
&toaddr, length)) != OK) { \
printf("Can't copy in sys_trace: %d\n", r);\
return r;\
} \
@@ -76,7 +76,8 @@ register message *m_ptr;
toaddr.offset = (myaddr); \
fromaddr.segment = (seg); \
toaddr.segment = D; \
if((r=virtual_copy_vmcheck(&fromaddr, &toaddr, length)) != OK) { \
if((r=virtual_copy_vmcheck(caller, &fromaddr, \
&toaddr, length)) != OK) { \
printf("Can't copy in sys_trace: %d\n", r);\
return r;\
} \
+7 -9
View File
@@ -11,13 +11,14 @@
#include "../system.h"
#include <minix/endpoint.h>
#if USE_UMAP
/*==========================================================================*
* do_umap *
*==========================================================================*/
PUBLIC int do_umap(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_umap(struct proc * caller, message * m_ptr)
{
/* Map virtual address to physical, for non-kernel processes. */
int seg_type = m_ptr->CP_SRC_SPACE & SEGMENT_TYPE;
@@ -28,20 +29,16 @@ register message *m_ptr; /* pointer to request message */
int proc_nr, r;
int naughty = 0;
phys_bytes phys_addr = 0, lin_addr = 0;
int caller_pn;
struct proc *targetpr, *caller;
struct proc *targetpr;
/* Verify process number. */
if (endpt == SELF)
proc_nr = who_p;
proc_nr = _ENDPOINT_P(caller->p_endpoint);
else
if (! isokendpt(endpt, &proc_nr))
return(EINVAL);
targetpr = proc_addr(proc_nr);
okendpt(who_e, &caller_pn);
caller = proc_addr(caller_pn);
/* See which mapping should be made. */
switch(seg_type) {
case LOCAL_SEG:
@@ -110,7 +107,8 @@ register message *m_ptr; /* pointer to request message */
m_ptr->CP_DST_ADDR = phys_addr;
if(naughty || phys_addr == 0) {
kprintf("kernel: umap 0x%x done by %d / %s, pc 0x%lx, 0x%lx -> 0x%lx\n",
seg_type, who_e, caller->p_name, caller->p_reg.pc, offset, phys_addr);
seg_type, caller->p_endpoint, caller->p_name,
caller->p_reg.pc, offset, phys_addr);
kprintf("caller stack: ");
proc_stacktrace(caller);
}
+3 -3
View File
@@ -7,10 +7,10 @@
/*===========================================================================*
* do_unused *
*===========================================================================*/
PUBLIC int do_unused(m)
message *m; /* pointer to request message */
PUBLIC int do_unused(struct proc * caller, message * m_ptr)
{
kprintf("SYSTEM: got unused request %d from %d\n", m->m_type, m->m_source);
kprintf("SYSTEM: got unused request %d from %d\n",
m_ptr->m_type, m_ptr->m_source);
return(EBADREQUEST); /* illegal message type */
}
+4 -7
View File
@@ -23,8 +23,7 @@ PRIVATE pvl_pair_t *pvl = (pvl_pair_t *) vdevio_buf;
/*===========================================================================*
* do_vdevio *
*===========================================================================*/
PUBLIC int do_vdevio(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_vdevio(struct proc * caller, message * m_ptr)
{
/* Perform a series of device I/O on behalf of a non-kernel process. The
* I/O addresses and I/O values are fetched from and returned to some buffer
@@ -38,7 +37,6 @@ register message *m_ptr; /* pointer to request message */
port_t port;
int i, j, io_size, nr_io_range;
int io_dir, io_type;
struct proc *rp;
struct priv *privp;
struct io_range *iorp;
int r;
@@ -68,12 +66,11 @@ register message *m_ptr; /* pointer to request message */
if (bytes > sizeof(vdevio_buf)) return(E2BIG);
/* Copy (port,value)-pairs from user. */
if((r=data_copy(who_e, (vir_bytes) m_ptr->DIO_VEC_ADDR,
if((r=data_copy(caller->p_endpoint, (vir_bytes) m_ptr->DIO_VEC_ADDR,
SYSTEM, (vir_bytes) vdevio_buf, bytes)) != OK)
return r;
rp= proc_addr(who_p);
privp= priv(rp);
privp= priv(caller);
if (privp && (privp->s_flags & CHECK_IO_PORT))
{
/* Check whether the I/O is allowed */
@@ -173,7 +170,7 @@ register message *m_ptr; /* pointer to request message */
/* Almost done, copy back results for input requests. */
if (io_in)
if((r=data_copy(SYSTEM, (vir_bytes) vdevio_buf,
who_e, (vir_bytes) m_ptr->DIO_VEC_ADDR,
caller->p_endpoint, (vir_bytes) m_ptr->DIO_VEC_ADDR,
(phys_bytes) bytes)) != OK)
return r;
return(OK);
+2 -3
View File
@@ -15,8 +15,7 @@
/*===========================================================================*
* do_vmctl *
*===========================================================================*/
PUBLIC int do_vmctl(m_ptr)
register message *m_ptr; /* pointer to request message */
PUBLIC int do_vmctl(struct proc * caller, message * m_ptr)
{
int proc_nr;
endpoint_t ep = m_ptr->SVMCTL_WHO;
@@ -171,7 +170,7 @@ register message *m_ptr; /* pointer to request message */
unlock;
return err;
}
if(newmap(p, (struct mem_map *) m_ptr->SVMCTL_VALUE) != OK)
if(newmap(caller, p, (struct mem_map *) m_ptr->SVMCTL_VALUE) != OK)
minix_panic("do_vmctl: newmap failed", NO_NUM);
FIXLINMSG(p);
vmassert(p->p_delivermsg_lin);
+2 -5
View File
@@ -18,11 +18,9 @@
/*===========================================================================*
* do_vtimer *
*===========================================================================*/
PUBLIC int do_vtimer(m_ptr)
message *m_ptr; /* pointer to request message */
PUBLIC int do_vtimer(struct proc * caller, message * m_ptr)
{
/* Set and/or retrieve the value of one of a process' virtual timers. */
struct proc *rrp; /* pointer to requesting process */
struct proc *rp; /* pointer to process the timer belongs to */
register int pt_flag; /* the misc on/off flag for the req.d timer */
register clock_t *pt_left; /* pointer to the process' ticks-left field */
@@ -30,8 +28,7 @@ message *m_ptr; /* pointer to request message */
int proc_nr, proc_nr_e;
/* The requesting process must be privileged. */
rrp = proc_addr(who_p);
if (! (priv(rrp)->s_flags & SYS_PROC)) return(EPERM);
if (! (priv(caller)->s_flags & SYS_PROC)) return(EPERM);
if (m_ptr->VT_WHICH != VT_VIRTUAL && m_ptr->VT_WHICH != VT_PROF)
return(EINVAL);