Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6d46289843 | ||
![]() |
4acb68bf9d | ||
![]() |
b7a097ec84 | ||
![]() |
57ed4bbb51 | ||
![]() |
cb800f32dc | ||
![]() |
6b940e1a03 | ||
![]() |
673b269068 | ||
![]() |
e27fa0d04e | ||
![]() |
f4499bd4a0 | ||
![]() |
2ec255bb5e | ||
![]() |
cd445fe22a | ||
![]() |
64b1205e6c | ||
![]() |
94881e6d4a | ||
![]() |
6677a8c8e0 | ||
![]() |
255ad2ab37 | ||
![]() |
7dc782dd1a | ||
![]() |
e9eb2c4f8b |
@ -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, ðstat) < 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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
/*===========================================================================*/
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
@ -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 || \
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user