From 0e2a7a9730ee04391a7c858eb8e2339bf7a63947 Mon Sep 17 00:00:00 2001 From: Jorrit Herder Date: Tue, 7 Jun 2005 12:34:25 +0000 Subject: [PATCH] Kernel cleanup. Reduced kernel size by 512KB by moving private buffer into cstart() function. Replaced assertions with erroneous return values. Removed assertions relating to isuserp(rp), since all processes should become user processes; system processes are now treated similar to other processes. --- kernel/Makefile | 2 - kernel/assert.h | 25 ------ kernel/debug.h | 1 - kernel/ipc.h | 2 +- kernel/misc.c | 65 +-------------- kernel/proc.c | 50 ++++++----- kernel/proc.h | 16 ++-- kernel/proto.h | 2 - kernel/start.c | 65 ++++++++------- kernel/system.h | 6 +- kernel/system/Makefile | 2 +- kernel/system/misc.c | 25 +++--- kernel/system/proctl.c | 7 +- kernel/system/sigctl.c | 185 +++++++++++++++++++---------------------- 14 files changed, 169 insertions(+), 284 deletions(-) delete mode 100755 kernel/assert.h diff --git a/kernel/Makefile b/kernel/Makefile index 8212b972a..4bfdd52b9 100755 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -92,7 +92,6 @@ main.o: sendmask.h misc.o: $a misc.o: $i/stdlib.h misc.o: $h/com.h -misc.o: assert.h printer.o: $a printer.o: $h/callnr.h @@ -124,7 +123,6 @@ system.o: $h/com.h system.o: system.h system.o: proc.h system.o: protect.h -system.o: assert.h system.o: sendmask.h table.o: $a diff --git a/kernel/assert.h b/kernel/assert.h deleted file mode 100755 index 87cf7205a..000000000 --- a/kernel/assert.h +++ /dev/null @@ -1,25 +0,0 @@ -/* assert.h */ - -#ifndef NDEBUG /* 8086 must do without training wheels. */ -#define NDEBUG (_WORD_SIZE == 2) -#endif - -#if !NDEBUG - -#define INIT_ASSERT static char *assert_file= __FILE__; - -void bad_assertion(char *file, int line, char *what); -void bad_compare(char *file, int line, int lhs, char *what, int rhs); - -#define assert(x) (!(x) ? bad_assertion(assert_file, __LINE__, #x) \ - : (void) 0) -#define compare(a,t,b) (!((a) t (b)) ? bad_compare(assert_file, __LINE__, \ - (a), #a " " #t " " #b, (b)) : (void) 0) -#else /* NDEBUG */ - -#define INIT_ASSERT /* nothing */ - -#define assert(x) (void)0 -#define compare(a,t,b) (void)0 - -#endif /* NDEBUG */ diff --git a/kernel/debug.h b/kernel/debug.h index 3382330d4..259c29484 100644 --- a/kernel/debug.h +++ b/kernel/debug.h @@ -1,4 +1,3 @@ - #ifndef DEBUG_H #define DEBUG_H diff --git a/kernel/ipc.h b/kernel/ipc.h index f996082d3..49d4def4f 100644 --- a/kernel/ipc.h +++ b/kernel/ipc.h @@ -13,7 +13,7 @@ #define NOTIFY 4 /* function code for notifications */ #if 0 -/* Bit map operations used to bits of simple bit mask. */ +/* Bit map operations to manipulate bits of a simple mask variable. */ #define set_bit(mask, n) ((mask) |= (1 << (n))) #define clear_bit(mask, n) ((mask) &= ~(1 << (n))) #define isset_bit(mask, n) ((mask) & (1 << (n))) diff --git a/kernel/misc.c b/kernel/misc.c index 37da8b924..dc40c9e81 100755 --- a/kernel/misc.c +++ b/kernel/misc.c @@ -1,10 +1,7 @@ /* This file contains a collection of miscellaneous procedures: * panic abort MINIX due to a fatal error - * bad_assertion for debugging - * bad_compare for debugging * alloc_bit bit map manipulation * free_bit bit map manipulation - * print_bitmap bit map manipulation */ #include "kernel.h" @@ -20,11 +17,7 @@ PUBLIC void panic(s,n) _CONST char *s; int n; { -/* The system has run aground of a fatal error. Terminate execution. - * If the panic originated in MM or FS, the string will be empty and the - * file system already syncked. If the panic originates in the kernel, we are - * kind of stuck. - */ +/* The system has run aground of a fatal kernel error. Terminate execution. */ static int panicking = 0; if (panicking ++) /* prevent recursive panics */ return; @@ -37,26 +30,6 @@ int n; prepare_shutdown(RBT_PANIC); } -#if ENABLE_K_DEBUGGING -/*===========================================================================* - * print_bitmap * - *===========================================================================*/ -PUBLIC void print_bitmap(bitmap, nr_bits) -bitchunk_t *bitmap; -bit_t nr_bits; -{ - bit_t bit_i; - - for (bit_i=0; bit_i < nr_bits; bit_i++) { - - kprintf("%d", GET_BIT(bitmap, bit_i) > 0 ); - if (! ((bit_i+1) % 8) ) kprintf(" ", NO_ARG); - if (! ((bit_i+1) % 64) ) kprintf("\n", NO_ARG); - } - kprintf("\n", NO_ARG); -} -#endif /* ENABLE_K_DEBUGGING */ - /*===========================================================================* * free_bit * *===========================================================================*/ @@ -107,39 +80,3 @@ bit_t nr_bits; return(-1); } - - - -#if !NDEBUG -/*=========================================================================* - * bad_assertion * - *=========================================================================*/ -PUBLIC void bad_assertion(file, line, what) -char *file; -int line; -char *what; -{ - kprintf("panic at %s", karg(file)); - kprintf(" (line %d): ", line); - kprintf("assertion \"%s\" failed.\n", karg(what)); - panic(NULL, NO_NUM); -} - -/*=========================================================================* - * bad_compare * - *=========================================================================*/ -PUBLIC void bad_compare(file, line, lhs, what, rhs) -char *file; -int line; -int lhs; -char *what; -int rhs; -{ - kprintf("panic at %s", karg(file)); - kprintf(" (line %d): ", line); - kprintf("compare (%d)", lhs); - kprintf(" %s ", karg(what)); - kprintf("(%d) failed.\n", rhs); - panic(NULL, NO_NUM); -} -#endif /* !NDEBUG */ diff --git a/kernel/proc.c b/kernel/proc.c index c4512c606..94bf2c12c 100755 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -1,6 +1,7 @@ -#define NEW_SCHED_Q 1 -#define OLD_SEND 0 -#define OLD_RECV 0 +#define NEW_ELOCKED_CHECK 1 +#define NEW_SCHED_Q 1 +#define OLD_SEND 0 +#define OLD_RECV 0 /* This file contains essentially all of the process and message handling. * Together with "mpx.s" it forms the lowest layer of the MINIX kernel. * There is one entry point from the outside: @@ -57,7 +58,7 @@ */ FORWARD _PROTOTYPE( int mini_send, (struct proc *caller_ptr, int dst, message *m_ptr, unsigned flags) ); -FORWARD _PROTOTYPE( int mini_rec, (struct proc *caller_ptr, int src, +FORWARD _PROTOTYPE( int mini_receive, (struct proc *caller_ptr, int src, message *m_ptr, unsigned flags) ); FORWARD _PROTOTYPE( int mini_notify, (struct proc *caller_ptr, int dst, message *m_ptr ) ); @@ -111,10 +112,12 @@ message *m_ptr; /* pointer to message in the caller's space */ * if the caller doesn't do receive(). */ if (! (caller_ptr->p_call_mask & (1 << function)) || - iskernel(src_dst) && function != SENDREC) return(ECALLDENIED); + (iskerneltask(src_dst) && function != SENDREC)) + return(ECALLDENIED); - /* Verify that requested source and/ or destination is a valid process. */ - if (! isoksrc_dst(src_dst) && function != ECHO) return(EBADSRCDST); + /* Require a valid source and/ or destination process, unless echoing. */ + if (! (isokprocn(src_dst) || src_dst == ANY || function == ECHO)) + return(EBADSRCDST); /* Check validity of message pointer. */ vb = (vir_bytes) m_ptr; @@ -145,21 +148,7 @@ message *m_ptr; /* pointer to message in the caller's space */ * - ECHO: the message directly will be echoed to the sender */ switch(function) { - case SENDREC: /* has FRESH_ANSWER flags */ -#if DEAD_CODE - { message m; - if (caller_ptr->p_nr == MEMORY && src_dst == FS_PROC_NR) { - CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, proc_addr(HARDWARE), &m); - kprintf("MEMORY sendrec FS, m.m_type %d", m.m_type); - kprintf("TTY_LINE %d", m.TTY_LINE); - kprintf("TTY_REQ %d\n", m.TTY_REQUEST); - } - if (caller_ptr->p_nr == FS_PROC_NR && src_dst == MEMORY) { - CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, proc_addr(HARDWARE), &m); - kprintf("FS sendrec MEMORY, m.m_type %d\n", m.m_type); - } - } -#endif + case SENDREC: /* has FRESH_ANSWER flag */ /* fall through */ case SEND: if (! isalive(src_dst)) { @@ -179,7 +168,7 @@ message *m_ptr; /* pointer to message in the caller's space */ break; /* done, or SEND failed */ } /* fall through for SENDREC */ case RECEIVE: - result = mini_rec(caller_ptr, src_dst, m_ptr, flags); + result = mini_receive(caller_ptr, src_dst, m_ptr, flags); break; case NOTIFY: result = mini_notify(caller_ptr, src_dst, m_ptr); @@ -217,12 +206,20 @@ unsigned flags; /* system call flags */ register struct proc *xp; #else register struct proc **xpp; + register struct proc *xp; #endif dst_ptr = proc_addr(dst); /* pointer to destination's proc entry */ /* Check for deadlock by 'caller_ptr' and 'dst' sending to each other. */ +#if NEW_ELOCKED_CHECK + xp = dst_ptr; + while (xp->p_flags & SENDING) { /* check while sending */ + xp = proc_addr(xp->p_sendto); /* get xp's destination */ + if (xp == caller_ptr) return(ELOCKED); /* deadlock if cyclic */ + } +#else if (dst_ptr->p_flags & SENDING) { next_ptr = proc_addr(dst_ptr->p_sendto); while (TRUE) { @@ -233,6 +230,7 @@ unsigned flags; /* system call flags */ break; } } +#endif /* Check if 'dst' is blocked waiting for this message. The destination's * SENDING flag may be set when its SENDREC call blocked while sending. @@ -272,9 +270,9 @@ unsigned flags; /* system call flags */ } /*===========================================================================* - * mini_rec * + * mini_receive * *===========================================================================*/ -PRIVATE int mini_rec(caller_ptr, src, m_ptr, flags) +PRIVATE int mini_receive(caller_ptr, src, m_ptr, flags) register struct proc *caller_ptr; /* process trying to get message */ int src; /* which message source is wanted */ message *m_ptr; /* pointer to message buffer */ @@ -398,7 +396,7 @@ message *m_ptr; /* pointer to message buffer */ /* Destination is not ready. Add the notification to the pending queue. * Get pointer to notification message. Don't copy if already in kernel. */ - if (! iskernelp(caller_ptr)) { + if (! istaskp(caller_ptr)) { CopyMess(proc_nr(caller_ptr), caller_ptr, m_ptr, proc_addr(HARDWARE), &ntf_mess); m_ptr = &ntf_mess; diff --git a/kernel/proc.h b/kernel/proc.h index 570d8decc..4972e3428 100755 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -110,26 +110,24 @@ struct proc { #define END_PROC_ADDR (&proc[NR_TASKS + NR_PROCS]) #define NIL_PROC ((struct proc *) 0) +#define cproc_addr(n) (&(proc + NR_TASKS)[(n)]) +#define proc_addr(n) (pproc_addr + NR_TASKS)[(n)] +#define proc_nr(p) ((p)->p_nr) + +#define iskerneltask(n) ((n) == CLOCK || (n) == SYSTASK) #define isidlehardware(n) ((n) == IDLE || (n) == HARDWARE) #define isokprocn(n) ((unsigned) ((n) + NR_TASKS) < NR_PROCS + NR_TASKS) #define isokprocp(p) ((p) >= BEG_PROC_ADDR && (p) < END_PROC_ADDR) -#define isoksrc_dst(n) (isokprocn(n) || (n) == ANY) #define isalive(n) (proc_addr(n)->p_type > P_NONE) #define isalivep(p) ((p)->p_type > P_NONE) -#define isrxhardware(n) ((n) == ANY || (n) == HARDWARE) -#define isreservedp(p) ((p)->p_type == P_RESERVED) #define isemptyp(p) ((p)->p_type == P_NONE) #define istaskp(p) ((p)->p_type == P_TASK) #define isdriverp(p) ((p)->p_type == P_DRIVER) #define isserverp(p) ((p)->p_type == P_SERVER) #define isuserp(p) ((p)->p_type == P_USER) -#define isuser(n) (proc_addr(n)->p_type == P_USER) #define isidlep(p) ((p)->p_type == P_IDLE) -#define cproc_addr(n) (&(proc + NR_TASKS)[(n)]) -#define proc_addr(n) (pproc_addr + NR_TASKS)[(n)] -#define proc_nr(p) ((p)->p_nr) -#define iskernelp(p) ((p)->p_nr < 0) -#define iskernel(n) ((n) == CLOCK || (n) == SYSTASK) + +#define isuser(n) (proc_addr(n)->p_type == P_USER) /* The process table and pointers to process table slots. The pointers allow * faster access because now a process entry can be found by indexing the diff --git a/kernel/proto.h b/kernel/proto.h index 5194a570b..9f73710c1 100755 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -40,7 +40,6 @@ _PROTOTYPE( void stop_sequence, (struct timer *tp) ); _PROTOTYPE( void panic, (_CONST char *s, int n) ); _PROTOTYPE( int alloc_bit, (bitchunk_t *map, bit_t nr_bits) ); _PROTOTYPE( void free_bit, (bit_t nr, bitchunk_t *map, bit_t nr_bits) ); -_PROTOTYPE( void print_bitmap, (bitchunk_t *map, bit_t nr_bits) ); /* proc.c */ _PROTOTYPE( int sys_call, (int function, int src_dest, message *m_ptr) ); @@ -54,7 +53,6 @@ _PROTOTYPE( void lock_unready, (struct proc *rp) ); /* start.c */ _PROTOTYPE( void cstart, (U16_t cs, U16_t ds, U16_t mds, U16_t parmoff, U16_t parmsize) ); -_PROTOTYPE( char *getkenv, (_CONST char *key) ); /* system.c */ _PROTOTYPE( void cause_sig, (int proc_nr, int sig_nr) ); diff --git a/kernel/start.c b/kernel/start.c index 9f6172b10..b2be5b83e 100755 --- a/kernel/start.c +++ b/kernel/start.c @@ -3,7 +3,6 @@ * * This code runs in real mode for a 16 bit kernel and may have to switch * to protected mode for a 286. - * * For a 32 bit kernel this already runs in protected mode, but the selectors * are still those given by the BIOS with interrupts disabled, so the * descriptors need to be reloaded and interrupt descriptors made. @@ -13,10 +12,8 @@ #include "protect.h" #include "proc.h" -/* Environment strings passed by loader. */ -PRIVATE char k_environ[128*sizeof(char *)]; - -FORWARD _PROTOTYPE( void mem_init, (void) ); +FORWARD _PROTOTYPE( void mem_init, (_CONST char *params)); +FORWARD _PROTOTYPE( char *get_value, (_CONST char *params, _CONST char *key)); /*==========================================================================* * cstart * @@ -29,7 +26,8 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */ /* Perform system initializations prior to calling main(). Most settings are * determined with help of the environment strings passed by MINIX' loader. */ - register char *envp; + char params[128*sizeof(char *)]; /* boot monitor parameters */ + register char *value; /* value in key=value pair */ unsigned mon_start; extern int etext, end; @@ -53,8 +51,8 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */ /* Copy the boot parameters to kernel memory. */ kinfo.params_base = seg2phys(mds) + parmoff; - kinfo.params_size = MAX(parmsize,sizeof(k_environ)-2); - phys_copy(kinfo.params_base, vir2phys(k_environ), kinfo.params_size); + kinfo.params_size = MAX(parmsize,sizeof(params)-2); + phys_copy(kinfo.params_base, vir2phys(params), kinfo.params_size); /* Record miscellaneous information for user-space servers. */ kinfo.nr_procs = NR_PROCS; @@ -64,8 +62,8 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */ kinfo.kmem_base = vir2phys(0); kinfo.kmem_size = (phys_bytes) &end; - /* Processor? */ - machine.processor=katoi(getkenv("processor")); /* 86, 186, 286, 386, ... */ + /* Processor? 86, 186, 286, 386, ... */ + machine.processor=katoi(get_value(params, "processor")); /* Decide if mode is protected for older machines. */ #if _WORD_SIZE == 2 @@ -74,20 +72,20 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */ if (! machine.protected) mon_return = 0; /* XT, AT or MCA bus? */ - envp = getkenv("bus"); - if (envp == NIL_PTR || kstrcmp(envp, "at") == 0) { + value = get_value(params, "bus"); + if (value == NIL_PTR || kstrcmp(value, "at") == 0) { machine.pc_at = TRUE; /* PC-AT compatible hardware */ - } else if (kstrcmp(envp, "mca") == 0) { + } else if (kstrcmp(value, "mca") == 0) { machine.pc_at = machine.ps_mca = TRUE; /* PS/2 with micro channel */ } /* Type of VDU: */ - envp = getkenv("video"); /* EGA or VGA video unit */ - if (kstrcmp(envp, "ega") == 0) machine.vdu_ega = TRUE; - if (kstrcmp(envp, "vga") == 0) machine.vdu_vga = machine.vdu_ega = TRUE; + value = get_value(params, "video"); /* EGA or VGA video unit */ + if (kstrcmp(value, "ega") == 0) machine.vdu_ega = TRUE; + if (kstrcmp(value, "vga") == 0) machine.vdu_vga = machine.vdu_ega = TRUE; /* Initialize free memory list from size passed by boot monitor. */ - mem_init(); + mem_init(params); /* Return to assembler code to switch to protected mode (if 286), * reload selectors and call main(). @@ -107,7 +105,8 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */ /*=========================================================================* * mem_init * *=========================================================================*/ -PRIVATE void mem_init() +PRIVATE void mem_init(params) +_CONST char *params; /* boot monitor parameters */ { /* Initialize the free memory list from the 'memory' boot variable. Translate * the byte offsets and sizes in this list to clicks, properly truncated. Also @@ -128,22 +127,23 @@ PRIVATE void mem_init() * b1:s1 is mem between 1M and 16M, b2:s2 is mem above 16M. Pairs b1:s1 * and b2:s2 are combined if the memory is adjacent. */ - s = getkenv("memory"); /* get memory boot variable */ + s = get_value(params, "memory"); /* get memory boot variable */ for (i = 0; i < NR_MEMS; i++) { - memp = &mem[i]; /* result is stored here */ - base = size = 0; - if (*s != 0) { /* end of boot variable */ - /* Expect base to be read (end != s) and ':' as next char. */ + memp = &mem[i]; /* next mem chunk is stored here */ + base = size = 0; /* initialize next base:size pair */ + if (*s != 0) { /* get fresh data, unless at end */ + + /* Read fresh base and expect colon as next char. */ base = kstrtoul(s, &end, 0x10); /* get number */ if (end != s && *end == ':') s = ++end; /* skip ':' */ - else *s=0; /* fake end for next; should not happen */ - /* Expect size to be read and skip ',', unless at end. */ + else *s=0; /* terminate, should not happen */ + + /* Read fresh size and expect comma or assume end. */ size = kstrtoul(s, &end, 0x10); /* get number */ if (end != s && *end == ',') s = ++end; /* skip ',' */ - else if (end != s && *end == 0) s = end; /* end found */ - else *s=0; /* fake end for next; should not happen */ + else *s=0; /* found end */ } - limit = base + size; + limit = base + size; /* limit is used for validity check */ #if _WORD_SIZE == 2 max_address = kinfo.protected ? MAX_16BIT : MAX_REAL; if (limit > max_address) limit = max_address; @@ -158,10 +158,11 @@ PRIVATE void mem_init() /*==========================================================================* - * getkenv * + * get_value * *==========================================================================*/ -PUBLIC char *getkenv(name) -_CONST char *name; +PRIVATE char *get_value(params, name) +_CONST char *params; /* boot monitor parameters */ +_CONST char *name; /* key to look up */ { /* Get environment value - kernel version of getenv to avoid setting up the * usual environment array. @@ -169,7 +170,7 @@ _CONST char *name; register _CONST char *namep; register char *envp; - for (envp = k_environ; *envp != 0;) { + for (envp = (char *) params; *envp != 0;) { for (namep = name; *namep != 0 && *namep == *envp; namep++, envp++) ; if (*namep == '\0' && *envp == '=') return(envp + 1); diff --git a/kernel/system.h b/kernel/system.h index 37b051a91..fe0e1804f 100644 --- a/kernel/system.h +++ b/kernel/system.h @@ -13,7 +13,6 @@ #include #include #include "proc.h" -#include "assert.h" _PROTOTYPE( int do_exec, (message *m_ptr) ); /* process control */ _PROTOTYPE( int do_fork, (message *m_ptr) ); @@ -27,6 +26,7 @@ _PROTOTYPE( int do_vcopy, (message *m_ptr) ); #define do_virvcopy do_vcopy #define do_physvcopy do_vcopy _PROTOTYPE( int do_umap, (message *m_ptr) ); +_PROTOTYPE( int do_physzero, (message *m_ptr) ); _PROTOTYPE( int do_unused, (message *m_ptr) ); /* miscellaneous */ _PROTOTYPE( int do_abort, (message *m_ptr) ); @@ -60,9 +60,5 @@ _PROTOTYPE( int do_trace, (message *m_ptr) ); /* process tracing */ #define do_trace do_unused #endif -_PROTOTYPE( int do_vircopy, (message *m_ptr) ); -_PROTOTYPE( int do_physcopy, (message *m_ptr) ); -_PROTOTYPE( int do_physzero, (message *m_ptr) ); -_PROTOTYPE( int do_biosio, (message *m_ptr) ); #endif /* SYSTEM_H */ diff --git a/kernel/system/Makefile b/kernel/system/Makefile index 6ff615131..51df0d07d 100644 --- a/kernel/system/Makefile +++ b/kernel/system/Makefile @@ -37,7 +37,7 @@ a = $h/config.h $h/const.h $h/type.h $h/ipc.h \ $k/proc.h $k/const.h $k/type.h $k/proto.h $k/glo.h # Dependencies from src/kernel/system.h -b = $k/system.h $h/com.h $k/proc.h $k/assert.h +b = $k/system.h $h/com.h $k/proc.h clock.o: $a $b copying.o: $a $b diff --git a/kernel/system/misc.c b/kernel/system/misc.c index 73f90389f..b985828d0 100644 --- a/kernel/system/misc.c +++ b/kernel/system/misc.c @@ -2,7 +2,6 @@ #include "../system.h" #include #include -INIT_ASSERT /*===========================================================================* @@ -37,26 +36,26 @@ message *m_ptr; /* pointer to request message */ * PM (normal abort or panic) or FS (panic), or TTY (a CTRL-ALT-DEL or ESC * after debugging dumps). */ - register struct proc *rp; - phys_bytes src_phys; - vir_bytes len; int how = m_ptr->ABRT_HOW; - rp = proc_addr(m_ptr->m_source); - if (how == RBT_MONITOR) { - /* The monitor is to run user specified instructions. */ - len = m_ptr->ABRT_MON_LEN + 1; - assert(len <= kinfo.params_size); - src_phys = numap_local(m_ptr->ABRT_MON_PROC, - (vir_bytes) m_ptr->ABRT_MON_ADDR, len); - assert(src_phys != 0); - phys_copy(src_phys, kinfo.params_base, (phys_bytes) len); + /* The monitor is to run user specified instructions. */ + int proc_nr = m_ptr->ABRT_MON_PROC; + int length = m_ptr->ABRT_MON_LEN + 1; + vir_bytes src_vir = (vir_bytes) m_ptr->ABRT_MON_ADDR; + phys_bytes src_phys = numap_local(proc_nr, src_vir, length); + + /* Validate length and address of shutdown code before copying. */ + if (length > kinfo.params_size || src_phys == 0) + kprintf("Warning, skipping shutdown code\n", NO_NUM); + else + phys_copy(src_phys, kinfo.params_base, (phys_bytes) length); } prepare_shutdown(how); return(OK); /* pro-forma (really EDISASTER) */ } + /* The system call implemented in this file: * m_type: SYS_GETINFO * diff --git a/kernel/system/proctl.c b/kernel/system/proctl.c index 42566983d..a608a8987 100644 --- a/kernel/system/proctl.c +++ b/kernel/system/proctl.c @@ -16,7 +16,6 @@ #endif #include "../debug.h" -INIT_ASSERT /*===========================================================================* * do_fork * @@ -33,9 +32,8 @@ register message *m_ptr; /* pointer to request message */ struct proc *rpp; rpp = proc_addr(m_ptr->PR_PPROC_NR); - assert(isuserp(rpp)); rpc = proc_addr(m_ptr->PR_PROC_NR); - assert(isemptyp(rpc)); + if (! isemptyp(rpc)) return(EINVAL); /* Copy parent 'proc' struct to child. */ #if (CHIP == INTEL) @@ -99,7 +97,7 @@ message *m_ptr; /* pointer to request message */ /* Copy the map from PM. */ src_phys = umap_local(proc_addr(caller), D, (vir_bytes) map_ptr, sizeof(rp->p_memmap)); - assert(src_phys != 0); + if (src_phys == 0) return(EFAULT); phys_copy(src_phys,vir2phys(rp->p_memmap),(phys_bytes)sizeof(rp->p_memmap)); #if (CHIP != M68000) @@ -140,7 +138,6 @@ register message *m_ptr; /* pointer to request message */ char *np; rp = proc_addr(m_ptr->PR_PROC_NR); - assert(isuserp(rp)); if (m_ptr->PR_TRACING) cause_sig(m_ptr->PR_PROC_NR, SIGTRAP); sp = (reg_t) m_ptr->PR_STACK_PTR; rp->p_reg.sp = sp; /* set the stack pointer */ diff --git a/kernel/system/sigctl.c b/kernel/system/sigctl.c index 21e0b04bc..d4b049841 100644 --- a/kernel/system/sigctl.c +++ b/kernel/system/sigctl.c @@ -21,7 +21,6 @@ #include "../system.h" #include #include -INIT_ASSERT /* PM is ready to accept signals and repeatedly does a system call to get * one. Find a process with pending signals. If no signals are available, @@ -72,61 +71,58 @@ message *m_ptr; /* pointer to request message */ { /* Handle sys_sigsend, POSIX-style signal handling. */ - struct sigmsg smsg; - register struct proc *rp; - phys_bytes src_phys, dst_phys; - struct sigcontext sc, *scp; - struct sigframe fr, *frp; - - rp = proc_addr(m_ptr->SIG_PROC); - assert(isuserp(rp)); - - /* Get the sigmsg structure into our address space. */ - src_phys = umap_local(proc_addr(PM_PROC_NR), D, (vir_bytes) - m_ptr->SIG_CTXT_PTR, (vir_bytes) sizeof(struct sigmsg)); - assert(src_phys != 0); - phys_copy(src_phys,vir2phys(&smsg),(phys_bytes) sizeof(struct sigmsg)); - - /* Compute the user stack pointer where sigcontext will be stored. */ - scp = (struct sigcontext *) smsg.sm_stkptr - 1; - - /* Copy the registers to the sigcontext structure. */ - kmemcpy(&sc.sc_regs, &rp->p_reg, sizeof(struct sigregs)); - - /* Finish the sigcontext initialization. */ - sc.sc_flags = SC_SIGCONTEXT; - sc.sc_mask = smsg.sm_mask; - - /* Copy the sigcontext structure to the user's stack. */ - dst_phys = umap_local(rp, D, (vir_bytes) scp, - (vir_bytes) sizeof(struct sigcontext)); - if (dst_phys == 0) return(EFAULT); - phys_copy(vir2phys(&sc), dst_phys, - (phys_bytes) sizeof(struct sigcontext)); - - /* Initialize the sigframe structure. */ - frp = (struct sigframe *) scp - 1; - fr.sf_scpcopy = scp; - fr.sf_retadr2= (void (*)()) rp->p_reg.pc; - fr.sf_fp = rp->p_reg.fp; - rp->p_reg.fp = (reg_t) &frp->sf_fp; - fr.sf_scp = scp; - fr.sf_code = 0; /* XXX - should be used for type of FP exception */ - fr.sf_signo = smsg.sm_signo; - fr.sf_retadr = (void (*)()) smsg.sm_sigreturn; - - /* Copy the sigframe structure to the user's stack. */ - dst_phys = umap_local(rp, D, (vir_bytes) frp, - (vir_bytes) sizeof(struct sigframe)); - if (dst_phys == 0) return(EFAULT); - phys_copy(vir2phys(&fr), dst_phys, - (phys_bytes) sizeof(struct sigframe)); - - /* Reset user registers to execute the signal handler. */ - rp->p_reg.sp = (reg_t) frp; - rp->p_reg.pc = (reg_t) smsg.sm_sighandler; - - return(OK); + struct sigmsg smsg; + register struct proc *rp; + phys_bytes src_phys, dst_phys; + struct sigcontext sc, *scp; + struct sigframe fr, *frp; + + rp = proc_addr(m_ptr->SIG_PROC); + + /* Get the sigmsg structure into our address space. */ + src_phys = umap_local(proc_addr(PM_PROC_NR), D, (vir_bytes) + m_ptr->SIG_CTXT_PTR, (vir_bytes) sizeof(struct sigmsg)); + if (src_phys == 0) return(EFAULT); + phys_copy(src_phys,vir2phys(&smsg),(phys_bytes) sizeof(struct sigmsg)); + + /* Compute the user stack pointer where sigcontext will be stored. */ + scp = (struct sigcontext *) smsg.sm_stkptr - 1; + + /* Copy the registers to the sigcontext structure. */ + kmemcpy(&sc.sc_regs, &rp->p_reg, sizeof(struct sigregs)); + + /* Finish the sigcontext initialization. */ + sc.sc_flags = SC_SIGCONTEXT; + sc.sc_mask = smsg.sm_mask; + + /* Copy the sigcontext structure to the user's stack. */ + dst_phys = umap_local(rp, D, (vir_bytes) scp, + (vir_bytes) sizeof(struct sigcontext)); + if (dst_phys == 0) return(EFAULT); + phys_copy(vir2phys(&sc), dst_phys, (phys_bytes) sizeof(struct sigcontext)); + + /* Initialize the sigframe structure. */ + frp = (struct sigframe *) scp - 1; + fr.sf_scpcopy = scp; + fr.sf_retadr2= (void (*)()) rp->p_reg.pc; + fr.sf_fp = rp->p_reg.fp; + rp->p_reg.fp = (reg_t) &frp->sf_fp; + fr.sf_scp = scp; + fr.sf_code = 0; /* XXX - should be used for type of FP exception */ + fr.sf_signo = smsg.sm_signo; + fr.sf_retadr = (void (*)()) smsg.sm_sigreturn; + + /* Copy the sigframe structure to the user's stack. */ + dst_phys = umap_local(rp, D, (vir_bytes) frp, + (vir_bytes) sizeof(struct sigframe)); + if (dst_phys == 0) return(EFAULT); + phys_copy(vir2phys(&fr), dst_phys, (phys_bytes) sizeof(struct sigframe)); + + /* Reset user registers to execute the signal handler. */ + rp->p_reg.sp = (reg_t) frp; + rp->p_reg.pc = (reg_t) smsg.sm_sighandler; + + return(OK); } PUBLIC int do_sigreturn(m_ptr) @@ -135,54 +131,47 @@ message *m_ptr; /* pointer to request message */ /* POSIX style signals require sys_sigreturn to put things in order before * the signalled process can resume execution */ - struct sigcontext sc; - register struct proc *rp; - phys_bytes src_phys; - - rp = proc_addr(m_ptr->SIG_PROC); - if (! isuserp(rp)) { - kprintf("S_SIGRETURN: message source: %d; ", m_ptr->m_source); - kprintf("got non-user process rp: %d\n", rp->p_nr); - } - assert(isuserp(rp)); - - /* Copy in the sigcontext structure. */ - src_phys = umap_local(rp, D, (vir_bytes) m_ptr->SIG_CTXT_PTR, - (vir_bytes) sizeof(struct sigcontext)); - if (src_phys == 0) return(EFAULT); - phys_copy(src_phys, vir2phys(&sc), - (phys_bytes) sizeof(struct sigcontext)); - - /* Make sure that this is not just a jmp_buf. */ - if ((sc.sc_flags & SC_SIGCONTEXT) == 0) return(EINVAL); - - /* Fix up only certain key registers if the compiler doesn't use - * register variables within functions containing setjmp. - */ - if (sc.sc_flags & SC_NOREGLOCALS) { - rp->p_reg.retreg = sc.sc_retreg; - rp->p_reg.fp = sc.sc_fp; - rp->p_reg.pc = sc.sc_pc; - rp->p_reg.sp = sc.sc_sp; - return(OK); - } - sc.sc_psw = rp->p_reg.psw; + struct sigcontext sc; + register struct proc *rp; + phys_bytes src_phys; + + rp = proc_addr(m_ptr->SIG_PROC); + + /* Copy in the sigcontext structure. */ + src_phys = umap_local(rp, D, (vir_bytes) m_ptr->SIG_CTXT_PTR, + (vir_bytes) sizeof(struct sigcontext)); + if (src_phys == 0) return(EFAULT); + phys_copy(src_phys, vir2phys(&sc), (phys_bytes) sizeof(struct sigcontext)); + + /* Make sure that this is not just a jmp_buf. */ + if ((sc.sc_flags & SC_SIGCONTEXT) == 0) return(EINVAL); + + /* Fix up only certain key registers if the compiler doesn't use + * register variables within functions containing setjmp. + */ + if (sc.sc_flags & SC_NOREGLOCALS) { + rp->p_reg.retreg = sc.sc_retreg; + rp->p_reg.fp = sc.sc_fp; + rp->p_reg.pc = sc.sc_pc; + rp->p_reg.sp = sc.sc_sp; + return(OK); + } + sc.sc_psw = rp->p_reg.psw; #if (CHIP == INTEL) - /* Don't panic kernel if user gave bad selectors. */ - sc.sc_cs = rp->p_reg.cs; - sc.sc_ds = rp->p_reg.ds; - sc.sc_es = rp->p_reg.es; + /* Don't panic kernel if user gave bad selectors. */ + sc.sc_cs = rp->p_reg.cs; + sc.sc_ds = rp->p_reg.ds; + sc.sc_es = rp->p_reg.es; #if _WORD_SIZE == 4 - sc.sc_fs = rp->p_reg.fs; - sc.sc_gs = rp->p_reg.gs; + sc.sc_fs = rp->p_reg.fs; + sc.sc_gs = rp->p_reg.gs; #endif #endif - /* Restore the registers. */ - kmemcpy(&rp->p_reg, (char *)&sc.sc_regs, sizeof(struct sigregs)); - return(OK); - + /* Restore the registers. */ + kmemcpy(&rp->p_reg, (char *)&sc.sc_regs, sizeof(struct sigregs)); + return(OK); } /*===========================================================================* -- 2.44.0