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 <string.h>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <sys/ioctl.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)
{
/* 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) {
case FT_ETHERNET:
/* Set NONBLOCK to avoid waiting for a device driver to become ready */
fcntl(np->fdp->fd, F_SETFL, fcntl(np->fdp->fd, F_GETFL) | O_NONBLOCK);
/* Cannot use NWIOGETHSTAT in non-blocking mode due to a race between
* 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) {
/* Not an Ethernet. */
close(fdp->fd);
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;
ethopt.nweo_flags= NWEO_COPY | NWEO_EN_LOC | NWEO_EN_BROAD
| 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;
reply.m_type = DL_TASK_REPLY;
reply.DL_STAT = flags;
reply.DL_FLAGS = flags;
reply.DL_COUNT = dep->de_read_s;
r = send(dep->de_client, &reply);

View File

@ -3,7 +3,7 @@
/* Minix release and version numbers. */
#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.
* It is divided up into two main sections. The first section contains

View File

@ -150,7 +150,7 @@
/* Some limits. */
#define MAX_INODE_NR ((ino_t) 037777777777) /* largest inode number */
#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 */

View File

@ -11,6 +11,10 @@
#include <minix/cpufeature.h>
#include <a.out.h>
#include <assert.h>
#include <signal.h>
#include <machine/vm.h>
#include <sys/sigcontext.h>
#include "archconst.h"
#include "proto.h"
@ -23,6 +27,9 @@
#include "apic.h"
#endif
PRIVATE int osfxsr_feature; /* FXSAVE/FXRSTOR instructions support (SSEx) */
/* set MP and NE flags to handle FPU exceptions in native mode. */
#define CR0_MP_NE 0x0022
/* 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)
{
#ifdef CONFIG_APIC
@ -438,3 +498,36 @@ PUBLIC struct proc * arch_finish_switch_to_user(void)
*((reg_t *)stk) = (reg_t) 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 _write_cr0 /* write a value in cr0 */
.globl _read_cr3
.globl _write_cr3
.globl _read_cr4
.globl _write_cr4
@ -50,6 +51,11 @@
.globl _fninit /* non-waiting FPU initialization */
.globl _fnstsw /* store status 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
@ -655,6 +661,10 @@ _fninit:
fninit
ret
_clts:
clts
ret
_fnstsw:
xor %eax, %eax
@ -671,6 +681,40 @@ _fnstcw:
pop %eax
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 */
/*===========================================================================*/
@ -745,6 +789,22 @@ _write_cr4:
0:
pop %ebp
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 */
/*===========================================================================*/
@ -847,3 +907,4 @@ _switch_address_space:
mov %edx, _ptproc
0:
ret

View File

@ -45,11 +45,25 @@ PUBLIC void vm_init(struct proc *newptproc)
{
if(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);
assert(ptproc == newptproc);
vm_enable_paging();
vm_running = 1;
}
/* 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;
}
PUBLIC void vm_stop(void)
{
write_cr0(read_cr0() & ~I386_CR0_PG);
}
PRIVATE void vm_enable_paging(void)
{
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_],
procs[_DST_], phys_addr[_DST_], bytes)) != OK) {
struct proc *target;
struct proc *target = NULL;
phys_bytes lin;
if(r != EFAULT_SRC && r != EFAULT_DST)
panic("lin_lin_copy failed: %d", r);
@ -821,8 +840,6 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
return r;
}
assert(procs[_SRC_] && procs[_DST_]);
if(r == EFAULT_SRC) {
lin = phys_addr[_SRC_];
target = procs[_SRC_];
@ -833,6 +850,9 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
panic("r strange: %d", r);
}
assert(caller);
assert(target);
vm_suspend(caller, target, lin, bytes, VMSTYPE_KERNELCALL);
return VMSUSPEND;
}

View File

@ -90,7 +90,7 @@ begbss:
.globl _params_offset
.globl _mon_ds
.globl _switch_to_user
.globl _lazy_fpu
.globl _save_fpu
.globl _hwint00 /* handlers for hardware interrupts */
.globl _hwint01
@ -589,33 +589,16 @@ _inval_opcode:
_copr_not_available:
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)
/* stop user process cycles */
push %ebp
mov $0, %ebp
call _context_stop
pop %ebp
lea P_MISC_FLAGS(%ebp), %ebx
movw (%ebx), %cx
and $MF_FPU_INITIALIZED, %cx
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 */
orw $MF_USED_FPU, (%ebx)
mov $0, %ebp
jmp _switch_to_user
copr_not_available_in_kernel:
@ -656,51 +639,6 @@ _machine_check:
_simd_exception:
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 */
/*===========================================================================*/

View File

@ -74,6 +74,7 @@ _PROTOTYPE( reg_t read_cr2, (void) );
_PROTOTYPE( void write_cr0, (unsigned long value) );
_PROTOTYPE( unsigned long read_cr4, (void) );
_PROTOTYPE( void write_cr4, (unsigned long value) );
_PROTOTYPE( void write_cr3, (unsigned long value) );
_PROTOTYPE( unsigned long read_cpu_flags, (void) );
_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) );
@ -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_write, (u32_t reg, u32_t hi, u32_t lo) );
_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( void fnstcw, (unsigned short* cw));

View File

@ -140,10 +140,18 @@
SAVE_TRAP_CTX(displ, %ebp, %esi) ;
#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 ;\
call _lazy_fpu ;\
add $4, %esp ;
call _save_fpu ;\
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

View File

@ -45,7 +45,6 @@ EXTERN time_t boottime;
EXTERN char params_buffer[512]; /* boot monitor parameters */
EXTERN int minix_panicing;
EXTERN char fpu_presence;
EXTERN char osfxsr_feature; /* FXSAVE/FXRSTOR instructions support (SSEx) */
EXTERN int verboseboot; /* verbose boot, init'ed in cstart */
#define MAGICTEST 0xC0FFEE23
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
* to userspace. This function does not return
*/
restore_fpu(proc_ptr);
restore_user_context(proc_ptr);
NOT_REACHABLE;
}
@ -560,6 +561,10 @@ PUBLIC int mini_send(
call = (caller_ptr->p_misc_flags & MF_REPLY_PEND ? SENDREC
: (flags & NON_BLOCKING ? SENDNB : SEND));
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);
} else {
if(flags & NON_BLOCKING) {
@ -589,10 +594,10 @@ PUBLIC int mini_send(
caller_ptr->p_sendto_e = dst_e;
/* 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 */
while (*xpp) xpp = &(*xpp)->p_q_link;
*xpp = caller_ptr; /* add caller to end */
caller_ptr->p_q_link = NULL; /* mark new end of list */
}
return(OK);
}
@ -678,7 +683,7 @@ PRIVATE int mini_receive(
IPC_STATUS_ADD_CALL(caller_ptr, NOTIFY);
return(OK);
goto receive_done;
}
}
@ -692,44 +697,47 @@ PRIVATE int mini_receive(
if (r == OK) {
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. */
xpp = &caller_ptr->p_caller_q;
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;
assert(!RTS_ISSET(*xpp, RTS_SLOT_FREE));
assert(!RTS_ISSET(*xpp, RTS_NO_ENDPOINT));
assert(!RTS_ISSET(sender, RTS_SLOT_FREE));
assert(!RTS_ISSET(sender, RTS_NO_ENDPOINT));
/* Found acceptable message. Copy it and update status. */
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
caller_ptr->p_delivermsg = (*xpp)->p_sendmsg;
caller_ptr->p_delivermsg.m_source = (*xpp)->p_endpoint;
caller_ptr->p_delivermsg = sender->p_sendmsg;
caller_ptr->p_delivermsg.m_source = sender->p_endpoint;
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);
/*
* if the message is originaly from the kernel on behalf of this
* 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);
/* 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)
sig_delay_done(*xpp);
if (sender->p_misc_flags & MF_SIG_DELAY)
sig_delay_done(sender);
*xpp = (*xpp)->p_q_link; /* remove from queue */
return(OK); /* report success */
*xpp = sender->p_q_link; /* remove from queue */
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 {
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_no_quantum(p) ((p)->p_rts_flags & RTS_NO_QUANTUM)
#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 */
#define proc_kernel_scheduler(p) ((p)->p_scheduler == NULL || \

View File

@ -5,6 +5,7 @@
#include <minix/safecopies.h>
#include <machine/archtypes.h>
#include <sys/sigcontext.h>
#include <a.out.h>
/* Struct declarations. */
@ -28,6 +29,9 @@ _PROTOTYPE( void cycles_accounting_init, (void) );
_PROTOTYPE( void context_stop, (struct proc * p) );
/* this is a wrapper to make calling it from assembly easier */
_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 */
_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));
_PROTOTYPE( void alloc_segments, (struct proc *rp) );
_PROTOTYPE( void vm_init, (struct proc *first) );
_PROTOTYPE( void vm_stop, (void) );
_PROTOTYPE( phys_bytes umap_local, (register struct proc *rp, int seg,
vir_bytes vir_addr, vir_bytes bytes));
_PROTOTYPE( phys_bytes umap_remote, (const struct proc* rp, int seg,

View File

@ -15,6 +15,7 @@
#include <assert.h>
#include <minix/endpoint.h>
#include <minix/u64.h>
#if USE_FORK
@ -89,6 +90,9 @@ PUBLIC int do_fork(struct proc * caller, message * m_ptr)
if (rpc->p_scheduler)
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
* child process and inhibit it from running by setting the NO_PRIV flag.
* 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);
} else {
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);
}
return(OK);

View File

@ -27,9 +27,6 @@ PUBLIC int do_sigsend(struct proc * caller, message * m_ptr)
struct sigcontext sc, *scp;
struct sigframe fr, *frp;
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 (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;
fr.sf_scp = scp;
#if (_MINIX_CHIP == _CHIP_INTEL)
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
fpu_sigcontext(rp, &fr, &sc);
fr.sf_signo = smsg.sm_signo;
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) {
/* i_nlinks == NO_LINK means free the inode. */
/* 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_dirt = DIRTY;
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 super_block *sp;
int major, minor, inumb;
int major, minor;
bit_t b;
ino_t inumb;
sp = get_super(dev); /* get pointer to super_block */
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);
}
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. */
if ((rip = get_inode(NO_DEV, inumb)) == NULL) {
@ -339,7 +344,7 @@ PRIVATE void free_inode(
/* Locate the appropriate super_block. */
sp = get_super(dev);
if (inumb > sp->s_ninodes) return;
if (inumb == 0 || inumb > sp->s_ninodes) return;
b = (bit_t) inumb;
free_bit(sp, IMAP, 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. */
ino_t numb; /* inode number */
ino_t inumb; /* inode number */
int r;
/* If rip is not NULL, it is used to get faster access to the inode. */
if (rip == NULL) {
/* Search for file in directory and try to get its inode. */
err_code = search_dir(dirp, file_name, &numb, LOOK_UP, IGN_PERM);
if (err_code == OK) rip = get_inode(dirp->i_dev, (int) numb);
err_code = search_dir(dirp, file_name, &inumb, LOOK_UP, IGN_PERM);
if (err_code == OK) rip = get_inode(dirp->i_dev, inumb);
if (err_code != OK || rip == NULL) return(err_code);
} else {
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 same_pdir; /* TRUE iff parent dirs are the same */
char old_name[NAME_MAX], new_name[NAME_MAX];
ino_t numb;
ino_t inumb;
phys_bytes len;
/* 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
* 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) {
r = search_dir(old_dirp, old_name, NULL, DELETE, IGN_PERM);
/* shouldn't go wrong. */
if(r == OK)
(void) search_dir(old_dirp, new_name, &numb, ENTER,
(void) search_dir(old_dirp, new_name, &inumb, ENTER,
IGN_PERM);
} 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)
(void) search_dir(old_dirp, old_name, NULL, DELETE,
IGN_PERM);
@ -443,9 +443,9 @@ PUBLIC int fs_rename()
if(r == OK && odir && !same_pdir) {
/* 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);
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_dirp->i_nlinks++;
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
* slot.
*/
ino_t numb;
ino_t inumb;
struct inode *rip;
/* 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 '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);
}
/* 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);
}
@ -468,17 +468,17 @@ char string[NAME_MAX+1]; /* component extracted from 'old_name' */
/*===========================================================================*
* 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 */
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 check_permissions; /* check permissions when flag is !IS_EMPTY */
{
/* 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 == 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 '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;
} else {
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);
}
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 */
for (i = 0; i < NAME_MAX && string[i]; i++) dp->d_name[i] = string[i];
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;
put_block(bp, DIRECTORY_BLOCK);
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) {
mp->mp_reply.sig_set = mp->mp_sigpending;
sigemptyset(&mp->mp_sigpending);
sigemptyset(&mp->mp_ksigpending);
}
else {
return(ENOSYS);

View File

@ -41,6 +41,7 @@ EXTERN struct mproc {
sigset_t mp_sigmask; /* signals to be blocked */
sigset_t mp_sigmask2; /* saved copy of mp_sigmask */
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 */
struct sigaction mp_sigact[_NSIG]; /* as in sigaction(2) */
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) {
sigaddset(&mp->mp_ignore, 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);
} else if (svec.sa_handler == SIG_DFL) {
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) {
sigaddset(&rmp->mp_sigpending, signo);
if(ksig) sigaddset(&rmp->mp_ksigpending, signo);
if (!(rmp->mp_flags & PM_SIG_PENDING)) {
/* 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. */
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
* pick the right signal manager. If PM is the assigned signal manager,
* the signal will come back and will actually be processed.
@ -370,11 +377,6 @@ int ksig; /* non-zero means signal comes from kernel */
return;
}
/* Always skip signals for PM (only necessary when broadcasting). */
if(rmp->mp_endpoint == PM_PROC_NR) {
return;
}
/* Print stacktrace if necessary. */
if(SIGS_IS_STACKTRACE(signo)) {
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)) {
/* Signal should be blocked. */
sigaddset(&rmp->mp_sigpending, signo);
if(ksig) sigaddset(&rmp->mp_ksigpending, signo);
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().
*/
sigaddset(&rmp->mp_sigpending, signo);
if(ksig) sigaddset(&rmp->mp_ksigpending, signo);
return;
}
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)) {
/* not yet unpaused; continue later */
sigaddset(&rmp->mp_sigpending, signo);
if(ksig) sigaddset(&rmp->mp_ksigpending, signo);
return;
}
@ -564,12 +569,15 @@ register struct mproc *rmp;
*/
int i;
int ksig;
for (i = 1; i < _NSIG; i++) {
if (sigismember(&rmp->mp_sigpending, i) &&
!sigismember(&rmp->mp_sigmask, i)) {
ksig = sigismember(&rmp->mp_ksigpending, 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)
break;
@ -711,6 +719,7 @@ int signo; /* signal to send to process (1 to _NSIG-1) */
rmp->mp_sigact[signo].sa_handler = SIG_DFL;
}
sigdelset(&rmp->mp_sigpending, signo);
sigdelset(&rmp->mp_ksigpending, signo);
if(vm_push_sig(rmp->mp_endpoint, &cur_sp) != OK)
return(FALSE);

View File

@ -253,6 +253,12 @@ PRIVATE int mount_fs(endpoint_t fs_e)
/* Get vnode of mountpoint */
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) */
if ((r = req_mountpoint(vp->v_fs_e, vp->v_inode_nr)) != OK) {
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");
}
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
includes:
cd ../include && $(MAKE) install
cd .. && $(MAKE) includes
depend: includes
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
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-2.0.0-5220
gawk-3.1.4
gcc-4.1.1
gcc-4.4.3
gcc-libs
gettext-0.14

View File

@ -194,7 +194,7 @@ if [ $PACKAGES -ne 0 ]
then mkdir -p $PACKAGEDIR || true
mkdir -p $PACKAGESOURCEDIR || true
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
fi
@ -350,7 +350,10 @@ echo " * Bootstrap /etc/mk files"
# and permissions will be set by its own src/etc/Makefile.
mkdir -p $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/usr/share/mk
chown -R root $RELEASEDIR/etc/mk
echo " * Chroot build"
cp chrootmake.sh $RELEASEDIR/usr/$SRC/tools/chrootmake.sh