Compare commits

...

17 Commits
main ... R3.1.7

Author SHA1 Message Date
Ben Gras
6d46289843 minor fix to make make bootstrapping work on newer machines. 2010-06-30 14:10:47 +00:00
Ben Gras
4acb68bf9d 3.1.7a 2010-06-29 12:15:00 +00:00
Ben Gras
b7a097ec84 fix dec21140A driver (reported by zvolkov)
(r7578 from trunk)
2010-06-29 12:09:02 +00:00
Ben Gras
57ed4bbb51 MF_REPLY_PEND should be removed when sendrec finishes
(r7565 from trunk)
2010-06-29 12:08:37 +00:00
Ben Gras
cb800f32dc mini_receive() clean up
(r7461 from trunk)
2010-06-29 12:06:29 +00:00
Ben Gras
6b940e1a03 Cycle counters zeroed after fork for the child
(r7365 from trunk)
2010-06-22 23:24:11 +00:00
Ben Gras
673b269068 Fix unlikely race (or crawl?) condition in case going from alarm to ioctl takes more than 1 second
(r7382 from trunk)
2010-06-22 23:23:31 +00:00
Ben Gras
e27fa0d04e Work around vfs/inet/eth race by avoiding non-blocking ioctl in dhcpd
(r7331 from trunk)
2010-06-22 23:22:36 +00:00
Ben Gras
f4499bd4a0 fixes r7363, r7356, r7352 from trunk 2010-06-18 13:54:30 +00:00
Ben Gras
2ec255bb5e fix from trunk: don't re-use mountpoints 2010-06-11 11:43:31 +00:00
Ben Gras
cd445fe22a assert conditions fix from trunk. 2010-06-09 12:56:44 +00:00
Ben Gras
64b1205e6c fix from trunk for assert(ptproc == newptproc) without vm_stop on shutdown. 2010-06-07 22:24:21 +00:00
Ben Gras
94881e6d4a make includes fix from trunk 2010-06-07 15:51:50 +00:00
Ben Gras
6677a8c8e0 mfs fix by tveerman from trunk. 2010-06-07 15:46:26 +00:00
Arun Thomas
255ad2ab37 Remove gcc-4.1.1 from packages list 2010-06-04 12:40:15 +00:00
Ben Gras
7dc782dd1a from trunk:
------------------------------------------------------------------------
r7154 | thruby | 2010-06-04 10:54:43 +0000 (Fri, 04 Jun 2010) | 1 line

Removed a buggy assert unintentionally commted in r7044
2010-06-04 11:06:44 +00:00
Ben Gras
e9eb2c4f8b 3.1.7 branch. 2010-06-03 11:33:56 +00:00
29 changed files with 315 additions and 181 deletions

View File

@ -10,6 +10,7 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <signal.h>
#include <time.h> #include <time.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/asynchio.h> #include <sys/asynchio.h>
@ -92,6 +93,12 @@ void closefd(fd_t *fdp)
} }
} }
static void timeout(int signum)
{
/* nothing to do, ioctl will be aborted automatically */
if (alarm(1) < 0) fatal("alarm(1)");
}
int opendev(network_t *np, fdtype_t fdtype, int compete) int opendev(network_t *np, fdtype_t fdtype, int compete)
{ {
/* Make sure that a network has the proper device open and configured. /* Make sure that a network has the proper device open and configured.
@ -169,14 +176,19 @@ int opendev(network_t *np, fdtype_t fdtype, int compete)
switch (fdtype) { switch (fdtype) {
case FT_ETHERNET: case FT_ETHERNET:
/* Set NONBLOCK to avoid waiting for a device driver to become ready */ /* Cannot use NWIOGETHSTAT in non-blocking mode due to a race between
fcntl(np->fdp->fd, F_SETFL, fcntl(np->fdp->fd, F_GETFL) | O_NONBLOCK); * the reply from the ethernet driver and the cancel message from VFS
* for reaching inet. Hence, a signal is used to interrupt NWIOGETHSTAT
* in case the driver isn't ready yet.
*/
if (signal(SIGALRM, timeout) == SIG_ERR) fatal("signal(SIGALRM)");
if (alarm(1) < 0) fatal("alarm(1)");
if (ioctl(np->fdp->fd, NWIOGETHSTAT, &ethstat) < 0) { if (ioctl(np->fdp->fd, NWIOGETHSTAT, &ethstat) < 0) {
/* Not an Ethernet. */ /* Not an Ethernet. */
close(fdp->fd); close(fdp->fd);
return 0; return 0;
} }
fcntl(np->fdp->fd, F_SETFL, fcntl(np->fdp->fd, F_GETFL) & ~O_NONBLOCK); if (alarm(0) < 0) fatal("alarm(0)");
np->eth= ethstat.nwes_addr; np->eth= ethstat.nwes_addr;
ethopt.nweo_flags= NWEO_COPY | NWEO_EN_LOC | NWEO_EN_BROAD ethopt.nweo_flags= NWEO_COPY | NWEO_EN_LOC | NWEO_EN_BROAD
| NWEO_REMANY | NWEO_TYPEANY | NWEO_RWDATALL; | NWEO_REMANY | NWEO_TYPEANY | NWEO_RWDATALL;

View File

@ -267,7 +267,7 @@ PRIVATE void do_reply(dpeth_t * dep)
if (dep->de_flags & DEF_ACK_RECV) flags |= DL_PACK_RECV; if (dep->de_flags & DEF_ACK_RECV) flags |= DL_PACK_RECV;
reply.m_type = DL_TASK_REPLY; reply.m_type = DL_TASK_REPLY;
reply.DL_STAT = flags; reply.DL_FLAGS = flags;
reply.DL_COUNT = dep->de_read_s; reply.DL_COUNT = dep->de_read_s;
r = send(dep->de_client, &reply); r = send(dep->de_client, &reply);

View File

@ -3,7 +3,7 @@
/* Minix release and version numbers. */ /* Minix release and version numbers. */
#define OS_RELEASE "3" #define OS_RELEASE "3"
#define OS_VERSION "1.7" #define OS_VERSION "1.7a"
/* This file sets configuration parameters for the MINIX kernel, FS, and PM. /* This file sets configuration parameters for the MINIX kernel, FS, and PM.
* It is divided up into two main sections. The first section contains * It is divided up into two main sections. The first section contains

View File

@ -150,7 +150,7 @@
/* Some limits. */ /* Some limits. */
#define MAX_INODE_NR ((ino_t) 037777777777) /* largest inode number */ #define MAX_INODE_NR ((ino_t) 037777777777) /* largest inode number */
#define MAX_FILE_POS ((off_t) 0x7FFFFFFF) /* largest legal file offset */ #define MAX_FILE_POS ((off_t) 0x7FFFFFFF) /* largest legal file offset */
#define UMAX_FILE_POS ((unsigned) 0x7FFFFFF) /* largest legal file offset */ #define UMAX_FILE_POS ((unsigned) 0x7FFFFFFF) /* largest legal file offset */
#define MAX_SYM_LOOPS 8 /* how many symbolic links are recursed */ #define MAX_SYM_LOOPS 8 /* how many symbolic links are recursed */

View File

@ -11,6 +11,10 @@
#include <minix/cpufeature.h> #include <minix/cpufeature.h>
#include <a.out.h> #include <a.out.h>
#include <assert.h> #include <assert.h>
#include <signal.h>
#include <machine/vm.h>
#include <sys/sigcontext.h>
#include "archconst.h" #include "archconst.h"
#include "proto.h" #include "proto.h"
@ -23,6 +27,9 @@
#include "apic.h" #include "apic.h"
#endif #endif
PRIVATE int osfxsr_feature; /* FXSAVE/FXRSTOR instructions support (SSEx) */
/* set MP and NE flags to handle FPU exceptions in native mode. */ /* set MP and NE flags to handle FPU exceptions in native mode. */
#define CR0_MP_NE 0x0022 #define CR0_MP_NE 0x0022
/* set CR4.OSFXSR[bit 9] if FXSR is supported. */ /* set CR4.OSFXSR[bit 9] if FXSR is supported. */
@ -194,6 +201,59 @@ PRIVATE void fpu_init(void)
} }
} }
PUBLIC void save_fpu(struct proc *pr)
{
if(!fpu_presence)
return;
/* If the process hasn't touched the FPU, there is nothing to do. */
if(!(pr->p_misc_flags & MF_USED_FPU))
return;
/* Save changed FPU context. */
if(osfxsr_feature) {
fxsave(pr->p_fpu_state.fpu_save_area_p);
fninit();
} else {
fnsave(pr->p_fpu_state.fpu_save_area_p);
}
/* Clear MF_USED_FPU to signal there is no unsaved FPU state. */
pr->p_misc_flags &= ~MF_USED_FPU;
}
PUBLIC void restore_fpu(struct proc *pr)
{
/* If the process hasn't touched the FPU, enable the FPU exception
* and don't restore anything.
*/
if(!(pr->p_misc_flags & MF_USED_FPU)) {
write_cr0(read_cr0() | I386_CR0_TS);
return;
}
/* If the process has touched the FPU, disable the FPU
* exception (both for the kernel and for the process once
* it's scheduled), and initialize or restore the FPU state.
*/
clts();
if(!(pr->p_misc_flags & MF_FPU_INITIALIZED)) {
fninit();
pr->p_misc_flags |= MF_FPU_INITIALIZED;
} else {
if(osfxsr_feature) {
fxrstor(pr->p_fpu_state.fpu_save_area_p);
} else {
frstor(pr->p_fpu_state.fpu_save_area_p);
}
}
}
PUBLIC void arch_init(void) PUBLIC void arch_init(void)
{ {
#ifdef CONFIG_APIC #ifdef CONFIG_APIC
@ -438,3 +498,36 @@ PUBLIC struct proc * arch_finish_switch_to_user(void)
*((reg_t *)stk) = (reg_t) proc_ptr; *((reg_t *)stk) = (reg_t) proc_ptr;
return proc_ptr; return proc_ptr;
} }
PUBLIC void fpu_sigcontext(struct proc *pr, struct sigframe *fr, struct sigcontext *sc)
{
int fp_error;
if (osfxsr_feature) {
fp_error = sc->sc_fpu_state.xfp_regs.fp_status &
~sc->sc_fpu_state.xfp_regs.fp_control;
} else {
fp_error = sc->sc_fpu_state.fpu_regs.fp_status &
~sc->sc_fpu_state.fpu_regs.fp_control;
}
if (fp_error & 0x001) { /* Invalid op */
/*
* swd & 0x240 == 0x040: Stack Underflow
* swd & 0x240 == 0x240: Stack Overflow
* User must clear the SF bit (0x40) if set
*/
fr->sf_code = FPE_FLTINV;
} else if (fp_error & 0x004) {
fr->sf_code = FPE_FLTDIV; /* Divide by Zero */
} else if (fp_error & 0x008) {
fr->sf_code = FPE_FLTOVF; /* Overflow */
} else if (fp_error & 0x012) {
fr->sf_code = FPE_FLTUND; /* Denormal, Underflow */
} else if (fp_error & 0x020) {
fr->sf_code = FPE_FLTRES; /* Precision */
} else {
fr->sf_code = 0; /* XXX - probably should be used for FPE_INTOVF or
* FPE_INTDIV */
}
}

View File

@ -38,6 +38,7 @@
.globl _getcr3val .globl _getcr3val
.globl _write_cr0 /* write a value in cr0 */ .globl _write_cr0 /* write a value in cr0 */
.globl _read_cr3 .globl _read_cr3
.globl _write_cr3
.globl _read_cr4 .globl _read_cr4
.globl _write_cr4 .globl _write_cr4
@ -50,6 +51,11 @@
.globl _fninit /* non-waiting FPU initialization */ .globl _fninit /* non-waiting FPU initialization */
.globl _fnstsw /* store status word (non-waiting) */ .globl _fnstsw /* store status word (non-waiting) */
.globl _fnstcw /* store control word (non-waiting) */ .globl _fnstcw /* store control word (non-waiting) */
.globl _fxsave
.globl _fnsave
.globl _fxrstor
.globl _frstor
.globl _clts
/* /*
* The routines only guarantee to preserve the registers the C compiler * The routines only guarantee to preserve the registers the C compiler
@ -655,6 +661,10 @@ _fninit:
fninit fninit
ret ret
_clts:
clts
ret
_fnstsw: _fnstsw:
xor %eax, %eax xor %eax, %eax
@ -671,6 +681,40 @@ _fnstcw:
pop %eax pop %eax
ret ret
/*===========================================================================*/
/* fxsave */
/*===========================================================================*/
_fxsave:
mov 4(%esp), %eax
fxsave (%eax) /* Do not change the operand! (gas2ack) */
ret
/*===========================================================================*/
/* fnsave */
/*===========================================================================*/
_fnsave:
mov 4(%esp), %eax
fnsave (%eax) /* Do not change the operand! (gas2ack) */
fwait /* required for compatibility with processors prior pentium */
ret
/*===========================================================================*/
/* fxrstor */
/*===========================================================================*/
_fxrstor:
mov 4(%esp), %eax
fxrstor (%eax) /* Do not change the operand! (gas2ack) */
ret
/*===========================================================================*/
/* frstor */
/*===========================================================================*/
_frstor:
mov 4(%esp), %eax
frstor (%eax) /* Do not change the operand! (gas2ack) */
ret
/*===========================================================================*/ /*===========================================================================*/
/* read_cr0 */ /* read_cr0 */
/*===========================================================================*/ /*===========================================================================*/
@ -745,6 +789,22 @@ _write_cr4:
0: 0:
pop %ebp pop %ebp
ret ret
/*===========================================================================*/
/* write_cr3 */
/*===========================================================================*/
/* PUBLIC void write_cr3(unsigned long value); */
_write_cr3:
push %ebp
mov %esp, %ebp
mov 8(%ebp), %eax
/* DO NOT CHANGE THE OPERAND!!! gas2ack does not handle it yet */
mov %eax, %cr3
pop %ebp
ret
/*===========================================================================*/ /*===========================================================================*/
/* getcr3val */ /* getcr3val */
/*===========================================================================*/ /*===========================================================================*/
@ -847,3 +907,4 @@ _switch_address_space:
mov %edx, _ptproc mov %edx, _ptproc
0: 0:
ret ret

View File

@ -45,11 +45,25 @@ PUBLIC void vm_init(struct proc *newptproc)
{ {
if(vm_running) if(vm_running)
panic("vm_init: vm_running"); panic("vm_init: vm_running");
/* switch_address_space() checks what is in cr3, and doesn't do
* anything if it's the same as the cr3 of its argument, newptproc.
* If MINIX was previously booted, this could very well be the case.
*
* The first time switch_address_space() is called, we want to
* force it to do something (load cr3 and set newptproc), so we
* zero cr3, and force paging off to make that a safe thing to do.
*
* After that, vm_enable_paging() enables paging with the page table
* of newptproc loaded.
*/
vm_stop();
write_cr3(0);
switch_address_space(newptproc); switch_address_space(newptproc);
assert(ptproc == newptproc); assert(ptproc == newptproc);
vm_enable_paging(); vm_enable_paging();
vm_running = 1; vm_running = 1;
} }
/* This function sets up a mapping from within the kernel's address /* This function sets up a mapping from within the kernel's address
@ -254,6 +268,11 @@ PRIVATE char *cr4_str(u32_t e)
return str; return str;
} }
PUBLIC void vm_stop(void)
{
write_cr0(read_cr0() & ~I386_CR0_PG);
}
PRIVATE void vm_enable_paging(void) PRIVATE void vm_enable_paging(void)
{ {
u32_t cr0, cr4; u32_t cr0, cr4;
@ -813,7 +832,7 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
if((r=lin_lin_copy(procs[_SRC_], phys_addr[_SRC_], if((r=lin_lin_copy(procs[_SRC_], phys_addr[_SRC_],
procs[_DST_], phys_addr[_DST_], bytes)) != OK) { procs[_DST_], phys_addr[_DST_], bytes)) != OK) {
struct proc *target; struct proc *target = NULL;
phys_bytes lin; phys_bytes lin;
if(r != EFAULT_SRC && r != EFAULT_DST) if(r != EFAULT_SRC && r != EFAULT_DST)
panic("lin_lin_copy failed: %d", r); panic("lin_lin_copy failed: %d", r);
@ -821,8 +840,6 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
return r; return r;
} }
assert(procs[_SRC_] && procs[_DST_]);
if(r == EFAULT_SRC) { if(r == EFAULT_SRC) {
lin = phys_addr[_SRC_]; lin = phys_addr[_SRC_];
target = procs[_SRC_]; target = procs[_SRC_];
@ -833,6 +850,9 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
panic("r strange: %d", r); panic("r strange: %d", r);
} }
assert(caller);
assert(target);
vm_suspend(caller, target, lin, bytes, VMSTYPE_KERNELCALL); vm_suspend(caller, target, lin, bytes, VMSTYPE_KERNELCALL);
return VMSUSPEND; return VMSUSPEND;
} }

View File

@ -90,7 +90,7 @@ begbss:
.globl _params_offset .globl _params_offset
.globl _mon_ds .globl _mon_ds
.globl _switch_to_user .globl _switch_to_user
.globl _lazy_fpu .globl _save_fpu
.globl _hwint00 /* handlers for hardware interrupts */ .globl _hwint00 /* handlers for hardware interrupts */
.globl _hwint01 .globl _hwint01
@ -589,33 +589,16 @@ _inval_opcode:
_copr_not_available: _copr_not_available:
TEST_INT_IN_KERNEL(4, copr_not_available_in_kernel) TEST_INT_IN_KERNEL(4, copr_not_available_in_kernel)
clts
cld /* set direction flag to a known value */ cld /* set direction flag to a known value */
SAVE_PROCESS_CTX_NON_LAZY(0) SAVE_PROCESS_CTX_NON_LAZY(0)
/* stop user process cycles */ /* stop user process cycles */
push %ebp push %ebp
mov $0, %ebp
call _context_stop call _context_stop
pop %ebp pop %ebp
lea P_MISC_FLAGS(%ebp), %ebx lea P_MISC_FLAGS(%ebp), %ebx
movw (%ebx), %cx orw $MF_USED_FPU, (%ebx)
and $MF_FPU_INITIALIZED, %cx mov $0, %ebp
jnz 0f /* jump if FPU is already initialized */
orw $MF_FPU_INITIALIZED, (%ebx)
fninit
jmp copr_return
0: /* load FPU context for current process */
mov %ss:FP_SAVE_AREA_P(%ebp), %eax
cmp $0, _osfxsr_feature
jz fp_l_no_fxsr /* FXSR is not avaible. */
/* DO NOT CHANGE THE OPERAND!!! gas2ack does not handle it yet */
fxrstor (%eax)
jmp copr_return
fp_l_no_fxsr:
/* DO NOT CHANGE THE OPERAND!!! gas2ack does not handle it yet */
frstor (%eax)
copr_return:
orw $MF_USED_FPU, (%ebx) /* fpu was used during last execution */
jmp _switch_to_user jmp _switch_to_user
copr_not_available_in_kernel: copr_not_available_in_kernel:
@ -656,51 +639,6 @@ _machine_check:
_simd_exception: _simd_exception:
EXCEPTION_NO_ERR_CODE(SIMD_EXCEPTION_VECTOR) EXCEPTION_NO_ERR_CODE(SIMD_EXCEPTION_VECTOR)
/*===========================================================================*/
/* lazy_fpu */
/*===========================================================================*/
/* void lazy_fpu(struct proc *pptr)
* It's called, when we are on kernel stack.
* Actualy lazy code is just few lines, which check MF_USED_FPU,
* another part is save_init_fpu().
*/
_lazy_fpu:
push %ebp
mov %esp, %ebp
push %eax
push %ebx
push %ecx
cmp $0, _fpu_presence /* Do we have FPU? */
jz no_fpu_available
mov 8(%ebp), %eax /* Get pptr */
lea P_MISC_FLAGS(%eax), %ebx
movw (%ebx), %cx
and $MF_USED_FPU, %cx
jz 0f /* Don't save FPU */
mov %ss:FP_SAVE_AREA_P(%eax), %eax
cmp $0, _osfxsr_feature
jz fp_s_no_fxsr /* FXSR is not avaible. */
/* DO NOT CHANGE THE OPERAND!!! gas2ack does not handle it yet */
fxsave (%eax)
fninit
jmp fp_saved
fp_s_no_fxsr:
/* DO NOT CHANGE THE OPERAND!!! gas2ack does not handle it yet */
fnsave (%eax)
fwait /* required for compatibility with processors prior pentium */
fp_saved:
andw $~MF_USED_FPU, (%ebx)
0: mov %cr0, %eax
or $0x00000008, %eax /* Set TS flag */
mov %eax, %cr0
no_fpu_available:
pop %ecx
pop %ebx
pop %eax
pop %ebp
ret
/*===========================================================================*/ /*===========================================================================*/
/* reload_cr3 */ /* reload_cr3 */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -74,6 +74,7 @@ _PROTOTYPE( reg_t read_cr2, (void) );
_PROTOTYPE( void write_cr0, (unsigned long value) ); _PROTOTYPE( void write_cr0, (unsigned long value) );
_PROTOTYPE( unsigned long read_cr4, (void) ); _PROTOTYPE( unsigned long read_cr4, (void) );
_PROTOTYPE( void write_cr4, (unsigned long value) ); _PROTOTYPE( void write_cr4, (unsigned long value) );
_PROTOTYPE( void write_cr3, (unsigned long value) );
_PROTOTYPE( unsigned long read_cpu_flags, (void) ); _PROTOTYPE( unsigned long read_cpu_flags, (void) );
_PROTOTYPE( void phys_insb, (u16_t port, phys_bytes buf, size_t count) ); _PROTOTYPE( void phys_insb, (u16_t port, phys_bytes buf, size_t count) );
_PROTOTYPE( void phys_insw, (u16_t port, phys_bytes buf, size_t count) ); _PROTOTYPE( void phys_insw, (u16_t port, phys_bytes buf, size_t count) );
@ -86,6 +87,11 @@ _PROTOTYPE( void reload_ds, (void) );
_PROTOTYPE( void ia32_msr_read, (u32_t reg, u32_t * hi, u32_t * lo) ); _PROTOTYPE( void ia32_msr_read, (u32_t reg, u32_t * hi, u32_t * lo) );
_PROTOTYPE( void ia32_msr_write, (u32_t reg, u32_t hi, u32_t lo) ); _PROTOTYPE( void ia32_msr_write, (u32_t reg, u32_t hi, u32_t lo) );
_PROTOTYPE( void fninit, (void)); _PROTOTYPE( void fninit, (void));
_PROTOTYPE( void clts, (void));
_PROTOTYPE( void fxsave, (void *));
_PROTOTYPE( void fnsave, (void *));
_PROTOTYPE( void fxrstor, (void *));
_PROTOTYPE( void frstor, (void *));
_PROTOTYPE( unsigned short fnstsw, (void)); _PROTOTYPE( unsigned short fnstsw, (void));
_PROTOTYPE( void fnstcw, (unsigned short* cw)); _PROTOTYPE( void fnstcw, (unsigned short* cw));

View File

@ -141,9 +141,17 @@
#define SAVE_PROCESS_CTX(displ) \ #define SAVE_PROCESS_CTX(displ) \
SAVE_PROCESS_CTX_NON_LAZY(displ) ;\ SAVE_PROCESS_CTX_NON_LAZY(displ) ;\
push %eax ;\
push %ebx ;\
push %ecx ;\
push %edx ;\
push %ebp ;\ push %ebp ;\
call _lazy_fpu ;\ call _save_fpu ;\
add $4, %esp ; pop %ebp ;\
pop %edx ;\
pop %ecx ;\
pop %ebx ;\
pop %eax ;
/* /*
* clear the IF flag in eflags which are stored somewhere in memory, e.g. on * clear the IF flag in eflags which are stored somewhere in memory, e.g. on

View File

@ -45,7 +45,6 @@ EXTERN time_t boottime;
EXTERN char params_buffer[512]; /* boot monitor parameters */ EXTERN char params_buffer[512]; /* boot monitor parameters */
EXTERN int minix_panicing; EXTERN int minix_panicing;
EXTERN char fpu_presence; EXTERN char fpu_presence;
EXTERN char osfxsr_feature; /* FXSAVE/FXRSTOR instructions support (SSEx) */
EXTERN int verboseboot; /* verbose boot, init'ed in cstart */ EXTERN int verboseboot; /* verbose boot, init'ed in cstart */
#define MAGICTEST 0xC0FFEE23 #define MAGICTEST 0xC0FFEE23
EXTERN u32_t magictest; /* global magic number */ EXTERN u32_t magictest; /* global magic number */

View File

@ -241,6 +241,7 @@ check_misc_flags:
* restore_user_context() carries out the actual mode switch from kernel * restore_user_context() carries out the actual mode switch from kernel
* to userspace. This function does not return * to userspace. This function does not return
*/ */
restore_fpu(proc_ptr);
restore_user_context(proc_ptr); restore_user_context(proc_ptr);
NOT_REACHABLE; NOT_REACHABLE;
} }
@ -560,6 +561,10 @@ PUBLIC int mini_send(
call = (caller_ptr->p_misc_flags & MF_REPLY_PEND ? SENDREC call = (caller_ptr->p_misc_flags & MF_REPLY_PEND ? SENDREC
: (flags & NON_BLOCKING ? SENDNB : SEND)); : (flags & NON_BLOCKING ? SENDNB : SEND));
IPC_STATUS_ADD_CALL(dst_ptr, call); IPC_STATUS_ADD_CALL(dst_ptr, call);
if (dst_ptr->p_misc_flags & MF_REPLY_PEND)
dst_ptr->p_misc_flags &= ~MF_REPLY_PEND;
RTS_UNSET(dst_ptr, RTS_RECEIVING); RTS_UNSET(dst_ptr, RTS_RECEIVING);
} else { } else {
if(flags & NON_BLOCKING) { if(flags & NON_BLOCKING) {
@ -589,10 +594,10 @@ PUBLIC int mini_send(
caller_ptr->p_sendto_e = dst_e; caller_ptr->p_sendto_e = dst_e;
/* Process is now blocked. Put in on the destination's queue. */ /* Process is now blocked. Put in on the destination's queue. */
assert(caller_ptr->p_q_link == NULL);
xpp = &dst_ptr->p_caller_q; /* find end of list */ xpp = &dst_ptr->p_caller_q; /* find end of list */
while (*xpp) xpp = &(*xpp)->p_q_link; while (*xpp) xpp = &(*xpp)->p_q_link;
*xpp = caller_ptr; /* add caller to end */ *xpp = caller_ptr; /* add caller to end */
caller_ptr->p_q_link = NULL; /* mark new end of list */
} }
return(OK); return(OK);
} }
@ -678,7 +683,7 @@ PRIVATE int mini_receive(
IPC_STATUS_ADD_CALL(caller_ptr, NOTIFY); IPC_STATUS_ADD_CALL(caller_ptr, NOTIFY);
return(OK); goto receive_done;
} }
} }
@ -692,44 +697,47 @@ PRIVATE int mini_receive(
if (r == OK) { if (r == OK) {
IPC_STATUS_ADD_CALL(caller_ptr, SENDA); IPC_STATUS_ADD_CALL(caller_ptr, SENDA);
return OK; /* Got a message */ goto receive_done;
} }
} }
/* Check caller queue. Use pointer pointers to keep code simple. */ /* Check caller queue. Use pointer pointers to keep code simple. */
xpp = &caller_ptr->p_caller_q; xpp = &caller_ptr->p_caller_q;
while (*xpp) { while (*xpp) {
if (src_e == ANY || src_p == proc_nr(*xpp)) { struct proc * sender = *xpp;
if (src_e == ANY || src_p == proc_nr(sender)) {
int call; int call;
assert(!RTS_ISSET(*xpp, RTS_SLOT_FREE)); assert(!RTS_ISSET(sender, RTS_SLOT_FREE));
assert(!RTS_ISSET(*xpp, RTS_NO_ENDPOINT)); assert(!RTS_ISSET(sender, RTS_NO_ENDPOINT));
/* Found acceptable message. Copy it and update status. */ /* Found acceptable message. Copy it and update status. */
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG)); assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
caller_ptr->p_delivermsg = (*xpp)->p_sendmsg; caller_ptr->p_delivermsg = sender->p_sendmsg;
caller_ptr->p_delivermsg.m_source = (*xpp)->p_endpoint; caller_ptr->p_delivermsg.m_source = sender->p_endpoint;
caller_ptr->p_misc_flags |= MF_DELIVERMSG; caller_ptr->p_misc_flags |= MF_DELIVERMSG;
RTS_UNSET(*xpp, RTS_SENDING); RTS_UNSET(sender, RTS_SENDING);
call = ((*xpp)->p_misc_flags & MF_REPLY_PEND ? SENDREC : SEND); call = (sender->p_misc_flags & MF_REPLY_PEND ? SENDREC : SEND);
IPC_STATUS_ADD_CALL(caller_ptr, call); IPC_STATUS_ADD_CALL(caller_ptr, call);
/* /*
* if the message is originaly from the kernel on behalf of this * if the message is originaly from the kernel on behalf of this
* process, we must send the status flags accordingly * process, we must send the status flags accordingly
*/ */
if ((*xpp)->p_misc_flags & MF_SENDING_FROM_KERNEL) { if (sender->p_misc_flags & MF_SENDING_FROM_KERNEL) {
IPC_STATUS_ADD_FLAGS(caller_ptr, IPC_FLG_MSG_FROM_KERNEL); IPC_STATUS_ADD_FLAGS(caller_ptr, IPC_FLG_MSG_FROM_KERNEL);
/* we can clean the flag now, not need anymore */ /* we can clean the flag now, not need anymore */
(*xpp)->p_misc_flags &= ~MF_SENDING_FROM_KERNEL; sender->p_misc_flags &= ~MF_SENDING_FROM_KERNEL;
} }
if ((*xpp)->p_misc_flags & MF_SIG_DELAY) if (sender->p_misc_flags & MF_SIG_DELAY)
sig_delay_done(*xpp); sig_delay_done(sender);
*xpp = (*xpp)->p_q_link; /* remove from queue */ *xpp = sender->p_q_link; /* remove from queue */
return(OK); /* report success */ sender->p_q_link = NULL;
goto receive_done;
} }
xpp = &(*xpp)->p_q_link; /* proceed to next */ xpp = &sender->p_q_link; /* proceed to next */
} }
} }
@ -748,6 +756,11 @@ PRIVATE int mini_receive(
} else { } else {
return(ENOTREADY); return(ENOTREADY);
} }
receive_done:
if (caller_ptr->p_misc_flags & MF_REPLY_PEND)
caller_ptr->p_misc_flags &= ~MF_REPLY_PEND;
return OK;
} }
/*===========================================================================* /*===========================================================================*

View File

@ -146,6 +146,7 @@ struct proc {
#define proc_is_preempted(p) ((p)->p_rts_flags & RTS_PREEMPTED) #define proc_is_preempted(p) ((p)->p_rts_flags & RTS_PREEMPTED)
#define proc_no_quantum(p) ((p)->p_rts_flags & RTS_NO_QUANTUM) #define proc_no_quantum(p) ((p)->p_rts_flags & RTS_NO_QUANTUM)
#define proc_ptr_ok(p) ((p)->p_magic == PMAGIC) #define proc_ptr_ok(p) ((p)->p_magic == PMAGIC)
#define proc_used_fpu(p) ((p)->p_misc_flags & (MF_FPU_INITIALIZED|MF_USED_FPU))
/* test whether the process is scheduled by the kernel's default policy */ /* test whether the process is scheduled by the kernel's default policy */
#define proc_kernel_scheduler(p) ((p)->p_scheduler == NULL || \ #define proc_kernel_scheduler(p) ((p)->p_scheduler == NULL || \

View File

@ -5,6 +5,7 @@
#include <minix/safecopies.h> #include <minix/safecopies.h>
#include <machine/archtypes.h> #include <machine/archtypes.h>
#include <sys/sigcontext.h>
#include <a.out.h> #include <a.out.h>
/* Struct declarations. */ /* Struct declarations. */
@ -28,6 +29,9 @@ _PROTOTYPE( void cycles_accounting_init, (void) );
_PROTOTYPE( void context_stop, (struct proc * p) ); _PROTOTYPE( void context_stop, (struct proc * p) );
/* this is a wrapper to make calling it from assembly easier */ /* this is a wrapper to make calling it from assembly easier */
_PROTOTYPE( void context_stop_idle, (void) ); _PROTOTYPE( void context_stop_idle, (void) );
_PROTOTYPE( void restore_fpu, (struct proc *) );
_PROTOTYPE( void save_fpu, (struct proc *) );
_PROTOTYPE( void fpu_sigcontext, (struct proc *, struct sigframe *fr, struct sigcontext *sc) );
/* main.c */ /* main.c */
_PROTOTYPE( void main, (void) ); _PROTOTYPE( void main, (void) );
@ -138,6 +142,7 @@ _PROTOTYPE( int data_copy_vmcheck, (struct proc *,
endpoint_t to, vir_bytes to_addr, size_t bytes)); endpoint_t to, vir_bytes to_addr, size_t bytes));
_PROTOTYPE( void alloc_segments, (struct proc *rp) ); _PROTOTYPE( void alloc_segments, (struct proc *rp) );
_PROTOTYPE( void vm_init, (struct proc *first) ); _PROTOTYPE( void vm_init, (struct proc *first) );
_PROTOTYPE( void vm_stop, (void) );
_PROTOTYPE( phys_bytes umap_local, (register struct proc *rp, int seg, _PROTOTYPE( phys_bytes umap_local, (register struct proc *rp, int seg,
vir_bytes vir_addr, vir_bytes bytes)); vir_bytes vir_addr, vir_bytes bytes));
_PROTOTYPE( phys_bytes umap_remote, (const struct proc* rp, int seg, _PROTOTYPE( phys_bytes umap_remote, (const struct proc* rp, int seg,

View File

@ -15,6 +15,7 @@
#include <assert.h> #include <assert.h>
#include <minix/endpoint.h> #include <minix/endpoint.h>
#include <minix/u64.h>
#if USE_FORK #if USE_FORK
@ -89,6 +90,9 @@ PUBLIC int do_fork(struct proc * caller, message * m_ptr)
if (rpc->p_scheduler) if (rpc->p_scheduler)
RTS_SET(rpc, RTS_NO_QUANTUM); RTS_SET(rpc, RTS_NO_QUANTUM);
make_zero64(rpc->p_cpu_time_left);
make_zero64(rpc->p_cycles);
/* If the parent is a privileged process, take away the privileges from the /* If the parent is a privileged process, take away the privileges from the
* child process and inhibit it from running by setting the NO_PRIV flag. * child process and inhibit it from running by setting the NO_PRIV flag.
* The caller should explicitely set the new privileges before executing. * The caller should explicitely set the new privileges before executing.

View File

@ -50,7 +50,6 @@ PUBLIC int do_setalarm(struct proc * caller, message * m_ptr)
reset_timer(tp); reset_timer(tp);
} else { } else {
tp->tmr_exp_time = (use_abs_time) ? exp_time : exp_time + get_uptime(); tp->tmr_exp_time = (use_abs_time) ? exp_time : exp_time + get_uptime();
assert(tp->tmr_exp_time > get_uptime());
set_timer(tp, tp->tmr_exp_time, tp->tmr_func); set_timer(tp, tp->tmr_exp_time, tp->tmr_func);
} }
return(OK); return(OK);

View File

@ -27,9 +27,6 @@ PUBLIC int do_sigsend(struct proc * caller, message * m_ptr)
struct sigcontext sc, *scp; struct sigcontext sc, *scp;
struct sigframe fr, *frp; struct sigframe fr, *frp;
int proc_nr, r; int proc_nr, r;
#if (_MINIX_CHIP == _CHIP_INTEL)
unsigned short int fp_error;
#endif
if (!isokendpt(m_ptr->SIG_ENDPT, &proc_nr)) return(EINVAL); if (!isokendpt(m_ptr->SIG_ENDPT, &proc_nr)) return(EINVAL);
if (iskerneln(proc_nr)) return(EPERM); if (iskerneln(proc_nr)) return(EPERM);
@ -69,38 +66,7 @@ PUBLIC int do_sigsend(struct proc * caller, message * m_ptr)
rp->p_reg.fp = (reg_t) &frp->sf_fp; rp->p_reg.fp = (reg_t) &frp->sf_fp;
fr.sf_scp = scp; fr.sf_scp = scp;
#if (_MINIX_CHIP == _CHIP_INTEL) fpu_sigcontext(rp, &fr, &sc);
if (osfxsr_feature == 1) {
fp_error = sc.sc_fpu_state.xfp_regs.fp_status &
~sc.sc_fpu_state.xfp_regs.fp_control;
} else {
fp_error = sc.sc_fpu_state.fpu_regs.fp_status &
~sc.sc_fpu_state.fpu_regs.fp_control;
}
if (fp_error & 0x001) { /* Invalid op */
/*
* swd & 0x240 == 0x040: Stack Underflow
* swd & 0x240 == 0x240: Stack Overflow
* User must clear the SF bit (0x40) if set
*/
fr.sf_code = FPE_FLTINV;
} else if (fp_error & 0x004) {
fr.sf_code = FPE_FLTDIV; /* Divide by Zero */
} else if (fp_error & 0x008) {
fr.sf_code = FPE_FLTOVF; /* Overflow */
} else if (fp_error & 0x012) {
fr.sf_code = FPE_FLTUND; /* Denormal, Underflow */
} else if (fp_error & 0x020) {
fr.sf_code = FPE_FLTRES; /* Precision */
} else {
fr.sf_code = 0; /* XXX - probably should be used for FPE_INTOVF or
* FPE_INTDIV */
}
#else
fr.sf_code = 0;
#endif
fr.sf_signo = smsg.sm_signo; fr.sf_signo = smsg.sm_signo;
fr.sf_retadr = (void (*)()) smsg.sm_sigreturn; fr.sf_retadr = (void (*)()) smsg.sm_sigreturn;

View File

@ -226,7 +226,11 @@ register struct inode *rip; /* pointer to inode to be released */
if (rip->i_nlinks == NO_LINK) { if (rip->i_nlinks == NO_LINK) {
/* i_nlinks == NO_LINK means free the inode. */ /* i_nlinks == NO_LINK means free the inode. */
/* return all the disk blocks */ /* return all the disk blocks */
if (truncate_inode(rip, (off_t) 0) != OK) return;
/* Ignore errors by truncate_inode in case inode is a block
* special or character special file.
*/
(void) truncate_inode(rip, (off_t) 0);
rip->i_mode = I_NOT_ALLOC; /* clear I_TYPE field */ rip->i_mode = I_NOT_ALLOC; /* clear I_TYPE field */
rip->i_dirt = DIRTY; rip->i_dirt = DIRTY;
free_inode(rip->i_dev, rip->i_num); free_inode(rip->i_dev, rip->i_num);
@ -257,8 +261,9 @@ PUBLIC struct inode *alloc_inode(dev_t dev, mode_t bits)
register struct inode *rip; register struct inode *rip;
register struct super_block *sp; register struct super_block *sp;
int major, minor, inumb; int major, minor;
bit_t b; bit_t b;
ino_t inumb;
sp = get_super(dev); /* get pointer to super_block */ sp = get_super(dev); /* get pointer to super_block */
if (sp->s_rd_only) { /* can't allocate an inode on a read only device. */ if (sp->s_rd_only) { /* can't allocate an inode on a read only device. */
@ -276,7 +281,7 @@ PUBLIC struct inode *alloc_inode(dev_t dev, mode_t bits)
return(NULL); return(NULL);
} }
sp->s_isearch = b; /* next time start here */ sp->s_isearch = b; /* next time start here */
inumb = (int) b; /* be careful not to pass unshort as param */ inumb = (ino_t) b; /* be careful not to pass unshort as param */
/* Try to acquire a slot in the inode table. */ /* Try to acquire a slot in the inode table. */
if ((rip = get_inode(NO_DEV, inumb)) == NULL) { if ((rip = get_inode(NO_DEV, inumb)) == NULL) {
@ -339,7 +344,7 @@ PRIVATE void free_inode(
/* Locate the appropriate super_block. */ /* Locate the appropriate super_block. */
sp = get_super(dev); sp = get_super(dev);
if (inumb > sp->s_ninodes) return; if (inumb == 0 || inumb > sp->s_ninodes) return;
b = (bit_t) inumb; b = (bit_t) inumb;
free_bit(sp, IMAP, b); free_bit(sp, IMAP, b);
if (b < sp->s_isearch) sp->s_isearch = b; if (b < sp->s_isearch) sp->s_isearch = b;

View File

@ -245,14 +245,14 @@ char file_name[NAME_MAX]; /* name of file to be removed */
{ {
/* Unlink 'file_name'; rip must be the inode of 'file_name' or NULL. */ /* Unlink 'file_name'; rip must be the inode of 'file_name' or NULL. */
ino_t numb; /* inode number */ ino_t inumb; /* inode number */
int r; int r;
/* If rip is not NULL, it is used to get faster access to the inode. */ /* If rip is not NULL, it is used to get faster access to the inode. */
if (rip == NULL) { if (rip == NULL) {
/* Search for file in directory and try to get its inode. */ /* Search for file in directory and try to get its inode. */
err_code = search_dir(dirp, file_name, &numb, LOOK_UP, IGN_PERM); err_code = search_dir(dirp, file_name, &inumb, LOOK_UP, IGN_PERM);
if (err_code == OK) rip = get_inode(dirp->i_dev, (int) numb); if (err_code == OK) rip = get_inode(dirp->i_dev, inumb);
if (err_code != OK || rip == NULL) return(err_code); if (err_code != OK || rip == NULL) return(err_code);
} else { } else {
dup_inode(rip); /* inode will be returned with put_inode */ dup_inode(rip); /* inode will be returned with put_inode */
@ -284,7 +284,7 @@ PUBLIC int fs_rename()
int odir, ndir; /* TRUE iff {old|new} file is dir */ int odir, ndir; /* TRUE iff {old|new} file is dir */
int same_pdir; /* TRUE iff parent dirs are the same */ int same_pdir; /* TRUE iff parent dirs are the same */
char old_name[NAME_MAX], new_name[NAME_MAX]; char old_name[NAME_MAX], new_name[NAME_MAX];
ino_t numb; ino_t inumb;
phys_bytes len; phys_bytes len;
/* Copy the last component of the old name */ /* Copy the last component of the old name */
@ -423,16 +423,16 @@ PUBLIC int fs_rename()
* otherwise first try to create the new name entry to make sure * otherwise first try to create the new name entry to make sure
* the rename will succeed. * the rename will succeed.
*/ */
numb = old_ip->i_num; /* inode number of old file */ inumb = old_ip->i_num; /* inode number of old file */
if(same_pdir) { if(same_pdir) {
r = search_dir(old_dirp, old_name, NULL, DELETE, IGN_PERM); r = search_dir(old_dirp, old_name, NULL, DELETE, IGN_PERM);
/* shouldn't go wrong. */ /* shouldn't go wrong. */
if(r == OK) if(r == OK)
(void) search_dir(old_dirp, new_name, &numb, ENTER, (void) search_dir(old_dirp, new_name, &inumb, ENTER,
IGN_PERM); IGN_PERM);
} else { } else {
r = search_dir(new_dirp, new_name, &numb, ENTER, IGN_PERM); r = search_dir(new_dirp, new_name, &inumb, ENTER, IGN_PERM);
if(r == OK) if(r == OK)
(void) search_dir(old_dirp, old_name, NULL, DELETE, (void) search_dir(old_dirp, old_name, NULL, DELETE,
IGN_PERM); IGN_PERM);
@ -443,9 +443,9 @@ PUBLIC int fs_rename()
if(r == OK && odir && !same_pdir) { if(r == OK && odir && !same_pdir) {
/* Update the .. entry in the directory (still points to old_dirp).*/ /* Update the .. entry in the directory (still points to old_dirp).*/
numb = new_dirp->i_num; inumb = new_dirp->i_num;
(void) unlink_file(old_ip, NULL, dot2); (void) unlink_file(old_ip, NULL, dot2);
if(search_dir(old_ip, dot2, &numb, ENTER, IGN_PERM) == OK) { if(search_dir(old_ip, dot2, &inumb, ENTER, IGN_PERM) == OK) {
/* New link created. */ /* New link created. */
new_dirp->i_nlinks++; new_dirp->i_nlinks++;
new_dirp->i_dirt = DIRTY; new_dirp->i_dirt = DIRTY;

View File

@ -363,7 +363,7 @@ int chk_perm; /* check permissions when string is looked up*/
* the directory, find the inode, open it, and return a pointer to its inode * the directory, find the inode, open it, and return a pointer to its inode
* slot. * slot.
*/ */
ino_t numb; ino_t inumb;
struct inode *rip; struct inode *rip;
/* If 'string' is empty, return an error. */ /* If 'string' is empty, return an error. */
@ -376,12 +376,12 @@ int chk_perm; /* check permissions when string is looked up*/
if (dirp == NULL) return(NULL); if (dirp == NULL) return(NULL);
/* If 'string' is not present in the directory, signal error. */ /* If 'string' is not present in the directory, signal error. */
if ( (err_code = search_dir(dirp, string, &numb, LOOK_UP, chk_perm)) != OK) { if ( (err_code = search_dir(dirp, string, &inumb, LOOK_UP, chk_perm)) != OK) {
return(NULL); return(NULL);
} }
/* The component has been found in the directory. Get inode. */ /* The component has been found in the directory. Get inode. */
if ( (rip = get_inode(dirp->i_dev, (int) numb)) == NULL) { if ( (rip = get_inode(dirp->i_dev, inumb)) == NULL) {
return(NULL); return(NULL);
} }
@ -468,17 +468,17 @@ char string[NAME_MAX+1]; /* component extracted from 'old_name' */
/*===========================================================================* /*===========================================================================*
* search_dir * * search_dir *
*===========================================================================*/ *===========================================================================*/
PUBLIC int search_dir(ldir_ptr, string, numb, flag, check_permissions) PUBLIC int search_dir(ldir_ptr, string, inumb, flag, check_permissions)
register struct inode *ldir_ptr; /* ptr to inode for dir to search */ register struct inode *ldir_ptr; /* ptr to inode for dir to search */
char string[NAME_MAX]; /* component to search for */ char string[NAME_MAX]; /* component to search for */
ino_t *numb; /* pointer to inode number */ ino_t *inumb; /* pointer to inode number */
int flag; /* LOOK_UP, ENTER, DELETE or IS_EMPTY */ int flag; /* LOOK_UP, ENTER, DELETE or IS_EMPTY */
int check_permissions; /* check permissions when flag is !IS_EMPTY */ int check_permissions; /* check permissions when flag is !IS_EMPTY */
{ {
/* This function searches the directory whose inode is pointed to by 'ldip': /* This function searches the directory whose inode is pointed to by 'ldip':
* if (flag == ENTER) enter 'string' in the directory with inode # '*numb'; * if (flag == ENTER) enter 'string' in the directory with inode # '*inumb';
* if (flag == DELETE) delete 'string' from the directory; * if (flag == DELETE) delete 'string' from the directory;
* if (flag == LOOK_UP) search for 'string' and return inode # in 'numb'; * if (flag == LOOK_UP) search for 'string' and return inode # in 'inumb';
* if (flag == IS_EMPTY) return OK if only . and .. in dir else ENOTEMPTY; * if (flag == IS_EMPTY) return OK if only . and .. in dir else ENOTEMPTY;
* *
* if 'string' is dot1 or dot2, no access permissions are checked. * if 'string' is dot1 or dot2, no access permissions are checked.
@ -563,7 +563,7 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
ldir_ptr->i_dirt = DIRTY; ldir_ptr->i_dirt = DIRTY;
} else { } else {
sp = ldir_ptr->i_sp; /* 'flag' is LOOK_UP */ sp = ldir_ptr->i_sp; /* 'flag' is LOOK_UP */
*numb = (ino_t) conv4(sp->s_native, *inumb = (ino_t) conv4(sp->s_native,
(int) dp->d_ino); (int) dp->d_ino);
} }
put_block(bp, DIRECTORY_BLOCK); put_block(bp, DIRECTORY_BLOCK);
@ -603,7 +603,7 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
(void) memset(dp->d_name, 0, (size_t) NAME_MAX); /* clear entry */ (void) memset(dp->d_name, 0, (size_t) NAME_MAX); /* clear entry */
for (i = 0; i < NAME_MAX && string[i]; i++) dp->d_name[i] = string[i]; for (i = 0; i < NAME_MAX && string[i]; i++) dp->d_name[i] = string[i];
sp = ldir_ptr->i_sp; sp = ldir_ptr->i_sp;
dp->d_ino = conv4(sp->s_native, (int) *numb); dp->d_ino = conv4(sp->s_native, (int) *inumb);
bp->b_dirt = DIRTY; bp->b_dirt = DIRTY;
put_block(bp, DIRECTORY_BLOCK); put_block(bp, DIRECTORY_BLOCK);
ldir_ptr->i_update |= CTIME | MTIME; /* mark mtime for update later */ ldir_ptr->i_update |= CTIME | MTIME; /* mark mtime for update later */

View File

@ -79,6 +79,7 @@ PUBLIC int do_procstat()
if (m_in.stat_nr == SELF) { if (m_in.stat_nr == SELF) {
mp->mp_reply.sig_set = mp->mp_sigpending; mp->mp_reply.sig_set = mp->mp_sigpending;
sigemptyset(&mp->mp_sigpending); sigemptyset(&mp->mp_sigpending);
sigemptyset(&mp->mp_ksigpending);
} }
else { else {
return(ENOSYS); return(ENOSYS);

View File

@ -41,6 +41,7 @@ EXTERN struct mproc {
sigset_t mp_sigmask; /* signals to be blocked */ sigset_t mp_sigmask; /* signals to be blocked */
sigset_t mp_sigmask2; /* saved copy of mp_sigmask */ sigset_t mp_sigmask2; /* saved copy of mp_sigmask */
sigset_t mp_sigpending; /* pending signals to be handled */ sigset_t mp_sigpending; /* pending signals to be handled */
sigset_t mp_ksigpending; /* bitmap for pending signals from the kernel */
sigset_t mp_sigtrace; /* signals to hand to tracer first */ sigset_t mp_sigtrace; /* signals to hand to tracer first */
struct sigaction mp_sigact[_NSIG]; /* as in sigaction(2) */ struct sigaction mp_sigact[_NSIG]; /* as in sigaction(2) */
vir_bytes mp_sigreturn; /* address of C library __sigreturn function */ vir_bytes mp_sigreturn; /* address of C library __sigreturn function */

View File

@ -67,6 +67,7 @@ PUBLIC int do_sigaction()
if (svec.sa_handler == SIG_IGN) { if (svec.sa_handler == SIG_IGN) {
sigaddset(&mp->mp_ignore, m_in.sig_nr); sigaddset(&mp->mp_ignore, m_in.sig_nr);
sigdelset(&mp->mp_sigpending, m_in.sig_nr); sigdelset(&mp->mp_sigpending, m_in.sig_nr);
sigdelset(&mp->mp_ksigpending, m_in.sig_nr);
sigdelset(&mp->mp_catch, m_in.sig_nr); sigdelset(&mp->mp_catch, m_in.sig_nr);
} else if (svec.sa_handler == SIG_DFL) { } else if (svec.sa_handler == SIG_DFL) {
sigdelset(&mp->mp_ignore, m_in.sig_nr); sigdelset(&mp->mp_ignore, m_in.sig_nr);
@ -347,6 +348,7 @@ int ksig; /* non-zero means signal comes from kernel */
if (rmp->mp_flags & FS_CALL) { if (rmp->mp_flags & FS_CALL) {
sigaddset(&rmp->mp_sigpending, signo); sigaddset(&rmp->mp_sigpending, signo);
if(ksig) sigaddset(&rmp->mp_ksigpending, signo);
if (!(rmp->mp_flags & PM_SIG_PENDING)) { if (!(rmp->mp_flags & PM_SIG_PENDING)) {
/* No delay calls: FS_CALL implies the process called us. */ /* No delay calls: FS_CALL implies the process called us. */
@ -361,6 +363,11 @@ int ksig; /* non-zero means signal comes from kernel */
/* Handle system signals for system processes first. */ /* Handle system signals for system processes first. */
if(rmp->mp_flags & PRIV_PROC) { if(rmp->mp_flags & PRIV_PROC) {
/* Always skip signals for PM (only necessary when broadcasting). */
if(rmp->mp_endpoint == PM_PROC_NR) {
return;
}
/* System signals have always to go through the kernel first to let it /* System signals have always to go through the kernel first to let it
* pick the right signal manager. If PM is the assigned signal manager, * pick the right signal manager. If PM is the assigned signal manager,
* the signal will come back and will actually be processed. * the signal will come back and will actually be processed.
@ -370,11 +377,6 @@ int ksig; /* non-zero means signal comes from kernel */
return; return;
} }
/* Always skip signals for PM (only necessary when broadcasting). */
if(rmp->mp_endpoint == PM_PROC_NR) {
return;
}
/* Print stacktrace if necessary. */ /* Print stacktrace if necessary. */
if(SIGS_IS_STACKTRACE(signo)) { if(SIGS_IS_STACKTRACE(signo)) {
sys_sysctl_stacktrace(rmp->mp_endpoint); sys_sysctl_stacktrace(rmp->mp_endpoint);
@ -406,6 +408,7 @@ int ksig; /* non-zero means signal comes from kernel */
if (!badignore && sigismember(&rmp->mp_sigmask, signo)) { if (!badignore && sigismember(&rmp->mp_sigmask, signo)) {
/* Signal should be blocked. */ /* Signal should be blocked. */
sigaddset(&rmp->mp_sigpending, signo); sigaddset(&rmp->mp_sigpending, signo);
if(ksig) sigaddset(&rmp->mp_ksigpending, signo);
return; return;
} }
@ -415,6 +418,7 @@ int ksig; /* non-zero means signal comes from kernel */
* will be delivered using the check_pending() calls in do_trace(). * will be delivered using the check_pending() calls in do_trace().
*/ */
sigaddset(&rmp->mp_sigpending, signo); sigaddset(&rmp->mp_sigpending, signo);
if(ksig) sigaddset(&rmp->mp_ksigpending, signo);
return; return;
} }
if (!badignore && sigismember(&rmp->mp_catch, signo)) { if (!badignore && sigismember(&rmp->mp_catch, signo)) {
@ -428,6 +432,7 @@ int ksig; /* non-zero means signal comes from kernel */
if (!(rmp->mp_flags & UNPAUSED)) { if (!(rmp->mp_flags & UNPAUSED)) {
/* not yet unpaused; continue later */ /* not yet unpaused; continue later */
sigaddset(&rmp->mp_sigpending, signo); sigaddset(&rmp->mp_sigpending, signo);
if(ksig) sigaddset(&rmp->mp_ksigpending, signo);
return; return;
} }
@ -564,12 +569,15 @@ register struct mproc *rmp;
*/ */
int i; int i;
int ksig;
for (i = 1; i < _NSIG; i++) { for (i = 1; i < _NSIG; i++) {
if (sigismember(&rmp->mp_sigpending, i) && if (sigismember(&rmp->mp_sigpending, i) &&
!sigismember(&rmp->mp_sigmask, i)) { !sigismember(&rmp->mp_sigmask, i)) {
ksig = sigismember(&rmp->mp_ksigpending, i);
sigdelset(&rmp->mp_sigpending, i); sigdelset(&rmp->mp_sigpending, i);
sig_proc(rmp, i, FALSE /*trace*/, FALSE /* ksig */); sigdelset(&rmp->mp_ksigpending, i);
sig_proc(rmp, i, FALSE /*trace*/, ksig);
if (rmp->mp_flags & FS_CALL) if (rmp->mp_flags & FS_CALL)
break; break;
@ -711,6 +719,7 @@ int signo; /* signal to send to process (1 to _NSIG-1) */
rmp->mp_sigact[signo].sa_handler = SIG_DFL; rmp->mp_sigact[signo].sa_handler = SIG_DFL;
} }
sigdelset(&rmp->mp_sigpending, signo); sigdelset(&rmp->mp_sigpending, signo);
sigdelset(&rmp->mp_ksigpending, signo);
if(vm_push_sig(rmp->mp_endpoint, &cur_sp) != OK) if(vm_push_sig(rmp->mp_endpoint, &cur_sp) != OK)
return(FALSE); return(FALSE);

View File

@ -253,6 +253,12 @@ PRIVATE int mount_fs(endpoint_t fs_e)
/* Get vnode of mountpoint */ /* Get vnode of mountpoint */
if ((vp = eat_path(PATH_NOFLAGS)) == NULL) return(err_code); if ((vp = eat_path(PATH_NOFLAGS)) == NULL) return(err_code);
if (vp->v_ref_count != 1) {
put_vnode(vp);
return(EBUSY);
}
/* Tell FS on which vnode it is mounted (glue into mount tree) */ /* Tell FS on which vnode it is mounted (glue into mount tree) */
if ((r = req_mountpoint(vp->v_fs_e, vp->v_inode_nr)) != OK) { if ((r = req_mountpoint(vp->v_fs_e, vp->v_inode_nr)) != OK) {
put_vnode(vp); put_vnode(vp);

View File

@ -559,21 +559,6 @@ PUBLIC void pb_unreferenced(struct vir_region *region, struct phys_region *pr)
panic("strange phys flags"); panic("strange phys flags");
} }
SLABFREE(pb); SLABFREE(pb);
} else {
struct phys_region *others;
int n = 0;
for(others = pb->firstregion; others;
others = others->next_ph_list) {
if(WRITABLE(region, others->ph)) {
if(map_ph_writept(others->parent->parent,
others->parent, others) != OK) {
printf("VM: map_ph_writept failed unexpectedly\n");
}
}
n++;
}
assert(n == pb->refcount);
} }
} }

View File

@ -51,7 +51,7 @@ image: includes
# rebuild the program or system libraries # rebuild the program or system libraries
includes: includes:
cd ../include && $(MAKE) install cd .. && $(MAKE) includes
depend: includes depend: includes
cd ../ && $(MAKE) depend cd ../ && $(MAKE) depend

View File

@ -1,5 +1,5 @@
Welcome to MINIX 3.1.7. Welcome to MINIX 3.1.7a.
The system is now running and many commands work normally. To use MINIX The system is now running and many commands work normally. To use MINIX
in a serious way, you need to install it to your hard disk, which you in a serious way, you need to install it to your hard disk, which you

View File

@ -32,7 +32,6 @@ flex-2.5.4
fltk-1.1.7 fltk-1.1.7
fltk-2.0.0-5220 fltk-2.0.0-5220
gawk-3.1.4 gawk-3.1.4
gcc-4.1.1
gcc-4.4.3 gcc-4.4.3
gcc-libs gcc-libs
gettext-0.14 gettext-0.14

View File

@ -194,7 +194,7 @@ if [ $PACKAGES -ne 0 ]
then mkdir -p $PACKAGEDIR || true then mkdir -p $PACKAGEDIR || true
mkdir -p $PACKAGESOURCEDIR || true mkdir -p $PACKAGESOURCEDIR || true
rm -f $PACKAGEDIR/List rm -f $PACKAGEDIR/List
retrieve $PACKAGEDIR $PACKAGELIST packages/`uname -p`/`uname -r`.`uname -v` retrieve $PACKAGEDIR $PACKAGELIST packages/`uname -p`/3.1.7
retrieve $PACKAGESOURCEDIR $PACKAGESOURCELIST software retrieve $PACKAGESOURCEDIR $PACKAGESOURCELIST software
fi fi
@ -350,7 +350,10 @@ echo " * Bootstrap /etc/mk files"
# and permissions will be set by its own src/etc/Makefile. # and permissions will be set by its own src/etc/Makefile.
mkdir -p $RELEASEDIR/etc/mk mkdir -p $RELEASEDIR/etc/mk
chmod 755 $RELEASEDIR/etc/mk chmod 755 $RELEASEDIR/etc/mk
mkdir -p $RELEASEDIR/usr/share/mk
chmod 755 $RELEASEDIR/usr/share/mk
cp $RELEASEDIR/usr/src/etc/mk/* $RELEASEDIR/etc/mk/ cp $RELEASEDIR/usr/src/etc/mk/* $RELEASEDIR/etc/mk/
cp $RELEASEDIR/usr/src/etc/mk/* $RELEASEDIR/usr/share/mk
chown -R root $RELEASEDIR/etc/mk chown -R root $RELEASEDIR/etc/mk
echo " * Chroot build" echo " * Chroot build"
cp chrootmake.sh $RELEASEDIR/usr/$SRC/tools/chrootmake.sh cp chrootmake.sh $RELEASEDIR/usr/$SRC/tools/chrootmake.sh