'proc number' is process slot, 'endpoint' are generation-aware process
instance numbers, encoded and decoded using macros in <minix/endpoint.h>.
proc number -> endpoint migration
. proc_nr in the interrupt hook is now an endpoint, proc_nr_e.
. m_source for messages and notifies is now an endpoint, instead of
proc number.
. isokendpt() converts an endpoint to a process number, returns
success (but fails if the process number is out of range, the
process slot is not a living process, or the given endpoint
number does not match the endpoint number in the process slot,
indicating an old process).
. okendpt() is the same as isokendpt(), but panic()s if the conversion
fails. This is mainly used for decoding message.m_source endpoints,
and other endpoint numbers in kernel data structures, which should
always be correct.
. if DEBUG_ENABLE_IPC_WARNINGS is enabled, isokendpt() and okendpt()
get passed the __FILE__ and __LINE__ of the calling lines, and
print messages about what is wrong with the endpoint number
(out of range proc, empty proc, or inconsistent endpoint number),
with the caller, making finding where the conversion failed easy
without having to include code for every call to print where things
went wrong. Sometimes this is harmless (wrong arg to a kernel call),
sometimes it's a fatal internal inconsistency (bogus m_source).
. some process table fields have been appended an _e to indicate it's
become and endpoint.
. process endpoint is stored in p_endpoint, without generation number.
it turns out the kernel never needs the generation number, except
when fork()ing, so it's decoded then.
. kernel calls all take endpoints as arguments, not proc numbers.
the one exception is sys_fork(), which needs to know in which slot
to put the child.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "../system.h"
|
||||
#include <minix/devio.h>
|
||||
#include <minix/endpoint.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
||||
@@ -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? */
|
||||
|
||||
@@ -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 <string.h>
|
||||
#include <signal.h>
|
||||
#include <minix/endpoint.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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 <minix/endpoint.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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 <minix/endpoint.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 <signal.h>
|
||||
#include <sys/sigcontext.h>
|
||||
#include <minix/endpoint.h>
|
||||
|
||||
#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 */
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "../system.h"
|
||||
#include <minix/type.h>
|
||||
#include <minix/endpoint.h>
|
||||
#include <ibm/int86.h>
|
||||
|
||||
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));
|
||||
|
||||
@@ -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 <jnherder@cs.vu.nl>
|
||||
*/
|
||||
|
||||
#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
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#include "../system.h"
|
||||
|
||||
#include <minix/endpoint.h>
|
||||
|
||||
#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<NR_IRQ_HOOKS; irq_hook_id++) {
|
||||
if (irq_hooks[irq_hook_id].proc_nr == NONE) {
|
||||
if (irq_hooks[irq_hook_id].proc_nr_e == NONE) {
|
||||
hook_ptr = &irq_hooks[irq_hook_id]; /* free hook */
|
||||
break;
|
||||
}
|
||||
@@ -98,7 +100,7 @@ register message *m_ptr; /* pointer to request message */
|
||||
if (notify_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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 <minix/endpoint.h>
|
||||
|
||||
#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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "../system.h"
|
||||
#include <minix/devio.h>
|
||||
#include <minix/endpoint.h>
|
||||
|
||||
#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. */
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include "../system.h"
|
||||
|
||||
#include <minix/endpoint.h>
|
||||
|
||||
#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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 <minix/endpoint.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "../system.h"
|
||||
#include <minix/devio.h>
|
||||
#include <minix/endpoint.h>
|
||||
|
||||
#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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user