Kernel changes:

- reinstalled priority changing, now in sched() and unready()
- reinstalled check on message buffer in sys_call()
- reinstalled check in send masks in sys_call()
- changed do_fork() to get new privilege structure for SYS_PROCs
- removed some processes from boot image---will be dynamically started later
This commit is contained in:
Jorrit Herder 2005-07-26 12:48:34 +00:00
parent 153fdabb26
commit 8866b4d0ef
15 changed files with 160 additions and 124 deletions

View file

@ -51,7 +51,7 @@
#define INIT_PSW 0x0200 /* initial psw */ #define INIT_PSW 0x0200 /* initial psw */
#define INIT_TASK_PSW 0x1200 /* initial psw for tasks (with IOPL 1) */ #define INIT_TASK_PSW 0x1200 /* initial psw for tasks (with IOPL 1) */
#define TRACEBIT 0x0100 /* OR this with psw in proc[] for tracing */ #define TRACEBIT 0x0100 /* OR this with psw in proc[] for tracing */
#define SETPSW(rp, new) /* permits only certain bits to be set */ \ #define SETPSW(rp, new) /* permits only certain bits to be set */ \
((rp)->p_reg.psw = (rp)->p_reg.psw & ~0xCD5 | (new) & 0xCD5) ((rp)->p_reg.psw = (rp)->p_reg.psw & ~0xCD5 | (new) & 0xCD5)
#define IF_MASK 0x00000200 #define IF_MASK 0x00000200
#define IOPL_MASK 0x003000 #define IOPL_MASK 0x003000

View file

@ -48,7 +48,7 @@ unsigned vec_nr;
ep = &ex_data[vec_nr]; ep = &ex_data[vec_nr];
if (vec_nr == 2) { /* spurious NMI on some machines */ if (vec_nr == 2) { /* spurious NMI on some machines */
kprintf("got spurious NMI\n",NO_NUM); kprintf("got spurious NMI\n");
return; return;
} }
@ -67,8 +67,8 @@ unsigned vec_nr;
else else
kprintf("\n%s\n", ep->msg); kprintf("\n%s\n", ep->msg);
kprintf("k_reenter = %d ", k_reenter); kprintf("k_reenter = %d ", k_reenter);
kprintf("process %d (%s)", proc_nr(saved_proc), saved_proc->p_name); kprintf("process %d (%s), ", proc_nr(saved_proc), saved_proc->p_name);
kprintf("pc = %d:0x%x", (unsigned) saved_proc->p_reg.cs, kprintf("pc = %u:0x%x", (unsigned) saved_proc->p_reg.cs,
(unsigned) saved_proc->p_reg.pc); (unsigned) saved_proc->p_reg.pc);
panic("exception in a kernel task", NO_NUM); panic("exception in a kernel task", NO_NUM);

View file

@ -1,6 +1,8 @@
#ifndef IPC_H #ifndef IPC_H
#define IPC_H #define IPC_H
#include <minix/com.h>
/* Masks and flags for system calls. */ /* Masks and flags for system calls. */
#define SYSCALL_FUNC 0x0F /* mask for system call function */ #define SYSCALL_FUNC 0x0F /* mask for system call function */
#define SYSCALL_FLAGS 0xF0 /* mask for system call flags */ #define SYSCALL_FLAGS 0xF0 /* mask for system call flags */
@ -8,18 +10,51 @@
#define FRESH_ANSWER 0x20 /* ignore pending notifications as answer */ #define FRESH_ANSWER 0x20 /* ignore pending notifications as answer */
/* (default behaviour for SENDREC calls) */ /* (default behaviour for SENDREC calls) */
/* System calls (numbers passed when trapping to the kernel). */ /* System call numbers that are passed when trapping to the kernel. The
#define ECHO 0 /* function code for echoing messages */ * numbers are carefully defined so that it can easily be seen (based on
#define SEND 1 /* function code for sending messages */ * the bits that are on) which checks should be done in sys_call().
#define RECEIVE 2 /* function code for receiving messages */ */
#define SENDREC 3 /* function code for SEND + RECEIVE */ #define ECHO 0 /* 0 0 0 0 1 (01) : echo a message */
#define NOTIFY 4 /* function code for notifications */ #define SEND 1 /* 0 0 0 1 1 (03) : blocking send */
#define ALERT 5 /* function code for alerting */ #define RECEIVE 2 /* 0 0 1 0 1 (05) : blocking receive */
#define SENDREC 3 /* 0 0 1 1 1 (07) : SEND + RECEIVE */
#define NOTIFY 4 /* temp */
#define ALERT 5 /* 0 1 0 1 0 (10) : nonblocking notify */
/* Call masks indicating which system calls a process can make. */ /* The following definitions determine whether a calls message buffer and/
#define EMPTY_CALL_MASK (0) * or destination processes should be validated.
*/
#define CHECK_PTR 0x01 /* 0 0 0 0 1 : validate message buffer */
#define CHECK_DST 0x02 /* 0 0 0 1 0 : validate message destination */
#define CHECK_SRC 0x04 /* 0 0 1 0 0 : validate message source */
/* Call masks indicating which system calls (traps) a process can make.
* The values here are used for the processes in the boot image.
*/
#define EMPTY_MASK (0)
#define FILLED_MASK (~0)
#define USER_CALL_MASK (1 << SENDREC) #define USER_CALL_MASK (1 << SENDREC)
#define SYSTEM_CALL_MASK (~0)
/* Send masks determine to whom processes can send messages or notifications.
* The values here are used for the processes in the boot image. We rely on
* the initialization code in main() to match the s_nr_to_id() mapping for the
* processes in the boot image, so that the send mask that is defined here
* can be directly copied onto map[0] of the actual send mask. Privilege
* structure 0 is shared by user processes.
*
* Note that process numbers in the boot image should not be higher than
* "BITCHUNK_BITS - NR_TASKS", because a bitchunk_t field is used to store
* the send masks in the table that describes that processes in the image.
*/
#define s_nr_to_id(n) (NR_TASKS + (n) + 1)
#define s(n) (1 << s_nr_to_id(n))
#define USER_SEND_MASK (s(PM_PROC_NR) | s(FS_PROC_NR))
#define DRIVER_SEND_MASK (s(PM_PROC_NR) | s(FS_PROC_NR) | s(SYSTEM) | \
s(CLOCK) | s(PRINTF_PROC) | s(TTY))
#define SERVER_SEND_MASK (~0)
#define SYSTEM_SEND_MASK (~1)
/* Sanity check to make sure the send masks can be set. */
extern int dummy[(BITCHUNK_BITS-NR_TASKS > INIT_PROC_NR) ? 1 : -1];
#endif /* IPC_H */ #endif /* IPC_H */

View file

@ -49,7 +49,7 @@ PUBLIC void main()
/* Clear the process table. Anounce each slot as empty and set up mappings /* Clear the process table. Anounce each slot as empty and set up mappings
* for proc_addr() and proc_nr() macros. Do the same for the table with * for proc_addr() and proc_nr() macros. Do the same for the table with
* system properties structures. * privilege structures for the system processes.
*/ */
for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) { 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_rts_flags = SLOT_FREE; /* initialize free slot */
@ -76,17 +76,17 @@ PUBLIC void main()
for (i=0; i < NR_BOOT_PROCS; ++i) { for (i=0; i < NR_BOOT_PROCS; ++i) {
ip = &image[i]; /* process' attributes */ ip = &image[i]; /* process' attributes */
rp = proc_addr(ip->proc_nr); /* get process pointer */ rp = proc_addr(ip->proc_nr); /* get process pointer */
rp->p_name[P_NAME_LEN-1] = '\0'; /* just for safety */
rp->p_max_priority = ip->priority; /* max scheduling priority */ rp->p_max_priority = ip->priority; /* max scheduling priority */
rp->p_priority = ip->priority; /* current priority */ rp->p_priority = ip->priority; /* current priority */
rp->p_quantum_size = ip->quantum; /* quantum size in ticks */ rp->p_quantum_size = ip->quantum; /* quantum size in ticks */
rp->p_sched_ticks = ip->quantum; /* current credit */ rp->p_sched_ticks = ip->quantum; /* current credit */
rp->p_full_quantums = QUANTUMS(ip->priority); /* nr quantums left */ rp->p_full_quantums = QUANTUMS(ip->priority); /* nr quantums left */
strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */ strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */
(void) set_priv(rp, (ip->flags & SYS_PROC)); /* assign structure */ (void) get_priv(rp, (ip->flags & SYS_PROC)); /* assign structure */
rp->p_priv->s_flags = ip->flags; /* process flags */ priv(rp)->s_flags = ip->flags; /* process flags */
rp->p_priv->s_call_mask = ip->call_mask;/* allowed system calls */ priv(rp)->s_call_mask = ip->call_mask; /* allowed traps */
if (i-NR_TASKS < 0) { /* part of the kernel? */ priv(rp)->s_send_mask.chunk[0] = ip->send_mask; /* restrict targets */
if (iskerneln(proc_nr(rp))) { /* part of the kernel? */
if (ip->stksize > 0) { /* HARDWARE stack size is 0 */ if (ip->stksize > 0) { /* HARDWARE stack size is 0 */
rp->p_priv->s_stack_guard = (reg_t *) ktsb; rp->p_priv->s_stack_guard = (reg_t *) ktsb;
*rp->p_priv->s_stack_guard = STACK_GUARD; *rp->p_priv->s_stack_guard = STACK_GUARD;
@ -97,14 +97,14 @@ PUBLIC void main()
/* processes that are in the kernel */ /* processes that are in the kernel */
hdrindex = 0; /* all use the first a.out header */ hdrindex = 0; /* all use the first a.out header */
} else { } else {
hdrindex = 1 + i-NR_TASKS; /* drivers, servers, INIT follow */ hdrindex = 1 + i-NR_TASKS; /* servers, drivers, INIT */
} }
/* The bootstrap loader created an array of the a.out headers at /* The bootstrap loader created an array of the a.out headers at
* absolute address 'aout'. Get one element to e_hdr. * absolute address 'aout'. Get one element to e_hdr.
*/ */
phys_copy(aout + hdrindex * A_MINHDR, vir2phys(&e_hdr), phys_copy(aout + hdrindex * A_MINHDR, vir2phys(&e_hdr),
(phys_bytes) A_MINHDR); (phys_bytes) A_MINHDR);
/* Convert addresses to clicks and build process memory map */ /* Convert addresses to clicks and build process memory map */
text_base = e_hdr.a_syms >> CLICK_SHIFT; text_base = e_hdr.a_syms >> CLICK_SHIFT;
text_clicks = (e_hdr.a_text + CLICK_SIZE-1) >> CLICK_SHIFT; text_clicks = (e_hdr.a_text + CLICK_SIZE-1) >> CLICK_SHIFT;
@ -127,7 +127,7 @@ PUBLIC void main()
/* Initialize the server stack pointer. Take it down one word /* Initialize the server stack pointer. Take it down one word
* to give crtso.s something to use as "argc". * to give crtso.s something to use as "argc".
*/ */
if (i-NR_TASKS >= 0) { if (isusern(proc_nr(rp))) { /* user-space process? */
rp->p_reg.sp = (rp->p_memmap[S].mem_vir + rp->p_reg.sp = (rp->p_memmap[S].mem_vir +
rp->p_memmap[S].mem_len) << CLICK_SHIFT; rp->p_memmap[S].mem_len) << CLICK_SHIFT;
rp->p_reg.sp -= sizeof(reg_t); rp->p_reg.sp -= sizeof(reg_t);

View file

@ -50,8 +50,8 @@ struct priv {
#define priv_id(rp) ((rp)->p_priv->s_id) #define priv_id(rp) ((rp)->p_priv->s_id)
#define priv(rp) ((rp)->p_priv) #define priv(rp) ((rp)->p_priv)
#define id_to_nr(id) priv_addr(id)->s_proc_nr; #define id_to_nr(id) priv_addr(id)->s_proc_nr
#define nr_to_id(nr) priv(proc_addr(nr))->s_id; #define nr_to_id(nr) priv(proc_addr(nr))->s_id
/* The system structures table and pointers to individual table slots. The /* The system structures table and pointers to individual table slots. The
* pointers allow faster access because now a process entry can be found by * pointers allow faster access because now a process entry can be found by

View file

@ -130,47 +130,46 @@ message *m_ptr; /* pointer to message in the caller's space */
if (! (isokprocn(src_dst) || src_dst == ANY || function == ECHO)) if (! (isokprocn(src_dst) || src_dst == ANY || function == ECHO))
return(EBADSRCDST); return(EBADSRCDST);
#if DEAD_CODE /* temporarily disabled for testing ALERT */ /* If the call involves a message buffer, i.e., for SEND, RECEIVE, SENDREC,
/* This check allows a message to be anywhere in data or stack or gap. * or ECHO, check the message pointer. This check allows a message to be
* It will have to be made more elaborate later for machines which * anywhere in data or stack or gap. It will have to be made more elaborate
* don't have the gap mapped. * for machines which don't have the gap mapped.
*/ */
vb = (vir_bytes) m_ptr; if (function & SENDREC) {
vlo = vb >> CLICK_SHIFT; /* vir click for bottom of message */ vb = (vir_bytes) m_ptr; /* virtual clicks */
vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT; /* vir click for top of msg */ vlo = vb >> CLICK_SHIFT; /* bottom of message */
if (vlo < caller_ptr->p_memmap[D].mem_vir || vlo > vhi || vhi = (vb + MESS_SIZE - 1) >> CLICK_SHIFT; /* top of message */
vhi >= caller_ptr->p_memmap[S].mem_vir + caller_ptr->p_memmap[S].mem_len) if (vlo < caller_ptr->p_memmap[D].mem_vir || vlo > vhi ||
return(EFAULT); vhi >= caller_ptr->p_memmap[S].mem_vir +
#endif caller_ptr->p_memmap[S].mem_len) return(EFAULT);
}
/* If the call is to send to a process, i.e., for SEND, SENDREC or NOTIFY,
* verify that the caller is allowed to send to the given destination and
* that the destination is still alive.
*/
if (function & SEND) {
if (! get_sys_bit(priv(caller_ptr)->s_send_mask, nr_to_id(src_dst))) {
kprintf("Warning, send_mask denied %d sending to %d\n",
proc_nr(caller_ptr), src_dst);
return(ECALLDENIED);
}
if (isemptyn(src_dst)) return(EDEADDST); /* cannot send to the dead */
}
/* Now check if the call is known and try to perform the request. The only /* Now check if the call is known and try to perform the request. The only
* system calls that exist in MINIX are sending and receiving messages. * system calls that exist in MINIX are sending and receiving messages.
* - SENDREC: combines SEND and RECEIVE in a single system call * - SENDREC: combines SEND and RECEIVE in a single system call
* - SEND: sender blocks until its message has been delivered * - SEND: sender blocks until its message has been delivered
* - RECEIVE: receiver blocks until an acceptable message has arrived * - RECEIVE: receiver blocks until an acceptable message has arrived
* - NOTIFY: sender continues; either directly deliver the message or * - NOTIFY: nonblocking call; deliver notification or mark pending
* queue the notification message until it can be delivered * - ECHO: nonblocking call; directly echo back the message
* - ECHO: the message directly will be echoed to the sender
*/ */
switch(function) { switch(function) {
case SENDREC: /* has FRESH_ANSWER flag */ case SENDREC: /* has FRESH_ANSWER flag */
/* fall through */ /* fall through */
case SEND: case SEND:
if (isemptyn(src_dst)) {
result = EDEADDST; /* cannot send to the dead */
break;
}
#if DEAD_CODE /* to be replaced by better mechanism */
mask_entry = isuserp(proc_addr(src_dst)) ? USER_PROC_NR : src_dst;
if (! isallowed(caller_ptr->p_sendmask, mask_entry)) {
kprintf("WARNING: sys_call denied %d ", caller_ptr->p_nr);
kprintf("sending to %d\n", proc_addr(src_dst)->p_nr);
result = ECALLDENIED; /* call denied by send mask */
break;
}
#endif
result = mini_send(caller_ptr, src_dst, m_ptr, flags); result = mini_send(caller_ptr, src_dst, m_ptr, flags);
if (function == SEND || result != OK) { if (function == SEND || result != OK) {
break; /* done, or SEND failed */ break; /* done, or SEND failed */
@ -191,18 +190,6 @@ message *m_ptr; /* pointer to message in the caller's space */
default: default:
result = EBADCALL; /* illegal system call */ result = EBADCALL; /* illegal system call */
} }
/* If the caller made a successfull, blocking system call it's priority may
* be raised. The priority may have been lowered if a process consumed too
* many full quantums in a row to prevent damage from infinite loops
*/
#if DEAD_CODE /* buggy ... do unready() first! */
if ((caller_ptr->p_priority > caller_ptr->p_max_priority) &&
! (flags & NON_BLOCKING) && (result == OK)) {
caller_ptr->p_priority = caller_ptr->p_max_priority;
caller_ptr->p_full_quantums = QUANTUMS(caller_ptr->p_priority);
}
#endif
/* Now, return the result of the system call to the caller. */ /* Now, return the result of the system call to the caller. */
return(result); return(result);
@ -514,7 +501,7 @@ register struct proc *rp; /* this process is now runnable */
#if DEBUG_SCHED_CHECK #if DEBUG_SCHED_CHECK
check_runqueues("ready"); check_runqueues("ready");
if(rp->p_ready) kprintf("ready() already ready process\n", NO_NUM); if(rp->p_ready) kprintf("ready() already ready process\n");
#endif #endif
/* Processes, in principle, are added to the end of the queue. However, /* Processes, in principle, are added to the end of the queue. However,
@ -562,7 +549,7 @@ register struct proc *rp; /* this process is no longer runnable */
#if DEBUG_SCHED_CHECK #if DEBUG_SCHED_CHECK
check_runqueues("unready"); check_runqueues("unready");
if (! rp->p_ready) kprintf("unready() already unready process\n", NO_NUM); if (! rp->p_ready) kprintf("unready() already unready process\n");
#endif #endif
/* Now make sure that the process is not in its ready queue. Remove the /* Now make sure that the process is not in its ready queue. Remove the
@ -582,6 +569,13 @@ register struct proc *rp; /* this process is no longer runnable */
} }
prev_xp = *xpp; /* save previous in chain */ prev_xp = *xpp; /* save previous in chain */
} }
/* The caller blocked. Reset the scheduling priority and quantums allowed.
* The process' priority may have been lowered if a process consumed too
* many full quantums in a row to prevent damage from infinite loops
*/
rp->p_priority = rp->p_max_priority;
rp->p_full_quantums = QUANTUMS(rp->p_priority);
#if DEBUG_SCHED_CHECK #if DEBUG_SCHED_CHECK
rp->p_ready = 0; rp->p_ready = 0;
@ -598,19 +592,8 @@ struct proc *sched_ptr; /* quantum eating process */
int q; int q;
/* Check if this process is preemptible, otherwise leave it as is. */ /* Check if this process is preemptible, otherwise leave it as is. */
if (! (priv(sched_ptr)->s_flags & PREEMPTIBLE)) { if (! (priv(sched_ptr)->s_flags & PREEMPTIBLE)) return;
#if DEAD_CODE
kprintf("Warning, sched for nonpreemptible proc %d\n", sched_ptr->p_nr);
#endif
return;
}
#if DEAD_CODE
if (sched_ptr->p_nr == IS_PROC_NR) {
kprintf("Scheduling IS: pri: %d, ", sched_ptr->p_priority);
kprintf("qua %d", sched_ptr->p_full_quantums);
}
#endif
/* Process exceeded the maximum number of full quantums it is allowed /* Process exceeded the maximum number of full quantums it is allowed
* to use in a row. Lower the process' priority, but make sure we don't * to use in a row. Lower the process' priority, but make sure we don't
* end up in the IDLE queue. This helps to limit the damage caused by * end up in the IDLE queue. This helps to limit the damage caused by
@ -619,13 +602,10 @@ struct proc *sched_ptr; /* quantum eating process */
*/ */
if (-- sched_ptr->p_full_quantums <= 0) { /* exceeded threshold */ if (-- sched_ptr->p_full_quantums <= 0) { /* exceeded threshold */
if (sched_ptr->p_priority + 1 < IDLE_Q ) { if (sched_ptr->p_priority + 1 < IDLE_Q ) {
q = sched_ptr->p_priority + 1; /* backup new priority */
unready(sched_ptr); /* remove from queues */ unready(sched_ptr); /* remove from queues */
sched_ptr->p_priority ++; /* lower priority */ sched_ptr->p_priority = q; /* lower priority */
ready(sched_ptr); /* add to new queue */ ready(sched_ptr); /* add to new queue */
#if DEAD_CODE
kprintf("Warning, proc %d got lower priority: ", sched_ptr->p_nr);
kprintf("%d\n", sched_ptr->p_priority);
#endif
} }
sched_ptr->p_full_quantums = QUANTUMS(sched_ptr->p_priority); sched_ptr->p_full_quantums = QUANTUMS(sched_ptr->p_priority);
} }
@ -646,14 +626,6 @@ kprintf("%d\n", sched_ptr->p_priority);
/* Give the expired process a new quantum and see who is next to run. */ /* Give the expired process a new quantum and see who is next to run. */
sched_ptr->p_sched_ticks = sched_ptr->p_quantum_size; sched_ptr->p_sched_ticks = sched_ptr->p_quantum_size;
pick_proc(); pick_proc();
#if DEAD_CODE
if (sched_ptr->p_nr == IS_PROC_NR) {
kprintf("Next proc: %d, ", next_ptr->p_nr);
kprintf("pri: %d, ", next_ptr->p_priority);
kprintf("qua: %d\n", next_ptr->p_full_quantums);
}
#endif
} }

View file

@ -79,7 +79,7 @@ struct proc {
#define IDLE_Q 15 /* lowest, only IDLE process goes here */ #define IDLE_Q 15 /* lowest, only IDLE process goes here */
/* Each queue has a maximum number of full quantums associated with it. */ /* Each queue has a maximum number of full quantums associated with it. */
#define QUANTUMS(q) (NR_SCHED_QUEUES - (q)) #define QUANTUMS(q) (1 + (NR_SCHED_QUEUES - (q))/2)
/* Magic process table addresses. */ /* Magic process table addresses. */
#define BEG_PROC_ADDR (&proc[0]) #define BEG_PROC_ADDR (&proc[0])

View file

@ -40,7 +40,7 @@ _PROTOTYPE( void cstart, (U16_t cs, U16_t ds, U16_t mds,
/* system.c */ /* system.c */
_PROTOTYPE( void send_sig, (int proc_nr, int sig_nr) ); _PROTOTYPE( void send_sig, (int proc_nr, int sig_nr) );
_PROTOTYPE( void cause_sig, (int proc_nr, int sig_nr) ); _PROTOTYPE( void cause_sig, (int proc_nr, int sig_nr) );
_PROTOTYPE( int set_priv, (register struct proc *rc,int sys_proc_flag) ); _PROTOTYPE( int get_priv, (register struct proc *rc, int proc_type) );
_PROTOTYPE( phys_bytes numap_local, (int proc_nr, vir_bytes vir_addr, _PROTOTYPE( phys_bytes numap_local, (int proc_nr, vir_bytes vir_addr,
vir_bytes bytes) ); vir_bytes bytes) );
_PROTOTYPE( void sys_task, (void) ); _PROTOTYPE( void sys_task, (void) );

View file

@ -11,7 +11,7 @@
* *
* In addition to the main sys_task() entry point, which starts the main loop, * In addition to the main sys_task() entry point, which starts the main loop,
* there are several other minor entry points: * there are several other minor entry points:
* set_priv: assign privilege structure to user or system process * get_priv: assign privilege structure to user or system process
* send_sig: send a signal directly to a system process * send_sig: send a signal directly to a system process
* cause_sig: take action to cause a signal to occur via PM * cause_sig: take action to cause a signal to occur via PM
* umap_local: map virtual address in LOCAL_SEG to physical * umap_local: map virtual address in LOCAL_SEG to physical
@ -164,9 +164,9 @@ PRIVATE void initialize(void)
/*===========================================================================* /*===========================================================================*
* set_priv * * get_priv *
*===========================================================================*/ *===========================================================================*/
PUBLIC int set_priv(rc, proc_type) PUBLIC int get_priv(rc, proc_type)
register struct proc *rc; /* new (child) process pointer */ register struct proc *rc; /* new (child) process pointer */
int proc_type; /* system or user process flag */ int proc_type; /* system or user process flag */
{ {

View file

@ -27,6 +27,7 @@ register message *m_ptr; /* pointer to request message */
#endif #endif
register struct proc *rpc; /* child process pointer */ register struct proc *rpc; /* child process pointer */
struct proc *rpp; /* parent process pointer */ struct proc *rpp; /* parent process pointer */
int i;
rpp = proc_addr(m_ptr->PR_PPROC_NR); rpp = proc_addr(m_ptr->PR_PPROC_NR);
rpc = proc_addr(m_ptr->PR_PROC_NR); rpc = proc_addr(m_ptr->PR_PROC_NR);
@ -51,6 +52,16 @@ register message *m_ptr; /* pointer to request message */
rpc->p_user_time = 0; /* set all the accounting times to 0 */ rpc->p_user_time = 0; /* set all the accounting times to 0 */
rpc->p_sys_time = 0; rpc->p_sys_time = 0;
/* If this is a system process, make sure the child process gets its own
* privilege structure for accounting.
*/
if (priv(rpc)->s_flags & SYS_PROC) {
if (OK != (i=get_priv(rpc, SYS_PROC))) return(i); /* get structure */
for (i=0; i< BITMAP_CHUNKS(NR_SYS_PROCS); i++) /* remove pending: */
priv(rpc)->s_notify_pending.chunk[i] = 0; /* - notifications */
priv(rpc)->s_int_pending = 0; /* - interrupts */
sigemptyset(&priv(rpc)->s_sig_pending); /* - signals */
}
return(OK); return(OK);
} }

View file

@ -22,6 +22,7 @@ message *m_ptr; /* pointer to request message */
register struct proc *rp; register struct proc *rp;
register struct priv *sp; register struct priv *sp;
int proc_nr; int proc_nr;
int i;
/* Extract message parameters. */ /* Extract message parameters. */
proc_nr = m_ptr->CTL_PROC_NR; proc_nr = m_ptr->CTL_PROC_NR;
@ -32,10 +33,23 @@ message *m_ptr; /* pointer to request message */
/* Make sure this process has its own privileges structure. */ /* Make sure this process has its own privileges structure. */
if (! (priv(rp)->s_flags & SYS_PROC)) if (! (priv(rp)->s_flags & SYS_PROC))
set_priv(rp, SYS_PROC); get_priv(rp, SYS_PROC);
/* Now update the process' privileges as requested. */ /* Now update the process' privileges as requested. */
rp->p_priv->s_call_mask = SYSTEM_CALL_MASK; rp->p_priv->s_call_mask = FILLED_MASK;
for (i=0; i<BITMAP_CHUNKS(NR_SYS_PROCS); i++) {
rp->p_priv->s_send_mask.chunk[i] = FILLED_MASK;
}
unset_sys_bit(rp->p_priv->s_send_mask, USER_PRIV_ID);
/* All process that this process can send to must be able to reply.
* Therefore, their send masks should be updated as well.
*/
for (i=0; i<NR_SYS_PROCS; i++) {
if (get_sys_bit(rp->p_priv->s_send_mask, i)) {
set_sys_bit(priv_addr(i)->s_send_mask, priv_id(rp));
}
}
return(OK); return(OK);
} }

View file

@ -60,7 +60,7 @@ register message *m_ptr;
if (rp->p_memmap[T].mem_len != 0) { if (rp->p_memmap[T].mem_len != 0) {
if ((src = umap_local(rp, T, tr_addr, TR_VLSIZE)) == 0) return(EIO); if ((src = umap_local(rp, T, tr_addr, TR_VLSIZE)) == 0) return(EIO);
phys_copy(src, vir2phys(&tr_data), (phys_bytes) sizeof(long)); phys_copy(src, vir2phys(&tr_data), (phys_bytes) sizeof(long));
m_ptr->CTL_DATA= tr_data; m_ptr->CTL_DATA = tr_data;
break; break;
} }
/* Text space is actually data space - fall through. */ /* Text space is actually data space - fall through. */

View file

@ -48,7 +48,7 @@
#define CLOCK_S SMALL_STACK #define CLOCK_S SMALL_STACK
/* Stack space for all the task stacks. Declared as (char *) to align it. */ /* Stack space for all the task stacks. Declared as (char *) to align it. */
#define TOT_STACK_SPACE (IDLE_S+HARDWARE_S+CLOCK_S+SYSTEM_S) #define TOT_STACK_SPACE (IDLE_S + HARDWARE_S + CLOCK_S + SYSTEM_S)
PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)]; PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
@ -60,6 +60,7 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
* routine and stack size is also provided. * routine and stack size is also provided.
*/ */
#define USER_F (PREEMPTIBLE | BILLABLE | RDY_Q_HEAD) #define USER_F (PREEMPTIBLE | BILLABLE | RDY_Q_HEAD)
#define IDLE_F (BILLABLE | SYS_PROC)
#define SYS_F (PREEMPTIBLE | SYS_PROC) #define SYS_F (PREEMPTIBLE | SYS_PROC)
#define TASK_F (SYS_PROC) #define TASK_F (SYS_PROC)
@ -68,37 +69,38 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
#define SYS_T 16 /* ticks */ #define SYS_T 16 /* ticks */
PUBLIC struct system_image image[] = { PUBLIC struct system_image image[] = {
{ IDLE, idle_task, USER_F, IDLE_T, IDLE_Q, IDLE_S, EMPTY_CALL_MASK, 0, "IDLE" }, { IDLE, idle_task, IDLE_F, IDLE_T, IDLE_Q, IDLE_S, EMPTY_MASK, EMPTY_MASK, "IDLE" },
{ CLOCK, clock_task, TASK_F, SYS_T, TASK_Q, CLOCK_S, SYSTEM_CALL_MASK, 0, "CLOCK" }, { CLOCK, clock_task, TASK_F, SYS_T, TASK_Q, CLOCK_S, FILLED_MASK, SYSTEM_SEND_MASK, "CLOCK" },
{ SYSTEM, sys_task, TASK_F, SYS_T, TASK_Q, SYSTEM_S, SYSTEM_CALL_MASK, 0, "SYS" }, { SYSTEM, sys_task, TASK_F, SYS_T, TASK_Q, SYSTEM_S, FILLED_MASK, SYSTEM_SEND_MASK, "SYS" },
{ HARDWARE, 0, TASK_F, SYS_T, TASK_Q, HARDWARE_S, EMPTY_CALL_MASK, 0,"KERNEL" }, { HARDWARE, 0, TASK_F, SYS_T, TASK_Q, HARDWARE_S, EMPTY_MASK, SYSTEM_SEND_MASK, "KERNEL" },
{ PM_PROC_NR, 0, SYS_F, SYS_T, 3, 0, SYSTEM_CALL_MASK, 0, "PM" }, { PM_PROC_NR, 0, SYS_F, SYS_T, 3, 0, FILLED_MASK, SERVER_SEND_MASK, "PM" },
{ FS_PROC_NR, 0, SYS_F, SYS_T, 3, 0, SYSTEM_CALL_MASK, 0, "FS" }, { FS_PROC_NR, 0, SYS_F, SYS_T, 3, 0, FILLED_MASK, SERVER_SEND_MASK, "FS" },
{ IS_PROC_NR, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "IS" }, { SM_PROC_NR, 0, SYS_F, SYS_T, 3, 0, FILLED_MASK, SYSTEM_SEND_MASK, "SM" },
{ TTY, 0, SYS_F, SYS_T, 1, 0, SYSTEM_CALL_MASK, 0, "TTY" }, { IS_PROC_NR, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "IS" },
{ MEMORY, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "MEMORY" }, { TTY, 0, SYS_F, SYS_T, 1, 0, FILLED_MASK, SYSTEM_SEND_MASK, "TTY" },
{ MEMORY, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "MEMORY" },
#if ENABLE_AT_WINI #if ENABLE_AT_WINI
{ AT_WINI, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "AT_WINI" }, { AT_WINI, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "AT_WINI" },
#endif #endif
#if ENABLE_FLOPPY #if ENABLE_FLOPPY
{ FLOPPY, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "FLOPPY" }, { FLOPPY, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "FLOPPY" },
#endif #endif
#if ENABLE_PRINTER #if ENABLE_PRINTER
{ PRINTER, 0, SYS_F, SYS_T, 3, 0, SYSTEM_CALL_MASK, 0, "PRINTER" }, { PRINTER, 0, SYS_F, SYS_T, 3, 0, FILLED_MASK, DRIVER_SEND_MASK, "PRINTER" },
#endif #endif
#if ENABLE_RTL8139 #if ENABLE_RTL8139
{ USR8139, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "RTL8139" }, { RTL8139, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "RTL8139" },
#endif #endif
#if ENABLE_FXP #if ENABLE_FXP
{ FXP, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "FXP" }, { FXP, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "FXP" },
#endif #endif
#if ENABLE_DPETH #if ENABLE_DPETH
{ DPETH, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "DPETH" }, { DPETH, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, DRIVER_SEND_MASK, "DPETH" },
#endif #endif
#if ENABLE_LOG #if ENABLE_LOG
{ LOG_PROC_NR, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, 0, "LOG" }, { LOG_PROC_NR, 0, SYS_F, SYS_T, 2, 0, FILLED_MASK, SYSTEM_SEND_MASK, "LOG" },
#endif #endif
{ INIT_PROC_NR, 0, USER_F, USER_T, USER_Q, 0, USER_CALL_MASK, 0, "INIT" }, { INIT_PROC_NR, 0, USER_F, USER_T, USER_Q, 0, USER_CALL_MASK, USER_SEND_MASK, "INIT" },
}; };
/* Verify the size of the system image table at compile time. If the number /* Verify the size of the system image table at compile time. If the number

View file

@ -18,7 +18,7 @@ struct system_image {
int priority; /* scheduling priority */ int priority; /* scheduling priority */
int stksize; /* stack size for tasks */ int stksize; /* stack size for tasks */
char call_mask; /* allowed system calls */ char call_mask; /* allowed system calls */
long send_mask; /* send mask protection */ bitchunk_t send_mask; /* send mask protection */
char proc_name[P_NAME_LEN]; /* name in process table */ char proc_name[P_NAME_LEN]; /* name in process table */
}; };

View file

@ -12,9 +12,9 @@
* output driver when a new message is ready. * output driver when a new message is ready.
*/ */
#include <stdarg.h>
#include "kernel.h" #include "kernel.h"
#include <unistd.h> #include <unistd.h>
#include <stdarg.h>
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
@ -58,6 +58,7 @@ int nr;
PUBLIC void kprintf(const char *fmt, ...) /* format to be printed */ PUBLIC void kprintf(const char *fmt, ...) /* format to be printed */
{ {
int c; /* next character in fmt */ int c; /* next character in fmt */
int d;
unsigned long u; /* hold number argument */ unsigned long u; /* hold number argument */
int base; /* base of number arg */ int base; /* base of number arg */
int negative = 0; /* print minus sign */ int negative = 0; /* print minus sign */
@ -79,8 +80,8 @@ PUBLIC void kprintf(const char *fmt, ...) /* format to be printed */
* conversion after the switch statement. * conversion after the switch statement.
*/ */
case 'd': /* output decimal */ case 'd': /* output decimal */
u = va_arg(argp, int); d = va_arg(argp, signed int);
if (u < 0) { negative = 1; u = -u; } if (d < 0) { negative = 1; u = -d; } else { u = d; }
base = 10; base = 10;
break; break;
case 'u': /* output unsigned long */ case 'u': /* output unsigned long */
@ -116,6 +117,7 @@ PUBLIC void kprintf(const char *fmt, ...) /* format to be printed */
/* This is where the actual output for format "%key" is done. */ /* This is where the actual output for format "%key" is done. */
if (negative) kputc('-'); /* print sign if negative */ if (negative) kputc('-'); /* print sign if negative */
while(*s != 0) { kputc(*s++); } /* print string/ number */ while(*s != 0) { kputc(*s++); } /* print string/ number */
s = NULL; /* reset for next round */
} }
else { else {
kputc(c); /* print and continue */ kputc(c); /* print and continue */