diff --git a/kernel/clock.c b/kernel/clock.c index d8dfb0d2c..6417d1921 100755 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -131,7 +131,7 @@ message *m_ptr; /* pointer to request message */ PRIVATE void init_clock() { /* Initialize the CLOCK's interrupt hook. */ - clock_hook.proc_nr = CLOCK; + clock_hook.proc_nr_e = CLOCK; /* Initialize channel 0 of the 8253A timer to, e.g., 60 Hz. */ outb(TIMER_MODE, SQUARE_WAVE); /* set timer to run continuously */ diff --git a/kernel/const.h b/kernel/const.h index e1d040bef..1c5bc88ee 100755 --- a/kernel/const.h +++ b/kernel/const.h @@ -23,6 +23,10 @@ #define structof(type, field, ptr) \ ((type *) (((char *) (ptr)) - offsetof(type, field))) +/* Translate an endpoint number to a process number, return success. */ +#define isokendpt(e,p) isokendpt_d((e),(p),0) +#define okendpt(e,p) isokendpt_d((e),(p),1) + /* Constants used in virtual_copy(). Values must be 0 and 1, respectively. */ #define _SRC_ 0 #define _DST_ 1 diff --git a/kernel/glo.h b/kernel/glo.h index ada3607ed..2b6f270a0 100755 --- a/kernel/glo.h +++ b/kernel/glo.h @@ -46,6 +46,7 @@ EXTERN int irq_use; /* map of all in-use irq's */ EXTERN reg_t mon_ss, mon_sp; /* boot monitor stack */ EXTERN int mon_return; /* true if we can return to monitor */ EXTERN int do_serial_debug; +EXTERN int who_e, who_p; /* message source endpoint and proc */ /* VM */ EXTERN phys_bytes vm_base; diff --git a/kernel/main.c b/kernel/main.c index 8295a7859..275fff8f0 100755 --- a/kernel/main.c +++ b/kernel/main.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "proc.h" /* Prototype declarations for PRIVATE functions. */ @@ -51,6 +52,7 @@ PUBLIC void main() for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) { rp->p_rts_flags = SLOT_FREE; /* initialize free slot */ rp->p_nr = i; /* proc number from ptr */ + rp->p_endpoint = _ENDPOINT(0, rp->p_nr); /* generation no. 0 */ (pproc_addr + NR_TASKS)[i] = rp; /* proc ptr from number */ } for (sp = BEG_PRIV_ADDR, i = 0; sp < END_PRIV_ADDR; ++sp, ++i) { @@ -73,6 +75,7 @@ PUBLIC void main() for (i=0; i < NR_BOOT_PROCS; ++i) { ip = &image[i]; /* process' attributes */ rp = proc_addr(ip->proc_nr); /* get process pointer */ + ip->endpoint = rp->p_endpoint; /* ipc endpoint */ rp->p_max_priority = ip->priority; /* max scheduling priority */ rp->p_priority = ip->priority; /* current priority */ rp->p_quantum_size = ip->quantum; /* quantum size in ticks */ diff --git a/kernel/proc.c b/kernel/proc.c index 1fa720864..98faab837 100755 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -38,6 +38,8 @@ #include #include +#include +#include "debug.h" #include "kernel.h" #include "proc.h" @@ -45,7 +47,7 @@ * other parts of the kernel through lock_...(). The lock temporarily disables * interrupts to prevent race conditions. */ -FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dst, +FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dst_e, message *m_ptr, unsigned flags)); FORWARD _PROTOTYPE( int mini_receive, (struct proc *caller_ptr, int src, message *m_ptr, unsigned flags)); @@ -58,7 +60,7 @@ FORWARD _PROTOTYPE( void sched, (struct proc *rp, int *queue, int *front)); FORWARD _PROTOTYPE( void pick_proc, (void)); #define BuildMess(m_ptr, src, dst_ptr) \ - (m_ptr)->m_source = (src); \ + (m_ptr)->m_source = proc_addr(src)->p_endpoint; \ (m_ptr)->m_type = NOTIFY_FROM(src); \ (m_ptr)->NOTIFY_TIMESTAMP = get_uptime(); \ switch (src) { \ @@ -74,8 +76,9 @@ FORWARD _PROTOTYPE( void pick_proc, (void)); #if (CHIP == INTEL) #define CopyMess(s,sp,sm,dp,dm) \ - cp_mess(s, (sp)->p_memmap[D].mem_phys, \ - (vir_bytes)sm, (dp)->p_memmap[D].mem_phys, (vir_bytes)dm) + cp_mess(proc_addr(s)->p_endpoint, \ + (sp)->p_memmap[D].mem_phys, \ + (vir_bytes)sm, (dp)->p_memmap[D].mem_phys, (vir_bytes)dm) #endif /* (CHIP == INTEL) */ #if (CHIP == M68000) @@ -87,9 +90,9 @@ FORWARD _PROTOTYPE( void pick_proc, (void)); /*===========================================================================* * sys_call * *===========================================================================*/ -PUBLIC int sys_call(call_nr, src_dst, m_ptr) +PUBLIC int sys_call(call_nr, src_dst_e, m_ptr) int call_nr; /* system call number and flags */ -int src_dst; /* src to receive from or dst to send to */ +int src_dst_e; /* src to receive from or dst to send to */ message *m_ptr; /* pointer to message in the caller's space */ { /* System calls are done by trapping to the kernel with an INT instruction. @@ -102,7 +105,19 @@ message *m_ptr; /* pointer to message in the caller's space */ int mask_entry; /* bit to check in send mask */ int group_size; /* used for deadlock check */ int result; /* the system call's result */ + int src_dst; vir_clicks vlo, vhi; /* virtual clicks containing message to send */ + + /* Require a valid source and/ or destination process, unless echoing. */ + if (src_dst_e != ANY && function != ECHO) { + if(!isokendpt(src_dst_e, &src_dst)) { +#if DEBUG_ENABLE_IPC_WARNINGS + kprintf("sys_call: trap %d by %d with bad endpoint %d\n", + function, proc_nr(caller_ptr), src_dst_e); +#endif + return EDEADSRCDST; + } + } else src_dst = src_dst_e; /* Check if the process has privileges for the requested call. Calls to the * kernel may only be SENDREC, because tasks always reply and may not block @@ -110,31 +125,13 @@ message *m_ptr; /* pointer to message in the caller's space */ */ if (! (priv(caller_ptr)->s_trap_mask & (1 << function)) || (iskerneln(src_dst) && function != SENDREC - && function != RECEIVE)) { + && function != RECEIVE)) { #if DEBUG_ENABLE_IPC_WARNINGS kprintf("sys_call: trap %d not allowed, caller %d, src_dst %d\n", function, proc_nr(caller_ptr), src_dst); #endif return(ETRAPDENIED); /* trap denied by mask or kernel */ } - - /* Require a valid source and/ or destination process, unless echoing. */ - if (src_dst != ANY && function != ECHO) { - if (! isokprocn(src_dst)) { -#if DEBUG_ENABLE_IPC_WARNINGS - kprintf("sys_call: invalid src_dst, src_dst %d, caller %d\n", - src_dst, proc_nr(caller_ptr)); -#endif - return(EBADSRCDST); /* invalid process number */ - } - if (isemptyn(src_dst)) { -#if DEBUG_ENABLE_IPC_WARNINGS - kprintf("sys_call: dead src_dst; trap %d, from %d, to %d\n", - function, proc_nr(caller_ptr), src_dst); -#endif - return(EDEADSRCDST); - } - } /* If the call involves a message buffer, i.e., for SEND, RECEIVE, SENDREC, * or ECHO, check the message pointer. This check allows a message to be @@ -193,14 +190,14 @@ message *m_ptr; /* pointer to message in the caller's space */ priv(caller_ptr)->s_flags |= SENDREC_BUSY; /* fall through */ case SEND: - result = mini_send(caller_ptr, src_dst, m_ptr, flags); + result = mini_send(caller_ptr, src_dst_e, m_ptr, flags); if (function == SEND || result != OK) { break; /* done, or SEND failed */ } /* fall through for SENDREC */ case RECEIVE: if (function == RECEIVE) priv(caller_ptr)->s_flags &= ~SENDREC_BUSY; - result = mini_receive(caller_ptr, src_dst, m_ptr, flags); + result = mini_receive(caller_ptr, src_dst_e, m_ptr, flags); break; case NOTIFY: result = mini_notify(caller_ptr, src_dst); @@ -223,7 +220,7 @@ message *m_ptr; /* pointer to message in the caller's space */ PRIVATE int deadlock(function, cp, src_dst) int function; /* trap number */ register struct proc *cp; /* pointer to caller */ -register int src_dst; /* src or dst process */ +int src_dst; /* src or dst process */ { /* Check for deadlock. This can happen if 'caller_ptr' and 'src_dst' have * a cyclic dependency of blocking send and receive calls. The only cyclic @@ -236,6 +233,7 @@ register int src_dst; /* src or dst process */ int trap_flags; while (src_dst != ANY) { /* check while process nr */ + int src_dst_e; xp = proc_addr(src_dst); /* follow chain of processes */ group_size ++; /* extra process in group */ @@ -243,9 +241,10 @@ register int src_dst; /* src or dst process */ * has not, the cycle cannot be closed and we are done. */ if (xp->p_rts_flags & RECEIVING) { /* xp has dependency */ - src_dst = xp->p_getfrom; /* get xp's source */ + if(xp->p_getfrom_e == ANY) src_dst = ANY; + else okendpt(xp->p_getfrom_e, &src_dst); } else if (xp->p_rts_flags & SENDING) { /* xp has dependency */ - src_dst = xp->p_sendto; /* get xp's destination */ + okendpt(xp->p_sendto_e, &src_dst); } else { return(0); /* not a deadlock */ } @@ -270,9 +269,9 @@ register int src_dst; /* src or dst process */ /*===========================================================================* * mini_send * *===========================================================================*/ -PRIVATE int mini_send(caller_ptr, dst, m_ptr, flags) +PRIVATE int mini_send(caller_ptr, dst_e, m_ptr, flags) register struct proc *caller_ptr; /* who is trying to send a message? */ -int dst; /* to whom is message being sent? */ +int dst_e; /* to whom is message being sent? */ message *m_ptr; /* pointer to message buffer */ unsigned flags; /* system call flags */ { @@ -280,14 +279,19 @@ unsigned flags; /* system call flags */ * for this message, copy the message to it and unblock 'dst'. If 'dst' is * not waiting at all, or is waiting for another source, queue 'caller_ptr'. */ - register struct proc *dst_ptr = proc_addr(dst); + register struct proc *dst_ptr; register struct proc **xpp; + int dst_p; + + dst_p = _ENDPOINT_P(dst_e); + dst_ptr = proc_addr(dst_p); /* Check if 'dst' is blocked waiting for this message. The destination's * SENDING flag may be set when its SENDREC call blocked while sending. */ if ( (dst_ptr->p_rts_flags & (RECEIVING | SENDING)) == RECEIVING && - (dst_ptr->p_getfrom == ANY || dst_ptr->p_getfrom == caller_ptr->p_nr)) { + (dst_ptr->p_getfrom_e == ANY + || dst_ptr->p_getfrom_e == caller_ptr->p_endpoint)) { /* Destination is indeed waiting for this message. */ CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, dst_ptr, dst_ptr->p_messbuf); @@ -297,7 +301,7 @@ unsigned flags; /* system call flags */ caller_ptr->p_messbuf = m_ptr; if (caller_ptr->p_rts_flags == 0) dequeue(caller_ptr); caller_ptr->p_rts_flags |= SENDING; - caller_ptr->p_sendto = dst; + caller_ptr->p_sendto_e = dst_e; /* Process is now blocked. Put in on the destination's queue. */ xpp = &dst_ptr->p_caller_q; /* find end of list */ @@ -313,9 +317,9 @@ unsigned flags; /* system call flags */ /*===========================================================================* * mini_receive * *===========================================================================*/ -PRIVATE int mini_receive(caller_ptr, src, m_ptr, flags) +PRIVATE int mini_receive(caller_ptr, src_e, m_ptr, flags) register struct proc *caller_ptr; /* process trying to get message */ -int src; /* which message source is wanted */ +int src_e; /* which message source is wanted */ message *m_ptr; /* pointer to message buffer */ unsigned flags; /* system call flags */ { @@ -329,7 +333,10 @@ unsigned flags; /* system call flags */ int bit_nr; sys_map_t *map; bitchunk_t *chunk; - int i, src_id, src_proc_nr; + int i, src_id, src_proc_nr, src_p; + + if(src_e == ANY) src_p = ANY; + else okendpt(src_e, &src_p); /* Check to see if a message from desired source is already available. * The caller's SENDING flag may be set if SENDREC couldn't send. If it is @@ -354,7 +361,7 @@ unsigned flags; /* system call flags */ kprintf("mini_receive: sending notify from NONE\n"); } #endif - if (src!=ANY && src!=src_proc_nr) continue; /* source not ok */ + if (src_e!=ANY && src_p != src_proc_nr) continue;/* source not ok */ *chunk &= ~(1 << i); /* no longer pending */ /* Found a suitable source, deliver the notification message. */ @@ -367,7 +374,7 @@ unsigned flags; /* system call flags */ /* Check caller queue. Use pointer pointers to keep code simple. */ xpp = &caller_ptr->p_caller_q; while (*xpp != NIL_PROC) { - if (src == ANY || src == proc_nr(*xpp)) { + if (src_e == ANY || src_p == proc_nr(*xpp)) { /* Found acceptable message. Copy it and update status. */ CopyMess((*xpp)->p_nr, *xpp, (*xpp)->p_messbuf, caller_ptr, m_ptr); if (((*xpp)->p_rts_flags &= ~SENDING) == 0) enqueue(*xpp); @@ -382,7 +389,7 @@ unsigned flags; /* system call flags */ * Block the process trying to receive, unless the flags tell otherwise. */ if ( ! (flags & NON_BLOCKING)) { - caller_ptr->p_getfrom = src; + caller_ptr->p_getfrom_e = src_e; caller_ptr->p_messbuf = m_ptr; if (caller_ptr->p_rts_flags == 0) dequeue(caller_ptr); caller_ptr->p_rts_flags |= RECEIVING; @@ -408,7 +415,8 @@ int dst; /* which process to notify */ */ if ((dst_ptr->p_rts_flags & (RECEIVING|SENDING)) == RECEIVING && ! (priv(dst_ptr)->s_flags & SENDREC_BUSY) && - (dst_ptr->p_getfrom == ANY || dst_ptr->p_getfrom == caller_ptr->p_nr)) { + (dst_ptr->p_getfrom_e == ANY + || dst_ptr->p_getfrom_e == caller_ptr->p_endpoint)) { /* Destination is indeed waiting for a message. Assemble a notification * message and deliver it. Copy from pseudo-source HARDWARE, since the @@ -434,9 +442,9 @@ int dst; /* which process to notify */ /*===========================================================================* * lock_notify * *===========================================================================*/ -PUBLIC int lock_notify(src, dst) -int src; /* sender of the notification */ -int dst; /* who is to be notified */ +PUBLIC int lock_notify(src_e, dst_e) +int src_e; /* (endpoint) sender of the notification */ +int dst_e; /* (endpoint) who is to be notified */ { /* Safe gateway to mini_notify() for tasks and interrupt handlers. The sender * is explicitely given to prevent confusion where the call comes from. MINIX @@ -444,7 +452,10 @@ int dst; /* who is to be notified */ * the first kernel entry (hardware interrupt, trap, or exception). Locking * is done by temporarily disabling interrupts. */ - int result; + int result, src, dst; + + if(!isokendpt(src_e, &src) || !isokendpt(dst_e, &dst)) + return EDEADSRCDST; /* Exception or interrupt occurred, thus already locked. */ if (k_reenter >= 0) { @@ -638,14 +649,14 @@ PRIVATE void pick_proc() /*===========================================================================* * lock_send * *===========================================================================*/ -PUBLIC int lock_send(dst, m_ptr) -int dst; /* to whom is message being sent? */ +PUBLIC int lock_send(dst_e, m_ptr) +int dst_e; /* to whom is message being sent? */ message *m_ptr; /* pointer to message buffer */ { /* Safe gateway to mini_send() for tasks. */ int result; lock(2, "send"); - result = mini_send(proc_ptr, dst, m_ptr, NON_BLOCKING); + result = mini_send(proc_ptr, dst_e, m_ptr, NON_BLOCKING); unlock(2); return(result); } @@ -681,3 +692,52 @@ struct proc *rp; /* this process is no longer runnable */ } } +/*===========================================================================* + * isokendpt_f * + *===========================================================================*/ +#if DEBUG_ENABLE_IPC_WARNINGS +PUBLIC int isokendpt_f(file, line, e, p, fatalflag) +char *file; +int line; +#else +PUBLIC int isokendpt_f(e, p, fatalflag) +#endif +int e, *p, fatalflag; +{ + int ok = 0; + /* Convert an endpoint number into a process number. + * Return nonzero if the process is alive with the corresponding + * generation number, zero otherwise. + * + * This function is called with file and line number by the + * isokendpt_d macro if DEBUG_ENABLE_IPC_WARNINGS is defined, + * otherwise without. This allows us to print the where the + * conversion was attempted, making the errors verbose without + * adding code for that at every call. + * + * If fatalflag is nonzero, we must panic if the conversion doesn't + * succeed. + */ + *p = _ENDPOINT_P(e); + if(!isokprocn(*p)) { +#if DEBUG_ENABLE_IPC_WARNINGS + kprintf("kernel:%s:%d: bad endpoint %d: proc %d out of range\n", + file, line, e, *p); +#endif + } else if(isemptyn(*p)) { +#if DEBUG_ENABLE_IPC_WARNINGS + kprintf("kernel:%s:%d: bad endpoint %d: proc %d empty\n", file, line, e, *p); +#endif + } else if(proc_addr(*p)->p_endpoint != e) { +#if DEBUG_ENABLE_IPC_WARNINGS + kprintf("kernel:%s:%d: bad endpoint %d: proc %d has ept %d (generation %d vs. %d)\n", file, line, + e, *p, proc_addr(*p)->p_endpoint, + _ENDPOINT_G(e), _ENDPOINT_G(proc_addr(*p)->p_endpoint)); +#endif + } else ok = 1; + if(!ok && fatalflag) { + panic("invalid endpoint ", e); + } + return ok; +} + diff --git a/kernel/proc.h b/kernel/proc.h index 7f6a32780..2c57e039d 100755 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -46,13 +46,15 @@ struct proc { struct proc *p_caller_q; /* head of list of procs wishing to send */ struct proc *p_q_link; /* link to next proc wishing to send */ message *p_messbuf; /* pointer to passed message buffer */ - proc_nr_t p_getfrom; /* from whom does process want to receive? */ - proc_nr_t p_sendto; /* to whom does process want to send? */ + int p_getfrom_e; /* from whom does process want to receive? */ + int p_sendto_e; /* to whom does process want to send? */ sigset_t p_pending; /* bit map for pending kernel signals */ char p_name[P_NAME_LEN]; /* name of the process, including \0 */ + int p_endpoint; /* endpoint number, generation-aware */ + #if DEBUG_SCHED_CHECK int p_ready, p_found; #endif diff --git a/kernel/proto.h b/kernel/proto.h index 1d69a9519..3bb1f413b 100755 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -29,6 +29,13 @@ _PROTOTYPE( int lock_notify, (int src, int dst) ); _PROTOTYPE( int lock_send, (int dst, message *m_ptr) ); _PROTOTYPE( void lock_enqueue, (struct proc *rp) ); _PROTOTYPE( void lock_dequeue, (struct proc *rp) ); +#if DEBUG_ENABLE_IPC_WARNINGS +_PROTOTYPE( int isokendpt_f, (char *file, int line, int e, int *p, int f)); +#define isokendpt_d(e, p, f) isokendpt_f(__FILE__, __LINE__, (e), (p), (f)) +#else +_PROTOTYPE( int isokendpt_f, (int e, int *p, int f) ); +#define isokendpt_d(e, p, f) isokendpt_f((e), (p), (f)) +#endif /* start.c */ _PROTOTYPE( void cstart, (U16_t cs, U16_t ds, U16_t mds, diff --git a/kernel/system.c b/kernel/system.c index 410c40393..399b28309 100755 --- a/kernel/system.c +++ b/kernel/system.c @@ -28,12 +28,14 @@ * Sep 30, 2004 source code documentation updated (Jorrit N. Herder) */ +#include "debug.h" #include "kernel.h" #include "system.h" #include #include #include #include +#include #if (CHIP == INTEL) #include #include "protect.h" @@ -72,7 +74,9 @@ PUBLIC void sys_task() /* Get work. Block and wait until a request message arrives. */ receive(ANY, &m); call_nr = (unsigned) m.m_type - KERNEL_CALL; - caller_ptr = proc_addr(m.m_source); + who_e = m.m_source; + okendpt(who_e, &who_p); + caller_ptr = proc_addr(who_p); /* See if the caller made a valid request and try to handle it. */ if (! (priv(caller_ptr)->s_call_mask & (1<s_sig_pending, sig_nr); - lock_notify(SYSTEM, proc_nr); + lock_notify(SYSTEM, rp->p_endpoint); } /*===========================================================================* @@ -420,22 +432,30 @@ vir_bytes bytes; /* # of bytes to copy */ vir_addr[_SRC_] = src_addr; vir_addr[_DST_] = dst_addr; for (i=_SRC_; i<=_DST_; i++) { + int proc_nr, type; + struct proc *p; + + type = vir_addr[i]->segment & SEGMENT_TYPE; + if(type != PHYS_SEG && isokendpt(vir_addr[i]->proc_nr_e, &proc_nr)) + p = proc_addr(proc_nr); + else + p = NULL; /* Get physical address. */ - switch((vir_addr[i]->segment & SEGMENT_TYPE)) { + switch(type) { case LOCAL_SEG: + if(!p) return EDEADSRCDST; seg_index = vir_addr[i]->segment & SEGMENT_INDEX; - phys_addr[i] = umap_local( proc_addr(vir_addr[i]->proc_nr), - seg_index, vir_addr[i]->offset, bytes ); + phys_addr[i] = umap_local(p, seg_index, vir_addr[i]->offset, bytes); break; case REMOTE_SEG: + if(!p) return EDEADSRCDST; seg_index = vir_addr[i]->segment & SEGMENT_INDEX; - phys_addr[i] = umap_remote( proc_addr(vir_addr[i]->proc_nr), - seg_index, vir_addr[i]->offset, bytes ); + phys_addr[i] = umap_remote(p, seg_index, vir_addr[i]->offset, bytes); break; case BIOS_SEG: - phys_addr[i] = umap_bios( proc_addr(vir_addr[i]->proc_nr), - vir_addr[i]->offset, bytes ); + if(!p) return EDEADSRCDST; + phys_addr[i] = umap_bios(p, vir_addr[i]->offset, bytes ); break; case PHYS_SEG: phys_addr[i] = vir_addr[i]->offset; diff --git a/kernel/system.h b/kernel/system.h index 4c884b6d8..78ca0ed7d 100644 --- a/kernel/system.h +++ b/kernel/system.h @@ -31,6 +31,7 @@ #define SYSTEM_H /* Common includes for the system library. */ +#include "debug.h" #include "kernel.h" #include "proto.h" #include "proc.h" diff --git a/kernel/system/do_abort.c b/kernel/system/do_abort.c index 9130ac059..d0b32b516 100644 --- a/kernel/system/do_abort.c +++ b/kernel/system/do_abort.c @@ -30,8 +30,7 @@ message *m_ptr; /* pointer to request message */ /* See if the monitor is to run the specified instructions. */ if (how == RBT_MONITOR) { - proc_nr = m_ptr->ABRT_MON_PROC; - if (! isokprocn(proc_nr)) return(EINVAL); + if(!isokendpt(m_ptr->ABRT_MON_ENDPT, &proc_nr)) return(EDEADSRCDST); length = m_ptr->ABRT_MON_LEN + 1; if (length > kinfo.params_size) return(E2BIG); src_phys = numap_local(proc_nr,(vir_bytes)m_ptr->ABRT_MON_ADDR,length); diff --git a/kernel/system/do_copy.c b/kernel/system/do_copy.c index 9c1431835..177cc610e 100644 --- a/kernel/system/do_copy.c +++ b/kernel/system/do_copy.c @@ -31,10 +31,10 @@ register message *m_ptr; /* pointer to request message */ int i; /* Dismember the command message. */ - vir_addr[_SRC_].proc_nr = m_ptr->CP_SRC_PROC_NR; + 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 = m_ptr->CP_DST_PROC_NR; + 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; @@ -43,10 +43,12 @@ register message *m_ptr; /* pointer to request message */ * 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 == SELF) vir_addr[i].proc_nr = m_ptr->m_source; - if (! isokprocn(vir_addr[i].proc_nr) && vir_addr[i].segment != PHYS_SEG) + if (vir_addr[i].proc_nr_e == SELF) + vir_addr[i].proc_nr_e = m_ptr->m_source; + if (vir_addr[i].segment != PHYS_SEG && + ! isokendpt(vir_addr[i].proc_nr_e, &p)) return(EINVAL); /* Check if physical addressing is used without SYS_PHYSCOPY. */ diff --git a/kernel/system/do_devio.c b/kernel/system/do_devio.c index a5e48dc93..a1da1a274 100644 --- a/kernel/system/do_devio.c +++ b/kernel/system/do_devio.c @@ -10,6 +10,7 @@ #include "../system.h" #include +#include #if USE_DEVIO @@ -25,7 +26,7 @@ register message *m_ptr; /* pointer to request message */ struct io_range *iorp; int i, size, nr_io_range; - rp= proc_addr(m_ptr->m_source); + rp= proc_addr(who_p); privp= priv(rp); if (!privp) { diff --git a/kernel/system/do_endksig.c b/kernel/system/do_endksig.c index 7e8038649..63d4b20a6 100644 --- a/kernel/system/do_endksig.c +++ b/kernel/system/do_endksig.c @@ -2,7 +2,7 @@ * m_type: SYS_ENDKSIG * * The parameters for this kernel call are: - * m2_i1: SIG_PROC # process for which PM is done + * m2_i1: SIG_ENDPT # process for which PM is done */ #include "../system.h" @@ -22,11 +22,15 @@ message *m_ptr; /* pointer to request message */ * signal it got with SYS_GETKSIG. */ register struct proc *rp; + int proc; /* Get process pointer and verify that it had signals pending. If the * process is already dead its flags will be reset. */ - rp = proc_addr(m_ptr->SIG_PROC); + if(!isokendpt(m_ptr->SIG_ENDPT, &proc)) + return EINVAL; + + rp = proc_addr(proc); if (! (rp->p_rts_flags & SIG_PENDING)) return(EINVAL); /* PM has finished one kernel signal. Perhaps process is ready now? */ diff --git a/kernel/system/do_exec.c b/kernel/system/do_exec.c index 932d42eca..554819856 100644 --- a/kernel/system/do_exec.c +++ b/kernel/system/do_exec.c @@ -2,7 +2,7 @@ * m_type: SYS_EXEC * * The parameters for this kernel call are: - * m1_i1: PR_PROC_NR (process that did exec call) + * m1_i1: PR_ENDPT (process that did exec call) * m1_p1: PR_STACK_PTR (new stack pointer) * m1_p2: PR_NAME_PTR (pointer to program name) * m1_p3: PR_IP_PTR (new instruction pointer) @@ -10,6 +10,7 @@ #include "../system.h" #include #include +#include #if USE_EXEC @@ -24,8 +25,12 @@ register message *m_ptr; /* pointer to request message */ reg_t sp; /* new sp */ phys_bytes phys_name; char *np; + int proc; - rp = proc_addr(m_ptr->PR_PROC_NR); + if(!isokendpt(m_ptr->PR_ENDPT, &proc)) + return EINVAL; + + rp = proc_addr(proc); sp = (reg_t) m_ptr->PR_STACK_PTR; rp->p_reg.sp = sp; /* set the stack pointer */ #if (CHIP == M68000) @@ -42,9 +47,8 @@ register message *m_ptr; /* pointer to request message */ rp->p_reg.pc = (reg_t) m_ptr->PR_IP_PTR; /* set pc */ rp->p_rts_flags &= ~RECEIVING; /* PM does not reply to EXEC call */ if (rp->p_rts_flags == 0) lock_enqueue(rp); - /* Save command name for debugging, ps(1) output, etc. */ - phys_name = numap_local(m_ptr->m_source, (vir_bytes) m_ptr->PR_NAME_PTR, + phys_name = numap_local(who_p, (vir_bytes) m_ptr->PR_NAME_PTR, (vir_bytes) P_NAME_LEN - 1); if (phys_name != 0) { phys_copy(phys_name, vir2phys(rp->p_name), (phys_bytes) P_NAME_LEN - 1); diff --git a/kernel/system/do_exit.c b/kernel/system/do_exit.c index 783d12c70..ecda123d9 100644 --- a/kernel/system/do_exit.c +++ b/kernel/system/do_exit.c @@ -2,11 +2,13 @@ * m_type: SYS_EXIT * * The parameters for this kernel call are: - * m1_i1: PR_PROC_NR (slot number of exiting process) + * m1_i1: PR_ENDPT (slot number of exiting process) */ #include "../system.h" +#include + #if USE_EXIT FORWARD _PROTOTYPE( void clear_proc, (register struct proc *rc)); @@ -23,20 +25,20 @@ message *m_ptr; /* pointer to request message */ * possibly removes the process from the message queues, and resets certain * process table fields to the default values. */ - int exit_proc_nr; + int exit_e; /* Determine what process exited. User processes are handled here. */ - if (PM_PROC_NR == m_ptr->m_source) { - exit_proc_nr = m_ptr->PR_PROC_NR; /* get exiting process */ - if (exit_proc_nr != SELF) { /* PM tries to exit self */ - if (! isokprocn(exit_proc_nr)) return(EINVAL); - clear_proc(proc_addr(exit_proc_nr)); /* exit a user process */ + if (PM_PROC_NR == who_p) { + if (m_ptr->PR_ENDPT != SELF) { /* PM tries to exit self */ + if(!isokendpt(m_ptr->PR_ENDPT, &exit_e)) /* get exiting process */ + return EINVAL; + clear_proc(proc_addr(exit_e)); /* exit a user process */ return(OK); /* report back to PM */ } } /* The PM or some other system process requested to be exited. */ - clear_proc(proc_addr(m_ptr->m_source)); + clear_proc(proc_addr(who_p)); return(EDONTREPLY); } @@ -61,6 +63,15 @@ register struct proc *rc; /* slot of process to clean up */ /* Make sure that the exiting process is no longer scheduled. */ if (rc->p_rts_flags == 0) lock_dequeue(rc); + /* Check the table with IRQ hooks to see if hooks should be released. */ + for (i=0; i < NR_IRQ_HOOKS; i++) { + int proc; + if (rc->p_endpoint == irq_hooks[i].proc_nr_e) { + rm_irq_handler(&irq_hooks[i]); /* remove interrupt handler */ + irq_hooks[i].proc_nr_e = NONE; /* mark hook as free */ + } + } + /* Release the process table slot. If this is a system process, also * release its privilege structure. Further cleanup is not needed at * this point. All important fields are reinitialized when the @@ -75,13 +86,15 @@ register struct proc *rc; /* slot of process to clean up */ * a normal exit), then it must be removed from the message queues. */ if (saved_rts_flags & SENDING) { - xpp = &proc[rc->p_sendto].p_caller_q; /* destination's queue */ + int target_proc; + okendpt(rc->p_sendto_e, &target_proc); + xpp = &proc[target_proc].p_caller_q; /* destination's queue */ while (*xpp != NIL_PROC) { /* check entire queue */ if (*xpp == rc) { /* process is on the queue */ *xpp = (*xpp)->p_q_link; /* replace by next process */ #if DEBUG_ENABLE_IPC_WARNINGS kprintf("Proc %d removed from queue at %d\n", - proc_nr(rc), rc->p_sendto); + proc_nr(rc), rc->p_sendto_e); #endif break; /* can only be queued once */ } @@ -101,7 +114,7 @@ register struct proc *rc; /* slot of process to clean up */ unset_sys_bit(priv(rp)->s_notify_pending, priv(rc)->s_id); /* Check if process is receiving from exiting process. */ - if ((rp->p_rts_flags & RECEIVING) && rp->p_getfrom == proc_nr(rc)) { + if ((rp->p_rts_flags & RECEIVING) && rp->p_getfrom_e == rc->p_endpoint) { rp->p_reg.retreg = ESRCDIED; /* report source died */ rp->p_rts_flags &= ~RECEIVING; /* no longer receiving */ #if DEBUG_ENABLE_IPC_WARNINGS @@ -109,7 +122,7 @@ register struct proc *rc; /* slot of process to clean up */ #endif if (rp->p_rts_flags == 0) lock_enqueue(rp);/* let process run again */ } - if ((rp->p_rts_flags & SENDING) && rp->p_sendto == proc_nr(rc)) { + if ((rp->p_rts_flags & SENDING) && rp->p_sendto_e == rc->p_endpoint) { rp->p_reg.retreg = EDSTDIED; /* report destination died */ rp->p_rts_flags &= ~SENDING; /* no longer sending */ #if DEBUG_ENABLE_IPC_WARNINGS @@ -119,14 +132,6 @@ register struct proc *rc; /* slot of process to clean up */ } } - /* Check the table with IRQ hooks to see if hooks should be released. */ - for (i=0; i < NR_IRQ_HOOKS; i++) { - if (irq_hooks[i].proc_nr == proc_nr(rc)) { - rm_irq_handler(&irq_hooks[i]); /* remove interrupt handler */ - irq_hooks[i].proc_nr = NONE; /* mark hook as free */ - } - } - /* Clean up virtual memory */ if (rc->p_misc_flags & MF_VM) vm_map_default(rc); diff --git a/kernel/system/do_fork.c b/kernel/system/do_fork.c index ec56cd919..aba2715ac 100644 --- a/kernel/system/do_fork.c +++ b/kernel/system/do_fork.c @@ -2,8 +2,8 @@ * m_type: SYS_FORK * * The parameters for this kernel call are: - * m1_i1: PR_PROC_NR (child's process table slot) - * m1_i2: PR_PPROC_NR (parent, process that forked) + * m1_i1: PR_SLOT (child's process table slot) + * m1_i2: PR_ENDPT (parent, process that forked) */ #include "../system.h" @@ -12,6 +12,8 @@ #include "../protect.h" #endif +#include + #if USE_FORK /*===========================================================================* @@ -20,19 +22,23 @@ PUBLIC int do_fork(m_ptr) register message *m_ptr; /* pointer to request message */ { -/* Handle sys_fork(). PR_PPROC_NR has forked. The child is PR_PROC_NR. */ +/* Handle sys_fork(). PR_ENDPT has forked. The child is PR_SLOT. */ #if (CHIP == INTEL) reg_t old_ldt_sel; #endif register struct proc *rpc; /* child process pointer */ struct proc *rpp; /* parent process pointer */ - int i; + int i, gen; + int p_proc; - rpp = proc_addr(m_ptr->PR_PPROC_NR); - rpc = proc_addr(m_ptr->PR_PROC_NR); + if(!isokendpt(m_ptr->PR_ENDPT, &p_proc)) + return EINVAL; + rpp = proc_addr(p_proc); + rpc = proc_addr(m_ptr->PR_SLOT); if (isemptyp(rpp) || ! isemptyp(rpc)) return(EINVAL); /* Copy parent 'proc' struct to child. And reinitialize some fields. */ + gen = _ENDPOINT_G(rpc->p_endpoint); #if (CHIP == INTEL) old_ldt_sel = rpc->p_ldt_sel; /* backup local descriptors */ *rpc = *rpp; /* copy 'proc' struct */ @@ -40,7 +46,10 @@ register message *m_ptr; /* pointer to request message */ #else *rpc = *rpp; /* copy 'proc' struct */ #endif - rpc->p_nr = m_ptr->PR_PROC_NR; /* this was obliterated by copy */ + if(++gen >= _ENDPOINT_MAX_GENERATION) /* increase generation */ + gen = 1; /* generation number wraparound */ + rpc->p_nr = m_ptr->PR_SLOT; /* this was obliterated by copy */ + rpc->p_endpoint = _ENDPOINT(gen, rpc->p_nr); /* new endpoint of slot */ /* Only one in group should have SIGNALED, child doesn't inherit tracing. */ rpc->p_rts_flags |= NO_MAP; /* inhibit process from running */ @@ -66,6 +75,10 @@ register message *m_ptr; /* pointer to request message */ rpc->p_priv = priv_addr(USER_PRIV_ID); rpc->p_rts_flags |= NO_PRIV; } + + /* Calculate endpoint identifier, so caller knows what it is. */ + m_ptr->PR_ENDPT = rpc->p_endpoint; + return(OK); } diff --git a/kernel/system/do_getinfo.c b/kernel/system/do_getinfo.c index a5791abbf..0017fb4de 100644 --- a/kernel/system/do_getinfo.c +++ b/kernel/system/do_getinfo.c @@ -6,7 +6,7 @@ * m1_p1: I_VAL_PTR (where to put it) * m1_i1: I_VAL_LEN (maximum length expected, optional) * m1_p2: I_VAL_PTR2 (second, optional pointer) - * m1_i2: I_VAL_LEN2 (second length or process nr) + * m1_i2: I_VAL_LEN2_E (second length or process nr) */ #include "../system.h" @@ -28,7 +28,7 @@ register message *m_ptr; /* pointer to request message */ size_t length; phys_bytes src_phys; phys_bytes dst_phys; - int proc_nr, nr; + int proc_nr, nr_e, nr; /* Set source address and length based on request type. */ switch (m_ptr->I_REQUEST) { @@ -64,7 +64,8 @@ register message *m_ptr; /* pointer to request message */ */ length = sizeof(struct proc *) * NR_SCHED_QUEUES; src_phys = vir2phys(rdy_head); - dst_phys = numap_local(m_ptr->m_source, (vir_bytes) m_ptr->I_VAL_PTR2, + okendpt(m_ptr->m_source, &proc_nr); + dst_phys = numap_local(proc_nr, (vir_bytes) m_ptr->I_VAL_PTR2, length); if (src_phys == 0 || dst_phys == 0) return(EFAULT); phys_copy(src_phys, dst_phys, length); @@ -81,8 +82,9 @@ register message *m_ptr; /* pointer to request message */ break; } case GET_PROC: { - nr = (m_ptr->I_VAL_LEN2 == SELF) ? m_ptr->m_source : m_ptr->I_VAL_LEN2; - if (! isokprocn(nr)) return(EINVAL); /* validate request */ + nr_e = (m_ptr->I_VAL_LEN2_E == SELF) ? + m_ptr->m_source : m_ptr->I_VAL_LEN2_E; + if(!isokendpt(nr_e, &nr)) return EINVAL; /* validate request */ length = sizeof(struct proc); src_phys = vir2phys(proc_addr(nr)); break; @@ -123,8 +125,9 @@ register message *m_ptr; /* pointer to request message */ length = sizeof(bios_buf_len); src_phys = vir2phys(&bios_buf_len); - if (length != m_ptr->I_VAL_LEN2) return (EINVAL); - proc_nr = m_ptr->m_source; /* only caller can request copy */ + if (length != m_ptr->I_VAL_LEN2_E) return (EINVAL); + if(!isokendpt(m_ptr->m_source, &proc_nr)) + panic("bogus source", m_ptr->m_source); dst_phys = numap_local(proc_nr, (vir_bytes) m_ptr->I_VAL_PTR2, length); if (src_phys == 0 || dst_phys == 0) return(EFAULT); phys_copy(src_phys, dst_phys, length); @@ -145,7 +148,8 @@ 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); - proc_nr = m_ptr->m_source; /* only caller can request copy */ + if(!isokendpt(m_ptr->m_source, &proc_nr)) + panic("bogus source", m_ptr->m_source); dst_phys = numap_local(proc_nr, (vir_bytes) m_ptr->I_VAL_PTR, length); if (src_phys == 0 || dst_phys == 0) return(EFAULT); phys_copy(src_phys, dst_phys, length); diff --git a/kernel/system/do_getksig.c b/kernel/system/do_getksig.c index 1910d7df0..95d85a507 100644 --- a/kernel/system/do_getksig.c +++ b/kernel/system/do_getksig.c @@ -2,13 +2,14 @@ * m_type: SYS_GETKSIG * * The parameters for this kernel call are: - * m2_i1: SIG_PROC # process with pending signals + * m2_i1: SIG_ENDPT # process with pending signals * m2_l1: SIG_MAP # bit map with pending signals */ #include "../system.h" #include #include +#include #if USE_GETKSIG @@ -29,7 +30,8 @@ message *m_ptr; /* pointer to request message */ /* Find the next process with pending signals. */ for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) { if (rp->p_rts_flags & SIGNALED) { - m_ptr->SIG_PROC = rp->p_nr; /* store signaled process */ + /* store signaled process' endpoint */ + m_ptr->SIG_ENDPT = rp->p_endpoint; m_ptr->SIG_MAP = rp->p_pending; /* pending signals map */ sigemptyset(&rp->p_pending); /* ball is in PM's court */ rp->p_rts_flags &= ~SIGNALED; /* blocked by SIG_PENDING */ @@ -38,7 +40,7 @@ message *m_ptr; /* pointer to request message */ } /* No process with pending signals was found. */ - m_ptr->SIG_PROC = NONE; + m_ptr->SIG_ENDPT = NONE; return(OK); } #endif /* USE_GETKSIG */ diff --git a/kernel/system/do_int86.c b/kernel/system/do_int86.c index 36df4ecde..f669b7896 100644 --- a/kernel/system/do_int86.c +++ b/kernel/system/do_int86.c @@ -7,6 +7,7 @@ #include "../system.h" #include +#include #include struct reg86u reg86; @@ -17,13 +18,11 @@ struct reg86u reg86; PUBLIC int do_int86(m_ptr) register message *m_ptr; /* pointer to request message */ { - int caller; vir_bytes caller_vir; phys_bytes caller_phys, kernel_phys; - caller = (int) m_ptr->m_source; caller_vir = (vir_bytes) m_ptr->INT86_REG86; - caller_phys = umap_local(proc_addr(caller), D, caller_vir, sizeof(reg86)); + caller_phys = umap_local(proc_addr(who_p), D, caller_vir, sizeof(reg86)); if (0 == caller_phys) return(EFAULT); kernel_phys = vir2phys(®86); phys_copy(caller_phys, kernel_phys, (phys_bytes) sizeof(reg86)); diff --git a/kernel/system/do_iopenable.c b/kernel/system/do_iopenable.c index 71b33caf5..f37a46199 100644 --- a/kernel/system/do_iopenable.c +++ b/kernel/system/do_iopenable.c @@ -2,14 +2,14 @@ * m_type: SYS_IOPENABLE * * The parameters for this system call are: - * m2_i2: PROC_NR (process to give I/O Protection Level bits) + * m2_i2: IO_ENDPT (process to give I/O Protection Level bits) * * Author: * Jorrit N. Herder */ -#include "../kernel.h" #include "../system.h" +#include "../kernel.h" /*===========================================================================* * do_iopenable * @@ -20,9 +20,10 @@ register message *m_ptr; /* pointer to request message */ int proc_nr; #if 1 /* ENABLE_USERPRIV && ENABLE_USERIOPL */ - proc_nr= m_ptr->PROC_NR; - if (proc_nr == SELF) - proc_nr = m_ptr->m_source; + if (m_ptr->IO_ENDPT == SELF) { + proc_nr = who_p; + } else if(!isokendpt(m_ptr->IO_ENDPT, &proc_nr)) + return(EINVAL); enable_iop(proc_addr(proc_nr)); return(OK); #else diff --git a/kernel/system/do_irqctl.c b/kernel/system/do_irqctl.c index ec08aa3d5..260cc4cde 100644 --- a/kernel/system/do_irqctl.c +++ b/kernel/system/do_irqctl.c @@ -11,6 +11,8 @@ #include "../system.h" +#include + #if USE_IRQCTL FORWARD _PROTOTYPE(int generic_handler, (irq_hook_t *hook)); @@ -41,9 +43,9 @@ register message *m_ptr; /* pointer to request message */ /* Enable or disable IRQs. This is straightforward. */ case IRQ_ENABLE: case IRQ_DISABLE: - if (irq_hook_id >= NR_IRQ_HOOKS || - irq_hooks[irq_hook_id].proc_nr == NONE) return(EINVAL); - if (irq_hooks[irq_hook_id].proc_nr != m_ptr->m_source) return(EPERM); + if (irq_hook_id >= NR_IRQ_HOOKS || irq_hook_id < 0 || + irq_hooks[irq_hook_id].proc_nr_e == NONE) return(EINVAL); + if (irq_hooks[irq_hook_id].proc_nr_e != m_ptr->m_source) return(EPERM); if (m_ptr->IRQ_REQUEST == IRQ_ENABLE) enable_irq(&irq_hooks[irq_hook_id]); else @@ -58,7 +60,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(m_ptr->m_source); + rp= proc_addr(who_p); privp= priv(rp); if (!privp) { @@ -84,7 +86,7 @@ register message *m_ptr; /* pointer to request message */ /* Find a free IRQ hook for this mapping. */ hook_ptr = NULL; for (irq_hook_id=0; irq_hook_id CHAR_BIT * sizeof(irq_id_t) - 1) return(EINVAL); /* Install the handler. */ - hook_ptr->proc_nr = m_ptr->m_source; /* process to notify */ + hook_ptr->proc_nr_e = m_ptr->m_source; /* process to notify */ hook_ptr->notify_id = notify_id; /* identifier to pass */ hook_ptr->policy = m_ptr->IRQ_POLICY; /* policy for interrupts */ put_irq_handler(hook_ptr, irq_vec, generic_handler); @@ -108,10 +110,10 @@ register message *m_ptr; /* pointer to request message */ break; case IRQ_RMPOLICY: - if (irq_hook_id >= NR_IRQ_HOOKS || - irq_hooks[irq_hook_id].proc_nr == NONE) { + if (irq_hook_id < 0 || irq_hook_id >= NR_IRQ_HOOKS || + irq_hooks[irq_hook_id].proc_nr_e == NONE) { return(EINVAL); - } else if (m_ptr->m_source != irq_hooks[irq_hook_id].proc_nr) { + } else if (m_ptr->m_source != irq_hooks[irq_hook_id].proc_nr_e) { return(EPERM); } /* Remove the handler and return. */ @@ -134,20 +136,30 @@ irq_hook_t *hook; * interrupts are transformed into messages to a driver. The IRQ line will be * reenabled if the policy says so. */ + int proc; /* As a side-effect, the interrupt handler gathers random information by * timestamping the interrupt events. This is used for /dev/random. */ get_randomness(hook->irq); + /* Check if the handler is still alive. If not, forget about the + * interrupt. This should never happen, as processes that die + * automatically get their interrupt hooks unhooked. + */ + if(!isokendpt(hook->proc_nr_e, &proc)) { + hook->proc_nr_e = NONE; + return 0; + } + /* Add a bit for this interrupt to the process' pending interrupts. When * sending the notification message, this bit map will be magically set * as an argument. */ - priv(proc_addr(hook->proc_nr))->s_int_pending |= (1 << hook->notify_id); + priv(proc_addr(proc))->s_int_pending |= (1 << hook->notify_id); /* Build notification message and return. */ - lock_notify(HARDWARE, hook->proc_nr); + lock_notify(HARDWARE, hook->proc_nr_e); return(hook->policy & IRQ_REENABLE); } diff --git a/kernel/system/do_kill.c b/kernel/system/do_kill.c index 9b87a1fe7..1c6f99c32 100644 --- a/kernel/system/do_kill.c +++ b/kernel/system/do_kill.c @@ -2,7 +2,7 @@ * m_type: SYS_KILL * * The parameters for this kernel call are: - * m2_i1: SIG_PROC # process to signal/ pending + * m2_i1: SIG_ENDPT # process to signal/ pending * m2_i2: SIG_NUMBER # signal number to send to process */ @@ -26,10 +26,11 @@ message *m_ptr; /* pointer to request message */ * are usually blocked on a RECEIVE), they can request the PM to transform * signals into messages. This is done by the PM with a call to sys_kill(). */ - proc_nr_t proc_nr = m_ptr->SIG_PROC; + proc_nr_t proc_nr; int sig_nr = m_ptr->SIG_NUMBER; - if (! isokprocn(proc_nr) || sig_nr > _NSIG) return(EINVAL); + if (!isokendpt(m_ptr->SIG_ENDPT, &proc_nr)) return(EINVAL); + if (sig_nr > _NSIG) return(EINVAL); if (iskerneln(proc_nr)) return(EPERM); if (m_ptr->m_source == PM_PROC_NR) { diff --git a/kernel/system/do_newmap.c b/kernel/system/do_newmap.c index f99f65dec..1da7b80ca 100644 --- a/kernel/system/do_newmap.c +++ b/kernel/system/do_newmap.c @@ -2,10 +2,11 @@ * m_type: SYS_NEWMAP * * The parameters for this kernel call are: - * m1_i1: PR_PROC_NR (install new map for this process) + * m1_i1: PR_ENDPT (install new map for this process) * m1_p1: PR_MEM_PTR (pointer to the new memory map) */ #include "../system.h" +#include #if USE_NEWMAP @@ -17,20 +18,18 @@ message *m_ptr; /* pointer to request message */ { /* Handle sys_newmap(). Fetch the memory map from PM. */ register struct proc *rp; /* process whose map is to be loaded */ - int caller; /* whose space has the new map (usually PM) */ struct mem_map *map_ptr; /* virtual address of map inside caller (PM) */ phys_bytes src_phys; /* physical address of map at the PM */ int old_flags; /* value of flags before modification */ + int proc; - /* Extract message parameters and copy new memory map from PM. */ - caller = m_ptr->m_source; map_ptr = (struct mem_map *) m_ptr->PR_MEM_PTR; - if (! isokprocn(m_ptr->PR_PROC_NR)) return(EINVAL); - if (iskerneln(m_ptr->PR_PROC_NR)) return(EPERM); - rp = proc_addr(m_ptr->PR_PROC_NR); + if (! isokendpt(m_ptr->PR_ENDPT, &proc)) return(EINVAL); + if (iskerneln(proc)) return(EPERM); + rp = proc_addr(proc); /* Copy the map from PM. */ - src_phys = umap_local(proc_addr(caller), D, (vir_bytes) map_ptr, + src_phys = umap_local(proc_addr(who_p), D, (vir_bytes) map_ptr, sizeof(rp->p_memmap)); if (src_phys == 0) return(EFAULT); phys_copy(src_phys,vir2phys(rp->p_memmap),(phys_bytes)sizeof(rp->p_memmap)); diff --git a/kernel/system/do_nice.c b/kernel/system/do_nice.c index cb0ad6692..855e4e067 100644 --- a/kernel/system/do_nice.c +++ b/kernel/system/do_nice.c @@ -2,7 +2,7 @@ * m_type: SYS_NICE * * The parameters for this kernel call are: - * m1_i1: PR_PROC_NR process number to change priority + * m1_i1: PR_ENDPT process number to change priority * m1_i2: PR_PRIORITY the new priority */ @@ -21,8 +21,7 @@ PUBLIC int do_nice(message *m_ptr) register struct proc *rp; /* Extract the message parameters and do sanity checking. */ - proc_nr = m_ptr->PR_PROC_NR; - if (! isokprocn(proc_nr)) return(EINVAL); + if(!isokendpt(m_ptr->PR_ENDPT, &proc_nr)) return EINVAL; if (iskerneln(proc_nr)) return(EPERM); pri = m_ptr->PR_PRIORITY; if (pri < PRIO_MIN || pri > PRIO_MAX) return(EINVAL); diff --git a/kernel/system/do_privctl.c b/kernel/system/do_privctl.c index 49df7322b..e01ff2333 100644 --- a/kernel/system/do_privctl.c +++ b/kernel/system/do_privctl.c @@ -2,7 +2,7 @@ * m_type: SYS_PRIVCTL * * The parameters for this kernel call are: - * m1_i1: PR_PROC_NR (process number of caller) + * m1_i1: PR_ENDPT (process number of caller) */ #include "../system.h" @@ -38,10 +38,9 @@ message *m_ptr; /* pointer to request message */ * running by the NO_PRIV flag. This flag is set when a privileged process * forks. */ - caller_ptr = proc_addr(m_ptr->m_source); + caller_ptr = proc_addr(who_p); if (! (priv(caller_ptr)->s_flags & SYS_PROC)) return(EPERM); - proc_nr = m_ptr->PR_PROC_NR; - if (! isokprocn(proc_nr)) return(EINVAL); + if(!isokendpt(m_ptr->PR_ENDPT, &proc_nr)) return(EINVAL); rp = proc_addr(proc_nr); switch(m_ptr->CTL_REQUEST) @@ -114,9 +113,6 @@ message *m_ptr; /* pointer to request message */ priv(rp)->s_io_tab[i].ior_limit= io_range.ior_limit; priv(rp)->s_nr_io_range++; - kprintf("do_privctl: added I/O range [0x%x..0x%x]\n", - io_range.ior_base, io_range.ior_limit); - return OK; case SYS_PRIV_ADD_MEM: @@ -145,9 +141,6 @@ message *m_ptr; /* pointer to request message */ priv(rp)->s_nr_mem_range++; #endif - kprintf("do_privctl: should add memory range [0x%x..0x%x]\n", - mem_range.mr_base, mem_range.mr_limit); - return OK; case SYS_PRIV_ADD_IRQ: @@ -166,8 +159,6 @@ message *m_ptr; /* pointer to request message */ priv(rp)->s_irq_tab[i]= m_ptr->CTL_MM_PRIV; priv(rp)->s_nr_irq++; - kprintf("do_privctl: adding IRQ %d\n", m_ptr->CTL_MM_PRIV); - return OK; default: diff --git a/kernel/system/do_sdevio.c b/kernel/system/do_sdevio.c index 831a18b87..82a707f8e 100644 --- a/kernel/system/do_sdevio.c +++ b/kernel/system/do_sdevio.c @@ -12,6 +12,7 @@ #include "../system.h" #include +#include #if USE_SDEVIO @@ -21,17 +22,20 @@ PUBLIC int do_sdevio(m_ptr) register message *m_ptr; /* pointer to request message */ { - int proc_nr = m_ptr->DIO_VEC_PROC; + int proc_nr, proc_nr_e = m_ptr->DIO_VEC_ENDPT; int count = m_ptr->DIO_VEC_SIZE; long port = m_ptr->DIO_PORT; phys_bytes phys_buf; - /* Check if process number is OK. A process number is allowed here, because - * driver may directly provide a pointer to a buffer at the user-process + /* Check if process endpoint is OK. + * A driver may directly provide a pointer to a buffer at the user-process * that initiated the device I/O. Kernel processes, of course, are denied. */ - if (proc_nr == SELF) proc_nr = m_ptr->m_source; - if (! isokprocn(proc_nr)) return(EINVAL); + if (proc_nr_e == SELF) + proc_nr = who_p; + else + if(!isokendpt(proc_nr_e, &proc_nr)) + return(EINVAL); if (iskerneln(proc_nr)) return(EPERM); /* Get and check physical address. */ diff --git a/kernel/system/do_segctl.c b/kernel/system/do_segctl.c index b6bdd00f4..e1b5b5988 100644 --- a/kernel/system/do_segctl.c +++ b/kernel/system/do_segctl.c @@ -31,7 +31,7 @@ register message *m_ptr; /* pointer to request message */ int result; /* First check if there is a slot available for this segment. */ - rp = proc_addr(m_ptr->m_source); + rp = proc_addr(who_p); index = -1; for (i=0; i < NR_REMOTE_SEGS; i++) { if (! rp->p_priv->s_farmem[i].in_use) { diff --git a/kernel/system/do_setalarm.c b/kernel/system/do_setalarm.c index a20d32383..98f756028 100644 --- a/kernel/system/do_setalarm.c +++ b/kernel/system/do_setalarm.c @@ -9,6 +9,8 @@ #include "../system.h" +#include + #if USE_SETALARM FORWARD _PROTOTYPE( void cause_alarm, (timer_t *tp) ); @@ -21,7 +23,6 @@ message *m_ptr; /* pointer to request message */ { /* A process requests a synchronous alarm, or wants to cancel its alarm. */ register struct proc *rp; /* pointer to requesting process */ - int proc_nr; /* which process wants the alarm */ long exp_time; /* expiration time for this alarm */ int use_abs_time; /* use absolute or relative time */ timer_t *tp; /* the process' timer structure */ @@ -30,13 +31,12 @@ 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 */ - proc_nr = m_ptr->m_source; /* process to interrupt later */ - rp = proc_addr(proc_nr); + rp = proc_addr(who_p); if (! (priv(rp)->s_flags & SYS_PROC)) return(EPERM); /* Get the timer structure and set the parameters for this alarm. */ tp = &(priv(rp)->s_alarm_timer); - tmr_arg(tp)->ta_int = proc_nr; + tmr_arg(tp)->ta_int = m_ptr->m_source; tp->tmr_func = cause_alarm; /* Return the ticks left on the previous alarm. */ @@ -67,8 +67,8 @@ timer_t *tp; * alarm. The process number is stored in timer argument 'ta_int'. Notify that * process with a notification message from CLOCK. */ - int proc_nr = tmr_arg(tp)->ta_int; /* get process number */ - lock_notify(CLOCK, proc_nr); /* notify process */ + int proc_nr_e = tmr_arg(tp)->ta_int; /* get process number */ + lock_notify(CLOCK, proc_nr_e); /* notify process */ } #endif /* USE_SETALARM */ diff --git a/kernel/system/do_sigreturn.c b/kernel/system/do_sigreturn.c index a821d3b3c..f1b026d9e 100644 --- a/kernel/system/do_sigreturn.c +++ b/kernel/system/do_sigreturn.c @@ -2,7 +2,7 @@ * m_type: SYS_SIGRETURN * * The parameters for this kernel call are: - * m2_i1: SIG_PROC # process returning from handler + * m2_i1: SIG_ENDPT # process returning from handler * m2_p1: SIG_CTXT_PTR # pointer to sigcontext structure * */ @@ -26,10 +26,11 @@ message *m_ptr; /* pointer to request message */ struct sigcontext sc; register struct proc *rp; phys_bytes src_phys; + int proc; - if (! isokprocn(m_ptr->SIG_PROC)) return(EINVAL); - if (iskerneln(m_ptr->SIG_PROC)) return(EPERM); - rp = proc_addr(m_ptr->SIG_PROC); + if (! isokendpt(m_ptr->SIG_ENDPT, &proc)) return(EINVAL); + if (iskerneln(proc)) return(EPERM); + rp = proc_addr(proc); /* Copy in the sigcontext structure. */ src_phys = umap_local(rp, D, (vir_bytes) m_ptr->SIG_CTXT_PTR, diff --git a/kernel/system/do_sigsend.c b/kernel/system/do_sigsend.c index 712152712..9e082b6f7 100644 --- a/kernel/system/do_sigsend.c +++ b/kernel/system/do_sigsend.c @@ -2,7 +2,7 @@ * m_type: SYS_SIGSEND * * The parameters for this kernel call are: - * m2_i1: SIG_PROC # process to call signal handler + * m2_i1: SIG_ENDPT # process to call signal handler * m2_p1: SIG_CTXT_PTR # pointer to sigcontext structure * m2_i3: SIG_FLAGS # flags for S_SIGRETURN call * @@ -28,10 +28,11 @@ message *m_ptr; /* pointer to request message */ phys_bytes src_phys, dst_phys; struct sigcontext sc, *scp; struct sigframe fr, *frp; + int proc; - if (! isokprocn(m_ptr->SIG_PROC)) return(EINVAL); - if (iskerneln(m_ptr->SIG_PROC)) return(EPERM); - rp = proc_addr(m_ptr->SIG_PROC); + if (!isokendpt(m_ptr->SIG_ENDPT, &proc)) return(EINVAL); + if (iskerneln(proc)) return(EPERM); + rp = proc_addr(proc); /* Get the sigmsg structure into our address space. */ src_phys = umap_local(proc_addr(PM_PROC_NR), D, (vir_bytes) diff --git a/kernel/system/do_times.c b/kernel/system/do_times.c index 53b9bec24..12846fd15 100644 --- a/kernel/system/do_times.c +++ b/kernel/system/do_times.c @@ -2,7 +2,7 @@ * m_type: SYS_TIMES * * The parameters for this kernel call are: - * m4_l1: T_PROC_NR (get info for this process) + * m4_l1: T_ENDPT (get info for this process) * m4_l1: T_USER_TIME (return values ...) * m4_l2: T_SYSTEM_TIME * m4_l5: T_BOOT_TICKS @@ -10,6 +10,8 @@ #include "../system.h" +#include + #if USE_TIMES /*===========================================================================* @@ -20,15 +22,15 @@ register message *m_ptr; /* pointer to request message */ { /* Handle sys_times(). Retrieve the accounting information. */ register struct proc *rp; - int proc_nr; + int proc_nr, e_proc_nr; /* Insert the times needed by the SYS_TIMES kernel call in the message. * The clock's interrupt handler may run to update the user or system time * while in this code, but that cannot do any harm. */ - proc_nr = (m_ptr->T_PROC_NR == SELF) ? m_ptr->m_source : m_ptr->T_PROC_NR; - if (isokprocn(proc_nr)) { - rp = proc_addr(m_ptr->T_PROC_NR); + e_proc_nr = (m_ptr->T_ENDPT == SELF) ? m_ptr->m_source : m_ptr->T_ENDPT; + if(e_proc_nr != NONE && isokendpt(e_proc_nr, &proc_nr)) { + rp = proc_addr(proc_nr); m_ptr->T_USER_TIME = rp->p_user_time; m_ptr->T_SYSTEM_TIME = rp->p_sys_time; } diff --git a/kernel/system/do_trace.c b/kernel/system/do_trace.c index 0e62842eb..0ff740470 100644 --- a/kernel/system/do_trace.c +++ b/kernel/system/do_trace.c @@ -2,7 +2,7 @@ * m_type: SYS_TRACE * * The parameters for this kernel call are: - * m2_i1: CTL_PROC_NR process that is traced + * m2_i1: CTL_ENDPT process that is traced * m2_i2: CTL_REQUEST trace request * m2_l1: CTL_ADDRESS address at traced process' space * m2_l2: CTL_DATA data to be written or returned here @@ -44,10 +44,10 @@ register message *m_ptr; vir_bytes tr_addr = (vir_bytes) m_ptr->CTL_ADDRESS; long tr_data = m_ptr->CTL_DATA; int tr_request = m_ptr->CTL_REQUEST; - int tr_proc_nr = m_ptr->CTL_PROC_NR; + int tr_proc_nr_e = m_ptr->CTL_ENDPT, tr_proc_nr; int i; - if (! isokprocn(tr_proc_nr)) return(EINVAL); + if(!isokendpt(tr_proc_nr_e, &tr_proc_nr)) return(EINVAL); if (iskerneln(tr_proc_nr)) return(EPERM); rp = proc_addr(tr_proc_nr); diff --git a/kernel/system/do_umap.c b/kernel/system/do_umap.c index 04c981e72..613549169 100644 --- a/kernel/system/do_umap.c +++ b/kernel/system/do_umap.c @@ -24,12 +24,16 @@ register message *m_ptr; /* pointer to request message */ int seg_index = m_ptr->CP_SRC_SPACE & SEGMENT_INDEX; vir_bytes offset = m_ptr->CP_SRC_ADDR; int count = m_ptr->CP_NR_BYTES; - int proc_nr = (int) m_ptr->CP_SRC_PROC_NR; + int endpt = (int) m_ptr->CP_SRC_ENDPT; + int proc_nr; phys_bytes phys_addr; /* Verify process number. */ - if (proc_nr == SELF) proc_nr = m_ptr->m_source; - if (! isokprocn(proc_nr)) return(EINVAL); + if (endpt == SELF) + proc_nr = who_p; + else + if (! isokendpt(endpt, &proc_nr)) + return(EINVAL); /* See which mapping should be made. */ switch(seg_type) { diff --git a/kernel/system/do_vcopy.c b/kernel/system/do_vcopy.c index 8db9e9526..f6db0fd67 100644 --- a/kernel/system/do_vcopy.c +++ b/kernel/system/do_vcopy.c @@ -26,7 +26,6 @@ register message *m_ptr; /* pointer to request message */ * different kernel calls so that permissions can be checked. */ int nr_req; - int caller_pid; vir_bytes caller_vir; phys_bytes caller_phys; phys_bytes kernel_phys; @@ -40,9 +39,8 @@ register message *m_ptr; /* pointer to request message */ bytes = nr_req * sizeof(struct vir_cp_req); /* Calculate physical addresses and copy (port,value)-pairs from user. */ - caller_pid = (int) m_ptr->m_source; caller_vir = (vir_bytes) m_ptr->VCP_VEC_ADDR; - caller_phys = umap_local(proc_addr(caller_pid), D, caller_vir, bytes); + caller_phys = umap_local(proc_addr(who_p), D, caller_vir, bytes); if (0 == caller_phys) return(EFAULT); kernel_phys = vir2phys(vir_cp_req); phys_copy(caller_phys, kernel_phys, (phys_bytes) bytes); diff --git a/kernel/system/do_vdevio.c b/kernel/system/do_vdevio.c index 54a5d65f2..94792bf7b 100644 --- a/kernel/system/do_vdevio.c +++ b/kernel/system/do_vdevio.c @@ -10,6 +10,7 @@ #include "../system.h" #include +#include #if USE_VDEVIO @@ -34,7 +35,6 @@ register message *m_ptr; /* pointer to request message */ int vec_size; /* size of vector */ int io_in; /* true if input */ size_t bytes; /* # bytes to be copied */ - int caller_proc; /* process number of caller */ vir_bytes caller_vir; /* virtual address at caller */ phys_bytes caller_phys; /* physical address at caller */ int i; @@ -53,9 +53,8 @@ register message *m_ptr; /* pointer to request message */ if (bytes > sizeof(vdevio_buf)) return(E2BIG); /* Calculate physical addresses and copy (port,value)-pairs from user. */ - caller_proc = m_ptr->m_source; caller_vir = (vir_bytes) m_ptr->DIO_VEC_ADDR; - caller_phys = umap_local(proc_addr(caller_proc), D, caller_vir, bytes); + caller_phys = umap_local(proc_addr(who_p), D, caller_vir, bytes); if (0 == caller_phys) return(EFAULT); phys_copy(caller_phys, vir2phys(vdevio_buf), (phys_bytes) bytes); diff --git a/kernel/system/do_vm.c b/kernel/system/do_vm.c index 4d2690bd8..0be63a9ee 100644 --- a/kernel/system/do_vm.c +++ b/kernel/system/do_vm.c @@ -2,11 +2,11 @@ * m_type: SYS_VM_MAP * * The parameters for this system call are: - * m4_l1: Process that requests map - * m4_l2: Map (TRUE) or unmap (FALSE) - * m4_l3: Base address - * m4_l4: Size - * m4_l5: Memory address + * m4_l1: Process that requests map (VM_MAP_ENDPT) + * m4_l2: Map (TRUE) or unmap (FALSE) (VM_MAP_MAPUNMAP) + * m4_l3: Base address (VM_MAP_BASE) + * m4_l4: Size (VM_MAP_SIZE) + * m4_l5: Memory address (VM_MAP_ADDR) */ #include "../system.h" @@ -42,13 +42,17 @@ message *m_ptr; /* pointer to request message */ vm_init(); } - proc_nr= m_ptr->m4_l1; - if (proc_nr == SELF) - proc_nr= m_ptr->m_source; - do_map= m_ptr->m4_l2; - base= m_ptr->m4_l3; - size= m_ptr->m4_l4; - offset= m_ptr->m4_l5; + if (m_ptr->VM_MAP_ENDPT == SELF) { + proc_nr = who_p; + } else { + if(!isokendpt(m_ptr->VM_MAP_ENDPT, &proc_nr)) + return EINVAL; + } + + do_map= m_ptr->VM_MAP_MAPUNMAP; + base= m_ptr->VM_MAP_BASE; + size= m_ptr->VM_MAP_SIZE; + offset= m_ptr->VM_MAP_ADDR; pp= proc_addr(proc_nr); p_phys= umap_local(pp, D, base, size); diff --git a/kernel/type.h b/kernel/type.h index 1d4a3b648..0d51f5527 100755 --- a/kernel/type.h +++ b/kernel/type.h @@ -21,6 +21,7 @@ struct boot_image { bitchunk_t ipc_to; /* send mask protection */ long call_mask; /* system call protection */ char proc_name[P_NAME_LEN]; /* name in process table */ + int endpoint; /* endpoint number when started */ }; struct memory { @@ -94,7 +95,7 @@ typedef struct irq_hook { int (*handler)(struct irq_hook *); /* interrupt handler */ int irq; /* IRQ vector number */ int id; /* id of this hook */ - int proc_nr; /* NONE if not in use */ + int proc_nr_e; /* (endpoint) NONE if not in use */ irq_id_t notify_id; /* id to return on interrupt */ irq_policy_t policy; /* bit mask for policy */ } irq_hook_t;