summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/config.in13
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c2
-rw-r--r--arch/alpha/kernel/entry.S480
-rw-r--r--arch/alpha/kernel/osf_sys.c412
-rw-r--r--arch/alpha/kernel/ptrace.c22
-rw-r--r--arch/alpha/kernel/signal.c599
-rw-r--r--arch/alpha/kernel/time.c182
-rw-r--r--arch/alpha/kernel/traps.c157
-rw-r--r--arch/alpha/lib/Makefile3
-rw-r--r--arch/alpha/lib/clear_user.S8
-rw-r--r--arch/alpha/lib/csum_partial_copy.c2
-rw-r--r--arch/i386/boot/compressed/head.S10
-rw-r--r--arch/i386/boot/compressed/misc.c2
-rw-r--r--arch/i386/boot/setup.S4
-rw-r--r--arch/i386/config.in13
-rw-r--r--arch/i386/defconfig23
-rw-r--r--arch/i386/kernel/bios32.c6
-rw-r--r--arch/i386/kernel/entry.S37
-rw-r--r--arch/i386/kernel/head.S14
-rw-r--r--arch/i386/kernel/init_task.c1
-rw-r--r--arch/i386/kernel/irq.h2
-rw-r--r--arch/i386/kernel/process.c25
-rw-r--r--arch/i386/kernel/ptrace.c12
-rw-r--r--arch/i386/kernel/signal.c654
-rw-r--r--arch/i386/kernel/sys_i386.c21
-rw-r--r--arch/i386/kernel/trampoline.S2
-rw-r--r--arch/i386/kernel/traps.c4
-rw-r--r--arch/i386/kernel/vm86.c9
-rw-r--r--arch/i386/lib/delay.c2
-rw-r--r--arch/i386/math-emu/errors.c4
-rw-r--r--arch/i386/math-emu/fpu_entry.c4
-rw-r--r--arch/m68k/config.in11
-rw-r--r--arch/m68k/kernel/entry.S2
-rw-r--r--arch/mips/Makefile21
-rw-r--r--arch/mips/config.in60
-rw-r--r--arch/mips/defconfig30
-rw-r--r--arch/mips/jazz/g364.c8
-rw-r--r--arch/mips/kernel/entry.S25
-rw-r--r--arch/mips/kernel/ipc.c2
-rw-r--r--arch/mips/kernel/irixelf.c10
-rw-r--r--arch/mips/kernel/irixioctl.c4
-rw-r--r--arch/mips/kernel/irixsig.c480
-rw-r--r--arch/mips/kernel/process.c2
-rw-r--r--arch/mips/kernel/ptrace.c10
-rw-r--r--arch/mips/kernel/setup.c16
-rw-r--r--arch/mips/kernel/signal.c451
-rw-r--r--arch/mips/kernel/syscall.c6
-rw-r--r--arch/mips/kernel/syscalls.h13
-rw-r--r--arch/mips/kernel/sysirix.c162
-rw-r--r--arch/mips/kernel/traps.c7
-rw-r--r--arch/mips/lib/Makefile7
-rw-r--r--arch/mips/lib/dump_tlb.c17
-rw-r--r--arch/mips/lib/pmaxcon.c150
-rw-r--r--arch/mips/lib/pmaxio.S40
-rw-r--r--arch/mips/mips/Makefile39
-rwxr-xr-xarch/mips/mips/mkprom25
-rw-r--r--arch/mips/mm/fault.c2
-rw-r--r--arch/mips/mm/init.c16
-rw-r--r--arch/mips/mm/r4xx0.c75
-rw-r--r--arch/mips/sgi/kernel/reset.c1
-rw-r--r--arch/mips/tools/offset.c5
-rw-r--r--arch/ppc/config.in12
-rw-r--r--arch/sparc/config.in11
-rw-r--r--arch/sparc64/config.in11
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c199
65 files changed, 2987 insertions, 1672 deletions
diff --git a/arch/alpha/config.in b/arch/alpha/config.in
index 9c74cc091..84402f1e0 100644
--- a/arch/alpha/config.in
+++ b/arch/alpha/config.in
@@ -134,6 +134,8 @@ if [ "$CONFIG_NET" = "y" ]; then
endmenu
fi
+source drivers/net/hamradio/Config.in
+
mainmenu_option next_comment
comment 'ISDN subsystem'
@@ -152,6 +154,17 @@ if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
fi
endmenu
+# Conditionally compile in the Uniform CD-ROM driver
+if [ "$CONFIG_BLK_DEV_IDECD" = "y" -o "$CONFIG_BLK_DEV_SR" = "y" -o "$CONFIG_SBPCD" = "y" -o "$CONFIG_MCD" = "y" -o "$CONFIG_CM206" = "y" -o "$CONFIG_CDU31A" = "y" ]; then
+ define_bool CONFIG_CDROM y
+else
+ if [ "$CONFIG_BLK_DEV_IDECD" = "m" -o "$CONFIG_BLK_DEV_SR" = "m" -o "$CONFIG_SBPCD" = "m" -o "$CONFIG_MCD" = "m" -o "$CONFIG_CM206" = "m" -o "$CONFIG_CDU31A" = "m" ]; then
+ define_bool CONFIG_CDROM m
+ else
+ define_bool CONFIG_CDROM n
+ fi
+fi
+
source fs/Config.in
source fs/nls/Config.in
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index be75f566f..822513e4e 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -94,7 +94,7 @@ EXPORT_SYMBOL(csum_partial_copy);
* The following are specially called from the uaccess assembly stubs.
*/
EXPORT_SYMBOL_NOVERS(__copy_user);
-EXPORT_SYMBOL_NOVERS(__clear_user);
+EXPORT_SYMBOL_NOVERS(__do_clear_user);
EXPORT_SYMBOL(__strncpy_from_user);
EXPORT_SYMBOL(__strlen_user);
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 75c0665a7..0eef8b539 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -10,7 +10,7 @@
#define rti .long PAL_rti
#define SIGCHLD 20
-#define NR_SYSCALLS 352
+#define NR_SYSCALLS 360
#define osf_vfork sys_fork
/*
@@ -32,9 +32,8 @@
#define TASK_STATE 0
#define TASK_COUNTER 8
#define TASK_PRIORITY 16
-#define TASK_SIGNAL 24
-#define TASK_BLOCKED 32
-#define TASK_FLAGS 40
+#define TASK_FLAGS 24
+#define TASK_SIGPENDING 32
/*
* task flags (must match include/linux/sched.h):
@@ -509,7 +508,7 @@ entSys:
lda $4,NR_SYSCALLS($31)
stq $16,SP_OFF+24($30)
lda $5,sys_call_table
- lda $27,do_entSys
+ lda $27,alpha_ni_syscall
cmpult $0,$4,$4
ldq $3,TASK_FLAGS($8)
stq $17,SP_OFF+32($30)
@@ -519,7 +518,7 @@ entSys:
bne $3,strace
beq $4,1f
ldq $27,0($5)
-1: jsr $26,($27),do_entSys
+1: jsr $26,($27),alpha_ni_syscall
ldgp $29,0($26)
blt $0,syscall_error /* the call failed */
stq $0,0($30)
@@ -544,11 +543,9 @@ ret_from_reschedule:
lda $4,init_task_union
bne $2,reschedule
xor $4,$8,$4
+ ldl $5,TASK_SIGPENDING($8)
beq $4,restore_all
- ldq $4,TASK_SIGNAL($8)
- ldq $16,TASK_BLOCKED($8)
- bic $4,$16,$4
- bne $4,signal_return
+ bne $5,signal_return
restore_all:
RESTORE_ALL
rti
@@ -574,12 +571,12 @@ strace:
/* get the system call pointer.. */
lda $1,NR_SYSCALLS($31)
lda $2,sys_call_table
- lda $27,do_entSys
+ lda $27,alpha_ni_syscall
cmpult $0,$1,$1
s8addq $0,$2,$2
beq $1,1f
ldq $27,0($2)
-1: jsr $26,($27),do_entSys
+1: jsr $26,($27),alpha_ni_syscall
ldgp $29,0($26)
/* check return.. */
@@ -656,6 +653,7 @@ signal_return:
bis $30,$30,$17
br $1,do_switch_stack
bis $30,$30,$18
+ bis $31,$31,$16
jsr $26,do_signal
lda $30,SWITCH_STACK_SIZE($30)
br $31,restore_all
@@ -686,6 +684,17 @@ sys_sigreturn:
.end sys_sigreturn
.align 3
+.ent sys_rt_sigreturn
+sys_rt_sigreturn:
+ bis $30,$30,$17
+ lda $30,-SWITCH_STACK_SIZE($30)
+ bis $30,$30,$18
+ jsr $26,do_rt_sigreturn
+ br $1,undo_switch_stack
+ br $31,ret_from_sys_call
+.end sys_rt_sigreturn
+
+.align 3
.ent sys_sigsuspend
sys_sigsuspend:
bis $30,$30,$17
@@ -696,80 +705,383 @@ sys_sigsuspend:
br $31,ret_from_sys_call
.end sys_sigsuspend
+.align 3
+.ent sys_rt_sigsuspend
+sys_rt_sigsuspend:
+ bis $30,$30,$18
+ br $1,do_switch_stack
+ bis $30,$30,$19
+ jsr $26,do_rt_sigsuspend
+ lda $30,SWITCH_STACK_SIZE($30)
+ br $31,ret_from_sys_call
+.end sys_rt_sigsuspend
+
+ .data
.align 3
.globl sys_call_table
sys_call_table:
-/*0*/ .quad do_entSys, sys_exit, sys_fork, sys_read, sys_write
- .quad do_entSys, sys_close, sys_wait4, do_entSys, sys_link
- .quad sys_unlink, do_entSys, sys_chdir, sys_fchdir, sys_mknod
- .quad sys_chmod, sys_chown, osf_brk, do_entSys, sys_lseek
- .quad sys_getxpid, osf_mount, osf_umount, sys_setuid, sys_getxuid
- .quad do_entSys, sys_ptrace, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, sys_access, do_entSys
- .quad do_entSys, sys_sync, sys_kill, do_entSys, sys_setpgid
- .quad do_entSys, sys_dup, sys_pipe, osf_set_program_attributes, do_entSys
- .quad sys_open, do_entSys, sys_getxgid, osf_sigprocmask, do_entSys
-/*50*/ .quad do_entSys, sys_acct, sys_sigpending, do_entSys, sys_ioctl
- .quad do_entSys, do_entSys, sys_symlink, sys_readlink, sys_execve
- .quad sys_umask, sys_chroot, do_entSys, sys_getpgrp, sys_getpagesize
- .quad do_entSys, osf_vfork, sys_newstat, sys_newlstat, do_entSys
- .quad do_entSys, osf_mmap, do_entSys, sys_munmap, sys_mprotect
- .quad sys_madvise, sys_vhangup, do_entSys, do_entSys, sys_getgroups
+ .quad alpha_ni_syscall /* 0 */
+ .quad sys_exit
+ .quad sys_fork
+ .quad sys_read
+ .quad sys_write
+ .quad alpha_ni_syscall /* 5 */
+ .quad sys_close
+ .quad osf_wait4
+ .quad alpha_ni_syscall
+ .quad sys_link
+ .quad sys_unlink /* 10 */
+ .quad alpha_ni_syscall
+ .quad sys_chdir
+ .quad sys_fchdir
+ .quad sys_mknod
+ .quad sys_chmod /* 15 */
+ .quad sys_chown
+ .quad osf_brk
+ .quad alpha_ni_syscall
+ .quad sys_lseek
+ .quad sys_getxpid /* 20 */
+ .quad osf_mount
+ .quad osf_umount
+ .quad sys_setuid
+ .quad sys_getxuid
+ .quad alpha_ni_syscall /* 25 */
+ .quad sys_ptrace
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 30 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad sys_access
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 35 */
+ .quad sys_sync
+ .quad sys_kill
+ .quad alpha_ni_syscall
+ .quad sys_setpgid
+ .quad alpha_ni_syscall /* 40 */
+ .quad sys_dup
+ .quad sys_pipe
+ .quad osf_set_program_attributes
+ .quad alpha_ni_syscall
+ .quad sys_open /* 45 */
+ .quad alpha_ni_syscall
+ .quad sys_getxgid
+ .quad osf_sigprocmask
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 50 */
+ .quad sys_acct
+ .quad osf_sigpending
+ .quad alpha_ni_syscall
+ .quad sys_ioctl
+ .quad alpha_ni_syscall /* 55 */
+ .quad alpha_ni_syscall
+ .quad sys_symlink
+ .quad sys_readlink
+ .quad sys_execve
+ .quad sys_umask /* 60 */
+ .quad sys_chroot
+ .quad alpha_ni_syscall
+ .quad sys_getpgrp
+ .quad sys_getpagesize
+ .quad alpha_ni_syscall /* 65 */
+ .quad osf_vfork
+ .quad sys_newstat
+ .quad sys_newlstat
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 70 */
+ .quad osf_mmap
+ .quad alpha_ni_syscall
+ .quad sys_munmap
+ .quad sys_mprotect
+ .quad sys_madvise /* 75 */
+ .quad sys_vhangup
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad sys_getgroups
/* map BSD's setpgrp to sys_setpgid for binary compatibility: */
- .quad sys_setgroups, do_entSys, sys_setpgid, sys_setitimer, do_entSys
- .quad do_entSys, sys_getitimer, sys_gethostname, sys_sethostname, sys_getdtablesize
- .quad sys_dup2, sys_newfstat, sys_fcntl, sys_select, sys_poll
- .quad sys_fsync, sys_setpriority, sys_socket, sys_connect, sys_accept
-/*100*/ .quad osf_getpriority, sys_send, sys_recv, sys_sigreturn, sys_bind
- .quad sys_setsockopt, sys_listen, do_entSys, do_entSys, do_entSys
- .quad do_entSys, sys_sigsuspend, do_entSys, sys_recvmsg, sys_sendmsg
- .quad do_entSys, sys_gettimeofday, sys_getrusage, sys_getsockopt, do_entSys
- .quad sys_readv, sys_writev, sys_settimeofday, sys_fchown, sys_fchmod
- .quad sys_recvfrom, sys_setreuid, sys_setregid, sys_rename, sys_truncate
- .quad sys_ftruncate, sys_flock, sys_setgid, sys_sendto, sys_shutdown
- .quad sys_socketpair, sys_mkdir, sys_rmdir, sys_utimes, do_entSys
- .quad do_entSys, sys_getpeername, do_entSys, do_entSys, sys_getrlimit
- .quad sys_setrlimit, do_entSys, sys_setsid, sys_quotactl, do_entSys
-/*150*/ .quad sys_getsockname, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, sys_sigaction, do_entSys, do_entSys, osf_getdirentries
- .quad osf_statfs, osf_fstatfs, do_entSys, do_entSys, do_entSys
- .quad osf_getdomainname, sys_setdomainname, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, osf_swapon
-/*200*/ .quad sys_msgctl, sys_msgget, sys_msgrcv, sys_msgsnd, sys_semctl
- .quad sys_semget, sys_semop, osf_utsname, do_entSys, osf_shmat
- .quad sys_shmctl, sys_shmdt, sys_shmget, do_entSys, do_entSys
- .quad do_entSys, do_entSys, sys_msync, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, sys_getpgid, sys_getsid
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, osf_sysinfo, do_entSys, do_entSys, osf_proplist_syscall
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
-/*250*/ .quad do_entSys, osf_usleep_thread, do_entSys, do_entSys, sys_sysfs
- .quad do_entSys, osf_getsysinfo, osf_setsysinfo, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
- .quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
+ .quad sys_setgroups /* 80 */
+ .quad alpha_ni_syscall
+ .quad sys_setpgid
+ .quad osf_setitimer
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 85 */
+ .quad osf_getitimer
+ .quad sys_gethostname
+ .quad sys_sethostname
+ .quad sys_getdtablesize
+ .quad sys_dup2 /* 90 */
+ .quad sys_newfstat
+ .quad sys_fcntl
+ .quad osf_select
+ .quad sys_poll
+ .quad sys_fsync /* 95 */
+ .quad sys_setpriority
+ .quad sys_socket
+ .quad sys_connect
+ .quad sys_accept
+ .quad osf_getpriority /* 100 */
+ .quad sys_send
+ .quad sys_recv
+ .quad sys_sigreturn
+ .quad sys_bind
+ .quad sys_setsockopt /* 105 */
+ .quad sys_listen
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 110 */
+ .quad sys_sigsuspend
+ .quad alpha_ni_syscall
+ .quad sys_recvmsg
+ .quad sys_sendmsg
+ .quad alpha_ni_syscall /* 115 */
+ .quad osf_gettimeofday
+ .quad osf_getrusage
+ .quad sys_getsockopt
+ .quad alpha_ni_syscall
+ .quad sys_readv /* 120 */
+ .quad sys_writev
+ .quad osf_settimeofday
+ .quad sys_fchown
+ .quad sys_fchmod
+ .quad sys_recvfrom /* 125 */
+ .quad sys_setreuid
+ .quad sys_setregid
+ .quad sys_rename
+ .quad sys_truncate
+ .quad sys_ftruncate /* 130 */
+ .quad sys_flock
+ .quad sys_setgid
+ .quad sys_sendto
+ .quad sys_shutdown
+ .quad sys_socketpair /* 135 */
+ .quad sys_mkdir
+ .quad sys_rmdir
+ .quad osf_utimes
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 140 */
+ .quad sys_getpeername
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad sys_getrlimit
+ .quad sys_setrlimit /* 145 */
+ .quad alpha_ni_syscall
+ .quad sys_setsid
+ .quad sys_quotactl
+ .quad alpha_ni_syscall
+ .quad sys_getsockname /* 150 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 155 */
+ .quad osf_sigaction
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad osf_getdirentries
+ .quad osf_statfs /* 160 */
+ .quad osf_fstatfs
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad osf_getdomainname /* 165 */
+ .quad sys_setdomainname
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 170 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 175 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 180 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 185 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 190 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 195 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad osf_swapon
+ .quad sys_msgctl /* 200 */
+ .quad sys_msgget
+ .quad sys_msgrcv
+ .quad sys_msgsnd
+ .quad sys_semctl
+ .quad sys_semget /* 205 */
+ .quad sys_semop
+ .quad osf_utsname
+ .quad alpha_ni_syscall
+ .quad osf_shmat
+ .quad sys_shmctl /* 210 */
+ .quad sys_shmdt
+ .quad sys_shmget
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 215 */
+ .quad alpha_ni_syscall
+ .quad sys_msync
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 220 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 225 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 230 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad sys_getpgid
+ .quad sys_getsid
+ .quad alpha_ni_syscall /* 235 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 240 */
+ .quad osf_sysinfo
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad osf_proplist_syscall
+ .quad alpha_ni_syscall /* 245 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 250 */
+ .quad osf_usleep_thread
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad sys_sysfs
+ .quad alpha_ni_syscall /* 255 */
+ .quad osf_getsysinfo
+ .quad osf_setsysinfo
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 260 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 265 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 270 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 275 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 280 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 285 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 290 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 295 */
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
/* linux-specific system calls start at 300 */
-/*300*/ .quad sys_bdflush, sys_sethae, sys_mount, sys_adjtimex, sys_swapoff
- .quad sys_getdents, alpha_create_module, sys_init_module, sys_delete_module, sys_get_kernel_syms
- .quad sys_syslog, sys_reboot, sys_clone, sys_uselib, sys_mlock
- .quad sys_munlock, sys_mlockall, sys_munlockall, sys_sysinfo, sys_sysctl
- .quad sys_idle, sys_umount, sys_swapon, sys_times, sys_personality
- .quad sys_setfsuid, sys_setfsgid, sys_ustat, sys_statfs, sys_fstatfs
- .quad sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler, sys_sched_yield
- .quad sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, do_entSys /* sys_afs_syscall */, sys_newuname
- .quad sys_nanosleep, sys_mremap, sys_nfsservctl, sys_setresuid, sys_getresuid
- .quad sys_pciconfig_read, sys_pciconfig_write, sys_query_module
- .quad sys_prctl, sys_pread, sys_pwrite
- .quad do_entSys, do_entSys
+ .quad sys_bdflush /* 300 */
+ .quad sys_sethae
+ .quad sys_mount
+ .quad sys_adjtimex
+ .quad sys_swapoff
+ .quad sys_getdents /* 305 */
+ .quad alpha_create_module
+ .quad sys_init_module
+ .quad sys_delete_module
+ .quad sys_get_kernel_syms
+ .quad sys_syslog /* 310 */
+ .quad sys_reboot
+ .quad sys_clone
+ .quad sys_uselib
+ .quad sys_mlock
+ .quad sys_munlock /* 315 */
+ .quad sys_mlockall
+ .quad sys_munlockall
+ .quad sys_sysinfo
+ .quad sys_sysctl
+ .quad sys_idle /* 320 */
+ .quad sys_umount
+ .quad sys_swapon
+ .quad sys_times
+ .quad sys_personality
+ .quad sys_setfsuid /* 325 */
+ .quad sys_setfsgid
+ .quad sys_ustat
+ .quad sys_statfs
+ .quad sys_fstatfs
+ .quad sys_sched_setparam /* 330 */
+ .quad sys_sched_getparam
+ .quad sys_sched_setscheduler
+ .quad sys_sched_getscheduler
+ .quad sys_sched_yield
+ .quad sys_sched_get_priority_max /* 335 */
+ .quad sys_sched_get_priority_min
+ .quad sys_sched_rr_get_interval
+ .quad alpha_ni_syscall /* sys_afs_syscall */
+ .quad sys_newuname
+ .quad sys_nanosleep /* 340 */
+ .quad sys_mremap
+ .quad sys_nfsservctl
+ .quad sys_setresuid
+ .quad sys_getresuid
+ .quad sys_pciconfig_read /* 345 */
+ .quad sys_pciconfig_write
+ .quad sys_query_module
+ .quad sys_prctl
+ .quad sys_pread
+ .quad sys_pwrite /* 350 */
+ .quad sys_rt_sigreturn
+ .quad sys_rt_sigaction
+ .quad sys_rt_sigprocmask
+ .quad sys_rt_sigpending
+ .quad sys_rt_sigtimedwait /* 355 */
+ .quad sys_rt_sigqueueinfo
+ .quad sys_rt_sigsuspend
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall
+ .quad alpha_ni_syscall /* 360 */
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index a736704a0..e64b6d5e1 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -28,6 +28,7 @@
#include <linux/stat.h>
#include <linux/mman.h>
#include <linux/shm.h>
+#include <linux/poll.h>
#include <asm/fpu.h>
#include <asm/io.h>
@@ -167,6 +168,9 @@ out:
return error;
}
+#undef ROUND_UP
+#undef NAME_OFFSET
+
/*
* Alpha syscall convention has no problem returning negative
* values:
@@ -202,24 +206,24 @@ asmlinkage unsigned long sys_madvise(void)
/*
* No need to acquire the kernel lock, we're local..
*/
-asmlinkage unsigned long sys_getxuid(int a0, int a1, int a2, int a3, int a4, int a5,
- struct pt_regs regs)
+asmlinkage unsigned long sys_getxuid(int a0, int a1, int a2, int a3, int a4,
+ int a5, struct pt_regs regs)
{
struct task_struct * tsk = current;
(&regs)->r20 = tsk->euid;
return tsk->uid;
}
-asmlinkage unsigned long sys_getxgid(int a0, int a1, int a2, int a3, int a4, int a5,
- struct pt_regs regs)
+asmlinkage unsigned long sys_getxgid(int a0, int a1, int a2, int a3, int a4,
+ int a5, struct pt_regs regs)
{
struct task_struct * tsk = current;
(&regs)->r20 = tsk->egid;
return tsk->gid;
}
-asmlinkage unsigned long sys_getxpid(int a0, int a1, int a2, int a3, int a4, int a5,
- struct pt_regs regs)
+asmlinkage unsigned long sys_getxpid(int a0, int a1, int a2, int a3, int a4,
+ int a5, struct pt_regs regs)
{
struct task_struct *tsk = current;
@@ -524,47 +528,6 @@ asmlinkage int osf_umount(char *path, int flag)
return ret;
}
-/*
- * I don't know what the parameters are: the first one
- * seems to be a timeval pointer, and I suspect the second
- * one is the time remaining.. Ho humm.. No documentation.
- */
-asmlinkage int osf_usleep_thread(struct timeval *sleep, struct timeval *remain)
-{
- struct timeval tmp;
- unsigned long ticks;
- int retval;
-
- lock_kernel();
- retval = verify_area(VERIFY_READ, sleep, sizeof(*sleep));
- if (retval)
- goto out;
- if (remain && (retval = verify_area(VERIFY_WRITE, remain, sizeof(*remain))))
- goto out;
- copy_from_user(&tmp, sleep, sizeof(*sleep));
- ticks = tmp.tv_usec;
- ticks = (ticks + (1000000 / HZ) - 1) / (1000000 / HZ);
- ticks += tmp.tv_sec * HZ;
- current->timeout = ticks + jiffies;
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- retval = 0;
- if (!remain)
- goto out;
- ticks = jiffies;
- if (ticks < current->timeout)
- ticks = current->timeout - ticks;
- else
- ticks = 0;
- current->timeout = 0;
- tmp.tv_sec = ticks / HZ;
- tmp.tv_usec = ticks % HZ;
- copy_to_user(remain, &tmp, sizeof(*remain));
-out:
- unlock_kernel();
- return retval;
-}
-
asmlinkage int osf_utsname(char *name)
{
int error;
@@ -956,3 +919,358 @@ asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer,
return -EOPNOTSUPP;
}
+
+/* Translations due to the fact that OSF's time_t is an int. Which
+ affects all sorts of things, like timeval and itimerval. */
+
+extern struct timezone sys_tz;
+extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
+extern int do_getitimer(int which, struct itimerval *value);
+extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
+asmlinkage int sys_utimes(char *, struct timeval *);
+extern int sys_wait4(pid_t, int *, int, struct rusage *);
+
+struct timeval32
+{
+ int tv_sec, tv_usec;
+};
+
+struct itimerval32
+{
+ struct timeval32 it_interval;
+ struct timeval32 it_value;
+};
+
+static inline long get_tv32(struct timeval *o, struct timeval32 *i)
+{
+ return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
+ (__get_user(o->tv_sec, &i->tv_sec) |
+ __get_user(o->tv_usec, &i->tv_usec)));
+}
+
+static inline long put_tv32(struct timeval32 *o, struct timeval *i)
+{
+ return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
+ (__put_user(i->tv_sec, &o->tv_sec) |
+ __put_user(i->tv_usec, &o->tv_usec)));
+}
+
+static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
+{
+ return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
+ (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
+ __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
+ __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
+ __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
+}
+
+static inline long put_it32(struct itimerval32 *o, struct itimerval *i)
+{
+ return (!access_ok(VERIFY_WRITE, i, sizeof(*i)) ||
+ (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
+ __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
+ __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
+ __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
+}
+
+asmlinkage int osf_gettimeofday(struct timeval32 *tv, struct timezone *tz)
+{
+ if (tv) {
+ struct timeval ktv;
+ do_gettimeofday(&ktv);
+ if (put_tv32(tv, &ktv))
+ return -EFAULT;
+ }
+ if (tz) {
+ if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
+ return -EFAULT;
+ }
+ return 0;
+}
+
+asmlinkage int osf_settimeofday(struct timeval32 *tv, struct timezone *tz)
+{
+ struct timeval ktv;
+ struct timezone ktz;
+
+ if (tv) {
+ if (get_tv32(&ktv, tv))
+ return -EFAULT;
+ }
+ if (tz) {
+ if (copy_from_user(&ktz, tz, sizeof(*tz)))
+ return -EFAULT;
+ }
+
+ return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
+}
+
+asmlinkage int osf_getitimer(int which, struct itimerval32 *it)
+{
+ struct itimerval kit;
+ int error;
+
+ error = do_getitimer(which, &kit);
+ if (!error && put_it32(it, &kit))
+ error = -EFAULT;
+
+ return error;
+}
+
+asmlinkage int osf_setitimer(int which, struct itimerval32 *in,
+ struct itimerval32 *out)
+{
+ struct itimerval kin, kout;
+ int error;
+
+ if (in) {
+ if (get_it32(&kin, in))
+ return -EFAULT;
+ } else
+ memset(&kin, 0, sizeof(kin));
+
+ error = do_setitimer(which, &kin, out ? &kout : NULL);
+ if (error || !out)
+ return error;
+
+ if (put_it32(out, &kout))
+ return -EFAULT;
+
+ return 0;
+
+}
+
+asmlinkage int osf_utimes(const char *filename, struct timeval32 *tvs)
+{
+ char *kfilename;
+ struct timeval ktvs[2];
+ mm_segment_t old_fs;
+ int ret;
+
+ kfilename = getname(filename);
+ if (IS_ERR(kfilename))
+ return PTR_ERR(kfilename);
+
+ if (tvs) {
+ if (get_tv32(&ktvs[0], &tvs[0]) ||
+ get_tv32(&ktvs[1], &tvs[1]))
+ return -EFAULT;
+ }
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = sys_utimes(kfilename, tvs ? ktvs : 0);
+ set_fs(old_fs);
+
+ putname(kfilename);
+
+ return ret;
+}
+
+asmlinkage int
+osf_select(int n, fd_set *inp, fd_set *outp, fd_set *exp,
+ struct timeval32 *tvp)
+{
+ fd_set_buffer *fds;
+ unsigned long timeout;
+ int ret;
+
+ timeout = ~0UL;
+ if (tvp) {
+ time_t sec, usec;
+
+ if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
+ || (ret = __get_user(sec, &tvp->tv_sec))
+ || (ret = __get_user(usec, &tvp->tv_usec)))
+ goto out_nofds;
+
+ timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
+ timeout += sec * HZ;
+ if (timeout)
+ timeout += jiffies + 1;
+ }
+
+ ret = -ENOMEM;
+ fds = (fd_set_buffer *) __get_free_page(GFP_KERNEL);
+ if (!fds)
+ goto out_nofds;
+ ret = -EINVAL;
+ if (n < 0)
+ goto out;
+ if (n > KFDS_NR)
+ n = KFDS_NR;
+ if ((ret = get_fd_set(n, inp->fds_bits, fds->in)) ||
+ (ret = get_fd_set(n, outp->fds_bits, fds->out)) ||
+ (ret = get_fd_set(n, exp->fds_bits, fds->ex)))
+ goto out;
+ zero_fd_set(n, fds->res_in);
+ zero_fd_set(n, fds->res_out);
+ zero_fd_set(n, fds->res_ex);
+
+ ret = do_select(n, fds, timeout);
+
+ /* OSF does not copy back the remaining time. */
+
+ if (ret < 0)
+ goto out;
+ if (!ret) {
+ ret = -ERESTARTNOHAND;
+ if (signal_pending(current))
+ goto out;
+ ret = 0;
+ }
+
+ set_fd_set(n, inp->fds_bits, fds->res_in);
+ set_fd_set(n, outp->fds_bits, fds->res_out);
+ set_fd_set(n, exp->fds_bits, fds->res_ex);
+
+out:
+ free_page((unsigned long) fds);
+out_nofds:
+ return ret;
+}
+
+struct rusage32 {
+ struct timeval32 ru_utime; /* user time used */
+ struct timeval32 ru_stime; /* system time used */
+ long ru_maxrss; /* maximum resident set size */
+ long ru_ixrss; /* integral shared memory size */
+ long ru_idrss; /* integral unshared data size */
+ long ru_isrss; /* integral unshared stack size */
+ long ru_minflt; /* page reclaims */
+ long ru_majflt; /* page faults */
+ long ru_nswap; /* swaps */
+ long ru_inblock; /* block input operations */
+ long ru_oublock; /* block output operations */
+ long ru_msgsnd; /* messages sent */
+ long ru_msgrcv; /* messages received */
+ long ru_nsignals; /* signals received */
+ long ru_nvcsw; /* voluntary context switches */
+ long ru_nivcsw; /* involuntary " */
+};
+
+asmlinkage int osf_getrusage(int who, struct rusage32 *ru)
+{
+ struct rusage32 r;
+
+ if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
+ return -EINVAL;
+
+ memset(&r, 0, sizeof(r));
+ switch (who) {
+ case RUSAGE_SELF:
+ r.ru_utime.tv_sec = CT_TO_SECS(current->times.tms_utime);
+ r.ru_utime.tv_usec = CT_TO_USECS(current->times.tms_utime);
+ r.ru_stime.tv_sec = CT_TO_SECS(current->times.tms_stime);
+ r.ru_stime.tv_usec = CT_TO_USECS(current->times.tms_stime);
+ r.ru_minflt = current->min_flt;
+ r.ru_majflt = current->maj_flt;
+ r.ru_nswap = current->nswap;
+ break;
+ case RUSAGE_CHILDREN:
+ r.ru_utime.tv_sec = CT_TO_SECS(current->times.tms_cutime);
+ r.ru_utime.tv_usec = CT_TO_USECS(current->times.tms_cutime);
+ r.ru_stime.tv_sec = CT_TO_SECS(current->times.tms_cstime);
+ r.ru_stime.tv_usec = CT_TO_USECS(current->times.tms_cstime);
+ r.ru_minflt = current->cmin_flt;
+ r.ru_majflt = current->cmaj_flt;
+ r.ru_nswap = current->cnswap;
+ break;
+ default:
+ r.ru_utime.tv_sec = CT_TO_SECS(current->times.tms_utime +
+ current->times.tms_cutime);
+ r.ru_utime.tv_usec = CT_TO_USECS(current->times.tms_utime +
+ current->times.tms_cutime);
+ r.ru_stime.tv_sec = CT_TO_SECS(current->times.tms_stime +
+ current->times.tms_cstime);
+ r.ru_stime.tv_usec = CT_TO_USECS(current->times.tms_stime +
+ current->times.tms_cstime);
+ r.ru_minflt = current->min_flt + current->cmin_flt;
+ r.ru_majflt = current->maj_flt + current->cmaj_flt;
+ r.ru_nswap = current->nswap + current->cnswap;
+ break;
+ }
+
+ return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
+}
+
+asmlinkage int osf_wait4(pid_t pid, int *ustatus, int options,
+ struct rusage32 *ur)
+{
+ if (!ur) {
+ return sys_wait4(pid, ustatus, options, NULL);
+ } else {
+ struct rusage r;
+ int ret, status;
+ mm_segment_t old_fs = get_fs();
+
+ set_fs (KERNEL_DS);
+ ret = sys_wait4(pid, &status, options, &r);
+ set_fs (old_fs);
+
+ if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
+ return -EFAULT;
+ __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
+ __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
+ __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
+ __put_user(r.ru_stime.tv_usec, &ur->ru_stime.tv_usec);
+ __put_user(r.ru_maxrss, &ur->ru_maxrss);
+ __put_user(r.ru_ixrss, &ur->ru_ixrss);
+ __put_user(r.ru_idrss, &ur->ru_idrss);
+ __put_user(r.ru_isrss, &ur->ru_isrss);
+ __put_user(r.ru_minflt, &ur->ru_minflt);
+ __put_user(r.ru_majflt, &ur->ru_majflt);
+ __put_user(r.ru_nswap, &ur->ru_nswap);
+ __put_user(r.ru_inblock, &ur->ru_inblock);
+ __put_user(r.ru_oublock, &ur->ru_oublock);
+ __put_user(r.ru_msgsnd, &ur->ru_msgsnd);
+ __put_user(r.ru_msgrcv, &ur->ru_msgrcv);
+ __put_user(r.ru_nsignals, &ur->ru_nsignals);
+ __put_user(r.ru_nvcsw, &ur->ru_nvcsw);
+ if (__put_user(r.ru_nivcsw, &ur->ru_nivcsw))
+ return -EFAULT;
+
+ if (ustatus && put_user(status, ustatus))
+ return -EFAULT;
+ return ret;
+ }
+}
+
+/*
+ * I don't know what the parameters are: the first one
+ * seems to be a timeval pointer, and I suspect the second
+ * one is the time remaining.. Ho humm.. No documentation.
+ */
+asmlinkage int osf_usleep_thread(struct timeval *sleep, struct timeval *remain)
+{
+ struct timeval tmp;
+ unsigned long ticks;
+
+ if (get_tv32(&tmp, sleep))
+ goto fault;
+
+ ticks = tmp.tv_usec;
+ ticks = (ticks + (1000000 / HZ) - 1) / (1000000 / HZ);
+ ticks += tmp.tv_sec * HZ;
+ current->timeout = ticks + jiffies;
+ current->state = TASK_INTERRUPTIBLE;
+
+ schedule();
+
+ if (remain) {
+ ticks = jiffies;
+ if (ticks < current->timeout)
+ ticks = current->timeout - ticks;
+ else
+ ticks = 0;
+ current->timeout = 0;
+ tmp.tv_sec = ticks / HZ;
+ tmp.tv_usec = ticks % HZ;
+ if (put_tv32(remain, &tmp))
+ goto fault;
+ }
+
+ return 0;
+fault:
+ return -EFAULT;
+}
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index 84cde1b4f..38cb5e05d 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -574,7 +574,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data,
(return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
ret = -EIO;
- if ((unsigned long) data > NSIG)
+ if ((unsigned long) data > _NSIG)
goto out;
if (request == PTRACE_SYSCALL)
child->flags |= PF_TRACESYS;
@@ -606,7 +606,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data,
case PTRACE_SINGLESTEP: { /* execute single instruction. */
ret = -EIO;
- if ((unsigned long) data > NSIG)
+ if ((unsigned long) data > _NSIG)
goto out;
child->debugreg[4] = -1; /* mark single-stepping */
child->flags &= ~PF_TRACESYS;
@@ -619,7 +619,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data,
case PTRACE_DETACH: { /* detach a process that was attached. */
ret = -EIO;
- if ((unsigned long) data > NSIG)
+ if ((unsigned long) data > _NSIG)
goto out;
child->flags &= ~(PF_PTRACED|PF_TRACESYS);
wake_up_process(child);
@@ -627,7 +627,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data,
REMOVE_LINKS(child);
child->p_pptr = child->p_opptr;
SET_LINKS(child);
- /* make sure single-step breakpoint is gone. */
+ /* make sure single-step breakpoint is gone. */
ptrace_cancel_bpt(child);
ret = 0;
goto out;
@@ -644,22 +644,20 @@ out:
asmlinkage void syscall_trace(void)
{
- lock_kernel();
if ((current->flags & (PF_PTRACED|PF_TRACESYS))
!= (PF_PTRACED|PF_TRACESYS))
- goto out;
+ return;
current->exit_code = SIGTRAP;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
schedule();
/*
- * this isn't the same as continuing with a signal, but it will do
+ * This isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the
* stopping signal is not SIGTRAP. -brl
*/
- if (current->exit_code)
- current->signal |= (1 << (current->exit_code - 1));
- current->exit_code = 0;
-out:
- unlock_kernel();
+ if (current->exit_code) {
+ send_sig(current->exit_code, current, 1);
+ current->exit_code = 0;
+ }
}
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index 9f71e6146..1d4e8931d 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -2,6 +2,8 @@
* linux/arch/alpha/kernel/signal.c
*
* Copyright (C) 1995 Linus Torvalds
+ *
+ * 1997-11-02 Modified for POSIX.1b signals by Richard Henderson
*/
#include <linux/sched.h>
@@ -14,21 +16,27 @@
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
+#include <linux/signal.h>
+#include <linux/stddef.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
+#include <asm/sigcontext.h>
+#include <asm/ucontext.h>
+
+#define DEBUG_SIG 0
-#define _S(nr) (1<<((nr)-1))
-#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
asmlinkage int sys_wait4(int, int *, int, struct rusage *);
asmlinkage void ret_from_sys_call(void);
-asmlinkage int do_signal(unsigned long, struct pt_regs *, struct switch_stack *,
- unsigned long, unsigned long);
+asmlinkage int do_signal(sigset_t *, struct pt_regs *,
+ struct switch_stack *, unsigned long, unsigned long);
extern int ptrace_set_bpt (struct task_struct *child);
extern int ptrace_cancel_bpt (struct task_struct *child);
+
/*
* The OSF/1 sigprocmask calling sequence is different from the
* C sigprocmask() sequence..
@@ -44,51 +52,153 @@ extern int ptrace_cancel_bpt (struct task_struct *child);
* Note that we don't need to acquire the kernel lock for SMP
* operation, as all of this is local to this thread.
*/
-asmlinkage unsigned long osf_sigprocmask(int how, unsigned long newmask,
- long a2, long a3, long a4, long a5, struct pt_regs regs)
+asmlinkage unsigned long
+osf_sigprocmask(int how, unsigned long newmask, long a2, long a3,
+ long a4, long a5, struct pt_regs regs)
{
- unsigned long ok, oldmask;
- struct task_struct * tsk;
-
- ok = how-1; /* 0 .. 2 */
- tsk = current;
- ok = ok <= 2;
- oldmask = -EINVAL;
- if (ok) {
- long sign; /* -1 .. 1 */
+ unsigned long oldmask = -EINVAL;
+
+ if ((unsigned long)how-1 <= 2) {
+ long sign = how-2; /* -1 .. 1 */
unsigned long block, unblock;
- oldmask = tsk->blocked;
newmask &= _BLOCKABLE;
- sign = how-2;
+ spin_lock_irq(&current->sigmask_lock);
+ oldmask = current->blocked.sig[0];
+
unblock = oldmask & ~newmask;
block = oldmask | newmask;
if (!sign)
block = unblock;
- regs.r0 = 0; /* special no error return */
if (sign <= 0)
newmask = block;
- tsk->blocked = newmask;
+ if (_NSIG_WORDS > 1 && sign > 0)
+ sigemptyset(&current->blocked);
+ current->blocked.sig[0] = newmask;
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ (&regs)->r0 = 0; /* special no error return */
}
return oldmask;
}
+asmlinkage int
+osf_sigaction(int sig, const struct osf_sigaction *act,
+ struct osf_sigaction *oact)
+{
+ struct k_sigaction new_ka, old_ka;
+ int ret;
+
+ if (act) {
+ old_sigset_t mask;
+ if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+ __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+ __get_user(new_ka.sa.sa_flags, &act->sa_flags))
+ return -EFAULT;
+ __get_user(mask, &act->sa_mask);
+ siginitset(&new_ka.sa.sa_mask, mask);
+ new_ka.ka_restorer = NULL;
+ }
+
+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+ if (!ret && oact) {
+ if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
+ return -EFAULT;
+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+ }
+
+ return ret;
+}
+
+asmlinkage int
+sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact,
+ void *restorer, size_t sigsetsize)
+{
+ struct k_sigaction new_ka, old_ka;
+ int ret;
+
+ /* XXX: Don't preclude handling different sized sigset_t's. */
+ if (sigsetsize != sizeof(sigset_t))
+ return -EINVAL;
+
+ if (act) {
+ new_ka.ka_restorer = restorer;
+ if (copy_from_user(&new_ka.sa, act, sizeof(*act)))
+ return -EFAULT;
+ }
+
+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+ if (!ret && oact) {
+ if (copy_to_user(oact, &old_ka.sa, sizeof(*oact)))
+ return -EFAULT;
+ }
+
+ return ret;
+}
+
+asmlinkage int
+osf_sigpending(old_sigset_t *set)
+{
+ sigset_t pending;
+
+ spin_lock_irq(&current->sigmask_lock);
+ sigandsets(&pending, &current->blocked, &current->signal);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ return copy_to_user(set, &pending, sizeof(*set));
+}
+
/*
- * atomically swap in the new signal mask, and wait for a signal.
+ * Atomically swap in the new signal mask, and wait for a signal.
*/
-asmlinkage int do_sigsuspend(unsigned long mask, struct pt_regs * regs, struct switch_stack * sw)
+asmlinkage int
+do_sigsuspend(old_sigset_t mask, struct pt_regs *reg, struct switch_stack *sw)
+{
+ sigset_t oldset;
+
+ mask &= _BLOCKABLE;
+ spin_lock_irq(&current->sigmask_lock);
+ oldset = current->blocked;
+ siginitset(&current->blocked, mask);
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ while (1) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ if (do_signal(&oldset, reg, sw, 0, 0))
+ return -EINTR;
+ }
+}
+
+asmlinkage int
+do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize,
+ struct pt_regs *reg, struct switch_stack *sw)
{
- unsigned long oldmask;
+ sigset_t oldset, set;
+ /* XXX: Don't preclude handling different sized sigset_t's. */
+ if (sigsetsize != sizeof(sigset_t))
+ return -EINVAL;
+ if (copy_from_user(&set, uset, sizeof(set)))
+ return -EFAULT;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
spin_lock_irq(&current->sigmask_lock);
- oldmask = current->blocked;
- current->blocked = mask & _BLOCKABLE;
+ oldset = current->blocked;
+ current->blocked = set;
+ recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(oldmask, regs, sw, 0, 0))
+ if (do_signal(&oldset, reg, sw, 0, 0))
return -EINTR;
}
}
@@ -96,26 +206,35 @@ asmlinkage int do_sigsuspend(unsigned long mask, struct pt_regs * regs, struct s
/*
* Do a signal return; undo the signal stack.
*/
-asmlinkage void do_sigreturn(struct sigcontext * sc,
- struct pt_regs * regs, struct switch_stack * sw)
+
+struct sigframe
{
- unsigned long mask, ps, usp;
- int i;
+ struct sigcontext sc;
+ unsigned long extramask[_NSIG_WORDS-1];
+ unsigned int retcode[3];
+};
- /* verify that it's a good sigcontext before using it */
- if (verify_area(VERIFY_READ, sc, sizeof(*sc)))
- goto give_sigsegv;
- if (__get_user(ps, &sc->sc_ps) || ps != 8)
- goto give_sigsegv;
- if (__get_user(mask, &sc->sc_mask) || (mask & ~_BLOCKABLE))
- goto give_sigsegv;
+struct rt_sigframe
+{
+ struct siginfo info;
+ struct ucontext uc;
+ unsigned int retcode[3];
+};
+
+#define INSN_MOV_R30_R16 0x47fe0410
+#define INSN_LDI_R0 0x201f0000
+#define INSN_CALLSYS 0x00000083
+
+
+static void
+restore_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+ struct switch_stack *sw)
+{
+ unsigned long usp;
+ int i;
- /* ok, looks fine, start restoring */
- __get_user(usp, sc->sc_regs+30);
- wrusp(usp);
__get_user(regs->pc, &sc->sc_pc);
sw->r26 = (unsigned long) ret_from_sys_call;
- current->blocked = mask;
__get_user(regs->r0, sc->sc_regs+0);
__get_user(regs->r1, sc->sc_regs+1);
@@ -147,47 +266,98 @@ asmlinkage void do_sigreturn(struct sigcontext * sc,
__get_user(regs->r27, sc->sc_regs+27);
__get_user(regs->r28, sc->sc_regs+28);
__get_user(regs->gp, sc->sc_regs+29);
+ __get_user(usp, sc->sc_regs+30);
+ wrusp(usp);
+
for (i = 0; i < 31; i++)
__get_user(sw->fp[i], sc->sc_fpregs+i);
+ __get_user(sw->fp[31], &sc->sc_fpcr);
+}
- /* send SIGTRAP if we're single-stepping: */
- lock_kernel();
+asmlinkage void
+do_sigreturn(struct sigframe *frame, struct pt_regs *regs,
+ struct switch_stack *sw)
+{
+ unsigned long ps;
+ sigset_t set;
+
+ /* Verify that it's a good sigcontext before using it */
+ if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+ goto give_sigsegv;
+ if (__get_user(ps, &frame->sc.sc_ps) || ps != 8)
+ goto give_sigsegv;
+ if (__get_user(set.sig[0], &frame->sc.sc_mask)
+ || (_NSIG_WORDS > 1
+ && __copy_from_user(&set.sig[1], &frame->extramask,
+ sizeof(frame->extramask))))
+ goto give_sigsegv;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sigmask_lock);
+ current->blocked = set;
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ restore_sigcontext(&frame->sc, regs, sw);
+
+ /* Send SIGTRAP if we're single-stepping: */
if (ptrace_cancel_bpt (current))
send_sig(SIGTRAP, current, 1);
- unlock_kernel();
return;
give_sigsegv:
lock_kernel();
do_exit(SIGSEGV);
- unlock_kernel();
}
-/*
- * Set up a signal frame...
- */
-static void setup_frame(struct sigaction * sa,
- struct pt_regs * regs,
- struct switch_stack * sw, int signr,
- unsigned long oldmask)
+asmlinkage void
+do_rt_sigreturn(struct rt_sigframe *frame, struct pt_regs *regs,
+ struct switch_stack *sw)
{
- int i;
- unsigned long oldsp;
- struct sigcontext * sc;
+ unsigned long ps;
+ sigset_t set;
- oldsp = rdusp();
- sc = ((struct sigcontext *) oldsp) - 1;
+ /* Verify that it's a good sigcontext before using it */
+ if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+ goto give_sigsegv;
+ if (__get_user(ps, &frame->uc.uc_mcontext.sc_ps) || ps != 8)
+ goto give_sigsegv;
+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+ goto give_sigsegv;
- /* check here if we would need to switch stacks.. */
- if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
- do_exit(SIGSEGV);
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sigmask_lock);
+ current->blocked = set;
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
- wrusp((unsigned long) sc);
+ restore_sigcontext(&frame->uc.uc_mcontext, regs, sw);
- __put_user(oldmask, &sc->sc_mask);
- __put_user(8, &sc->sc_ps);
+ /* Send SIGTRAP if we're single-stepping: */
+ if (ptrace_cancel_bpt (current))
+ send_sig(SIGTRAP, current, 1);
+ return;
+
+give_sigsegv:
+ lock_kernel();
+ do_exit(SIGSEGV);
+}
+
+
+/*
+ * Set up a signal frame.
+ */
+
+static void
+setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+ struct switch_stack *sw, unsigned long mask, unsigned long sp)
+{
+ long i;
+
+ __put_user(0, &sc->sc_onstack);
+ __put_user(mask, &sc->sc_mask);
__put_user(regs->pc, &sc->sc_pc);
- __put_user(oldsp, sc->sc_regs+30);
+ __put_user(8, &sc->sc_ps);
__put_user(regs->r0 , sc->sc_regs+0);
__put_user(regs->r1 , sc->sc_regs+1);
@@ -219,63 +389,167 @@ static void setup_frame(struct sigaction * sa,
__put_user(regs->r27, sc->sc_regs+27);
__put_user(regs->r28, sc->sc_regs+28);
__put_user(regs->gp , sc->sc_regs+29);
+ __put_user(sp, sc->sc_regs+30);
+ __put_user(0, sc->sc_regs+31);
+
for (i = 0; i < 31; i++)
__put_user(sw->fp[i], sc->sc_fpregs+i);
+ __put_user(0, sc->sc_fpregs+31);
+ __put_user(sw->fp[31], &sc->sc_fpcr);
+
__put_user(regs->trap_a0, &sc->sc_traparg_a0);
__put_user(regs->trap_a1, &sc->sc_traparg_a1);
__put_user(regs->trap_a2, &sc->sc_traparg_a2);
+}
+
+static void
+setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
+ struct pt_regs *regs, struct switch_stack * sw)
+{
+ unsigned long oldsp;
+ struct sigframe *frame;
+
+ oldsp = rdusp();
+ frame = (struct sigframe *)((oldsp - sizeof(*frame)) & -32);
+
+ /* XXX: Check here if we would need to switch stacks.. */
+ if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
+ goto give_sigsegv;
+
+ setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp);
+ if (_NSIG_WORDS > 1) {
+ __copy_to_user(frame->extramask, &set->sig[1],
+ sizeof(frame->extramask));
+ }
+
+ /* Set up to return from userspace. If provided, use a stub
+ already in userspace. */
+ if (ka->ka_restorer) {
+ regs->r26 = (unsigned long) ka->ka_restorer;
+ } else {
+ __put_user(INSN_MOV_R30_R16, frame->retcode+0);
+ __put_user(INSN_LDI_R0+__NR_sigreturn, frame->retcode+1);
+ __put_user(INSN_CALLSYS, frame->retcode+2);
+ imb();
+ regs->r26 = (unsigned long) frame->retcode;
+ }
+
+ /* "Return" to the handler */
+ regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler;
+ regs->r16 = sig; /* a0: signal number */
+ regs->r17 = 0; /* a1: exception code */
+ regs->r18 = (unsigned long) &frame->sc; /* a2: sigcontext pointer */
+ wrusp((unsigned long) frame);
+
+#if DEBUG_SIG
+ printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
+ current->comm, current->pid, frame, regs->pc, regs->r26);
+#endif
+
+ return;
+
+give_sigsegv:
+ lock_kernel();
+ do_exit(SIGSEGV);
+}
+
+static void
+setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *set, struct pt_regs *regs, struct switch_stack * sw)
+{
+ unsigned long oldsp;
+ struct rt_sigframe *frame;
+
+ oldsp = rdusp();
+ frame = (struct rt_sigframe *)((oldsp - sizeof(*frame)) & -32);
+
+ /* XXX: Check here if we would need to switch stacks.. */
+ if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
+ goto give_sigsegv;
+
+ __copy_to_user(&frame->info, info, sizeof(siginfo_t));
+
+ /* Zero all bits of the ucontext besides the sigcontext. */
+ __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
+
+ /* Copy in the bits we actually use. */
+ __put_user(set->sig[0], &frame->uc.uc_osf_sigmask);
+ setup_sigcontext(&frame->uc.uc_mcontext, regs, sw, set->sig[0], oldsp);
+ __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+ /* Set up to return from userspace. If provided, use a stub
+ already in userspace. */
+ if (ka->ka_restorer) {
+ regs->r26 = (unsigned long) ka->ka_restorer;
+ } else {
+ __put_user(INSN_MOV_R30_R16, frame->retcode+0);
+ __put_user(INSN_LDI_R0+__NR_rt_sigreturn, frame->retcode+1);
+ __put_user(INSN_CALLSYS, frame->retcode+2);
+ imb();
+ regs->r26 = (unsigned long) frame->retcode;
+ }
- /*
- * The following is:
- *
- * bis $30,$30,$16
- * addq $31,0x67,$0
- * call_pal callsys
- *
- * ie, "sigreturn(stack-pointer)"
- */
- __put_user(0x43ecf40047de0410, sc->sc_retcode+0);
- __put_user(0x0000000000000083, sc->sc_retcode+1);
- imb();
-
- /* "return" to the handler */
- regs->r27 = regs->pc = (unsigned long) sa->sa_handler;
- regs->r26 = (unsigned long) sc->sc_retcode;
- regs->r16 = signr; /* a0: signal number */
- regs->r17 = 0; /* a1: exception code; see gentrap.h */
- regs->r18 = (unsigned long) sc; /* a2: sigcontext pointer */
+ /* "Return" to the handler */
+ regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler;
+ regs->r16 = sig; /* a0: signal number */
+ regs->r17 = (unsigned long) &frame->info; /* a1: siginfo pointer */
+ regs->r18 = (unsigned long) &frame->uc; /* a2: ucontext pointer */
+ wrusp((unsigned long) frame);
+
+#if DEBUG_SIG
+ printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
+ current->comm, current->pid, frame, regs->pc, regs->r26);
+#endif
+
+ return;
+
+give_sigsegv:
+ lock_kernel();
+ do_exit(SIGSEGV);
}
+
/*
- * OK, we're invoking a handler
+ * OK, we're invoking a handler.
*/
-static inline void handle_signal(unsigned long signr, struct sigaction *sa,
- unsigned long oldmask, struct pt_regs * regs, struct switch_stack *sw)
+static inline void
+handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw)
{
- setup_frame(sa,regs,sw,signr,oldmask);
-
- if (sa->sa_flags & SA_ONESHOT)
- sa->sa_handler = NULL;
- if (!(sa->sa_flags & SA_NOMASK))
- current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE;
+ if (ka->sa.sa_flags & SA_SIGINFO)
+ setup_rt_frame(sig, ka, info, oldset, regs, sw);
+ else
+ setup_frame(sig, ka, oldset, regs, sw);
+
+ if (ka->sa.sa_flags & SA_RESETHAND)
+ ka->sa.sa_handler = SIG_DFL;
+
+ if (!(ka->sa.sa_flags & SA_NODEFER)) {
+ spin_lock_irq(&current->sigmask_lock);
+ sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+ sigaddset(&current->blocked,sig);
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+ }
}
-static inline void syscall_restart(unsigned long r0, unsigned long r19,
- struct pt_regs * regs, struct sigaction * sa)
+static inline void
+syscall_restart(unsigned long r0, unsigned long r19,
+ struct pt_regs *regs, struct k_sigaction *ka)
{
switch (regs->r0) {
+ case ERESTARTSYS:
+ if (!(ka->sa.sa_flags & SA_RESTART)) {
case ERESTARTNOHAND:
- no_system_call_restart:
regs->r0 = EINTR;
break;
- case ERESTARTSYS:
- if (!(sa->sa_flags & SA_RESTART))
- goto no_system_call_restart;
+ }
/* fallthrough */
- case ERESTARTNOINTR:
- regs->r0 = r0; /* reset v0 and a3 and replay syscall */
- regs->r19 = r19;
- regs->pc -= 4;
+ case ERESTARTNOINTR:
+ regs->r0 = r0; /* reset v0 and a3 and replay syscall */
+ regs->r19 = r19;
+ regs->pc -= 4;
+ break;
}
}
@@ -293,53 +567,77 @@ static inline void syscall_restart(unsigned long r0, unsigned long r19,
* restart. "r0" is also used as an indicator whether we can restart at
* all (if we get here from anything but a syscall return, it will be 0)
*/
-asmlinkage int do_signal(unsigned long oldmask,
- struct pt_regs * regs,
- struct switch_stack * sw,
- unsigned long r0, unsigned long r19)
+asmlinkage int
+do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
+ unsigned long r0, unsigned long r19)
{
- unsigned long mask;
- unsigned long signr, single_stepping;
- struct sigaction * sa;
- int ret;
+ unsigned long single_stepping = ptrace_cancel_bpt(current);
+
+ if (!oldset)
+ oldset = &current->blocked;
+
+ while (1) {
+ unsigned long signr;
+ struct k_sigaction *ka;
+ siginfo_t info;
+
+ spin_lock_irq(&current->sigmask_lock);
+ signr = dequeue_signal(&current->blocked, &info);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ if (!signr)
+ break;
- lock_kernel();
- mask = ~current->blocked;
- single_stepping = ptrace_cancel_bpt(current);
-
- while ((signr = current->signal & mask) != 0) {
- signr = ffz(~signr);
- clear_bit(signr, &current->signal);
- sa = current->sig->action + signr;
- signr++;
if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+ /* Let the debugger run. */
current->exit_code = signr;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
schedule();
single_stepping |= ptrace_cancel_bpt(current);
+
+ /* We're back. Did the debugger cancel the sig? */
if (!(signr = current->exit_code))
continue;
current->exit_code = 0;
+
+ /* The debugger continued. Ignore SIGSTOP. */
if (signr == SIGSTOP)
continue;
- if (_S(signr) & current->blocked) {
- current->signal |= _S(signr);
+
+ /* Update the siginfo structure. Is this good? */
+ if (signr != info.si_signo) {
+ info.si_signo = signr;
+ info.si_errno = 0;
+ info.si_code = SI_USER;
+ info.si_pid = current->p_pptr->pid;
+ info.si_uid = current->p_pptr->uid;
+ }
+
+ /* If the (new) signal is now blocked, requeue it. */
+ if (sigismember(&current->blocked, signr)) {
+ send_sig_info(signr, &info, current);
continue;
}
- sa = current->sig->action + signr - 1;
}
- if (sa->sa_handler == SIG_IGN) {
+
+ ka = &current->sig->action[signr-1];
+ if (ka->sa.sa_handler == SIG_IGN) {
if (signr != SIGCHLD)
continue;
- /* check for SIGCHLD: it's special */
+ /* Check for SIGCHLD: it's special. */
while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
/* nothing */;
continue;
}
- if (sa->sa_handler == SIG_DFL) {
+
+ if (ka->sa.sa_handler == SIG_DFL) {
+ int exit_code = signr & 0x7f;
+
+ /* Init gets no signals it doesn't want. */
if (current->pid == 1)
continue;
+
switch (signr) {
case SIGCONT: case SIGCHLD: case SIGWINCH:
continue;
@@ -347,13 +645,13 @@ asmlinkage int do_signal(unsigned long oldmask,
case SIGTSTP: case SIGTTIN: case SIGTTOU:
if (is_orphaned_pgrp(current->pgrp))
continue;
+ /* FALLTHRU */
+
case SIGSTOP:
- if (current->flags & PF_PTRACED)
- continue;
current->state = TASK_STOPPED;
current->exit_code = signr;
- if (!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags &
- SA_NOCLDSTOP))
+ if (!(current->p_pptr->sig->action[SIGCHLD-1]
+ .sa.sa_flags & SA_NOCLDSTOP))
notify_parent(current, SIGCHLD);
schedule();
single_stepping |= ptrace_cancel_bpt(current);
@@ -361,26 +659,32 @@ asmlinkage int do_signal(unsigned long oldmask,
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- if (current->binfmt && current->binfmt->core_dump) {
- if (current->binfmt->core_dump(signr, regs))
- signr |= 0x80;
- }
- /* fall through */
+ lock_kernel();
+ if (current->binfmt
+ && current->binfmt->core_dump
+ && current->binfmt->core_dump(signr, regs))
+ exit_code |= 0x80;
+ unlock_kernel();
+ /* FALLTHRU */
+
default:
- current->signal |= _S(signr & 0x7f);
+ lock_kernel();
+ sigaddset(&current->signal, signr);
current->flags |= PF_SIGNALED;
- do_exit(signr);
+ do_exit(exit_code);
+ /* NOTREACHED */
}
+ continue;
}
- if (r0)
- syscall_restart(r0, r19, regs, sa);
- handle_signal(signr, sa, oldmask, regs, sw);
- if (single_stepping) {
- ptrace_set_bpt(current); /* re-set breakpoint */
- }
- ret = 1;
- goto out;
+
+ /* Whee! Actually deliver the signal. */
+ if (r0) syscall_restart(r0, r19, regs, ka);
+ handle_signal(signr, ka, &info, oldset, regs, sw);
+ if (single_stepping)
+ ptrace_set_bpt(current); /* re-set bpt */
+ return 1;
}
+
if (r0 &&
(regs->r0 == ERESTARTNOHAND ||
regs->r0 == ERESTARTSYS ||
@@ -389,11 +693,8 @@ asmlinkage int do_signal(unsigned long oldmask,
regs->r19 = r19;
regs->pc -= 4;
}
- if (single_stepping) {
+ if (single_stepping)
ptrace_set_bpt(current); /* re-set breakpoint */
- }
- ret = 0;
-out:
- unlock_kernel();
- return ret;
+
+ return 0;
}
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 2b0870c3b..9d8b56dc3 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -17,17 +17,18 @@
* (round system clock to nearest tick instead of truncating)
* fixed algorithm in time_init for getting time from CMOS clock
*/
+#include <linux/config.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/mm.h>
+#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/hwrpb.h>
-#include <asm/delay.h>
#include <linux/mc146818rtc.h>
#include <linux/timex.h>
@@ -52,16 +53,18 @@ static int set_rtc_mmss(unsigned long);
/* lump static variables together for more efficient access: */
static struct {
- __u32 last_time; /* cycle counter last time it got invoked */
- unsigned long scaled_ticks_per_cycle; /* ticks/cycle * 2^48 */
- long last_rtc_update; /* last time the cmos clock got updated */
+ /* cycle counter last time it got invoked */
+ __u32 last_time;
+ /* ticks/cycle * 2^48 */
+ unsigned long scaled_ticks_per_cycle;
+ /* last time the cmos clock got updated */
+ time_t last_rtc_update;
} state;
static inline __u32 rpcc(void)
{
__u32 result;
-
asm volatile ("rpcc %0" : "r="(result));
return result;
}
@@ -73,37 +76,46 @@ static inline __u32 rpcc(void)
*/
void timer_interrupt(int irq, void *dev, struct pt_regs * regs)
{
- __u32 delta, now;
- int i, nticks;
+ const unsigned long half = 1UL << (FIX_SHIFT - 1);
+ const unsigned long mask = (1UL << (FIX_SHIFT + 1)) - 1;
+ unsigned long delta;
+ __u32 now;
+ long nticks;
+ /*
+ * Estimate how many ticks have passed since the last update.
+ * Round the result, .5 to even. When we loose ticks due to
+ * say using IDE, the clock has been seen to run up to 15% slow
+ * if we truncate.
+ */
now = rpcc();
delta = now - state.last_time;
state.last_time = now;
- if(hwrpb->cycle_freq) {
- nticks = (delta * state.scaled_ticks_per_cycle) >> (FIX_SHIFT-1);
- nticks = (nticks+1) >> 1;
- }
- else nticks=1; /* No way to estimate lost ticks if we don't know
- the cycle frequency. */
- for (i = 0; i < nticks; ++i) {
+ delta = delta * state.scaled_ticks_per_cycle;
+ if ((delta & mask) != half)
+ delta += half;
+ nticks = delta >> FIX_SHIFT;
+
+ do {
do_timer(regs);
- }
+ } while (--nticks > 0);
/*
* If we have an externally synchronized Linux clock, then update
* CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
* called as close as possible to 500 ms before the new second starts.
*/
- if (time_state != TIME_BAD && xtime.tv_sec > state.last_rtc_update + 660 &&
- xtime.tv_usec > 500000 - (tick >> 1) &&
- xtime.tv_usec < 500000 + (tick >> 1))
- if (set_rtc_mmss(xtime.tv_sec) == 0)
- state.last_rtc_update = xtime.tv_sec;
- else
- state.last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+ if (time_state != TIME_BAD
+ && xtime.tv_sec > state.last_rtc_update + 660
+ && xtime.tv_usec >= 500000 - (tick >> 1)
+ && xtime.tv_usec <= 500000 + (tick >> 1)) {
+ int tmp = set_rtc_mmss(xtime.tv_sec);
+ state.last_rtc_update = xtime.tv_sec - (tmp ? 600 : 0);
+ }
}
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+/*
+ * Converts Gregorian date to seconds since 1970-01-01 00:00:00.
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
*
@@ -140,25 +152,40 @@ void time_init(void)
unsigned char save_control;
#endif
void (*irq_handler)(int, void *, struct pt_regs *);
- unsigned int year, mon, day, hour, min, sec;
+ unsigned int year, mon, day, hour, min, sec, cc1, cc2;
- /* The Linux interpretation of the CMOS clock register contents:
+ /*
+ * The Linux interpretation of the CMOS clock register contents:
* When the Update-In-Progress (UIP) flag goes from 1 to 0, the
* RTC registers show the second which has precisely just started.
* Let's hope other operating systems interpret the RTC the same way.
*/
- /* read RTC exactly on falling edge of update flag */
- /* Wait for rise.... (may take up to 1 second) */
-
- do {} while(!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
-
-/* Jay Estabook <jestabro@amt.tay1.dec.com>:
- * Wait for the Update Done Interrupt bit (0x10) in reg C (12) to be set,
- * which (hopefully) indicates that the update is really done.
- */
-
- do {} while(!CMOS_READ(RTC_REG_C) & RTC_UIP);
-
+ do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
+ do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
+
+ /* Read cycle counter exactly on falling edge of update flag */
+ cc1 = rpcc();
+
+ /* If our cycle frequency isn't valid, go another round and give
+ a guess at what it should be. */
+ if (hwrpb->cycle_freq == 0) {
+ printk("HWPRB cycle frequency bogus. Estimating... ");
+
+ do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
+ do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
+ cc2 = rpcc();
+ hwrpb->cycle_freq = cc2 - cc1;
+ cc1 = cc2;
+
+ printk("%lu Hz\n", hwrpb->cycle_freq);
+ }
+
+ /* From John Bowman <bowman@math.ualberta.ca>: allow the values
+ to settle, as the Update-In-Progress bit going low isn't good
+ enough on some hardware. 2ms is our guess; we havn't found
+ bogomips yet, but this is close on a 500Mhz box. */
+ __delay(1000000);
+
sec = CMOS_READ(RTC_SECONDS);
min = CMOS_READ(RTC_MINUTES);
hour = CMOS_READ(RTC_HOURS);
@@ -167,14 +194,14 @@ void time_init(void)
year = CMOS_READ(RTC_YEAR);
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
- {
- BCD_TO_BIN(sec);
- BCD_TO_BIN(min);
- BCD_TO_BIN(hour);
- BCD_TO_BIN(day);
- BCD_TO_BIN(mon);
- BCD_TO_BIN(year);
- }
+ {
+ BCD_TO_BIN(sec);
+ BCD_TO_BIN(min);
+ BCD_TO_BIN(hour);
+ BCD_TO_BIN(day);
+ BCD_TO_BIN(mon);
+ BCD_TO_BIN(year);
+ }
#ifdef ALPHA_PRE_V1_2_SRM_CONSOLE
/*
* The meaning of life, the universe, and everything. Plus
@@ -192,9 +219,10 @@ void time_init(void)
extern void __you_loose (void);
__you_loose();
}
- state.last_time = rpcc();
- if(hwrpb->cycle_freq)
- state.scaled_ticks_per_cycle = ((unsigned long) HZ << FIX_SHIFT) / hwrpb->cycle_freq;
+
+ state.last_time = cc1;
+ state.scaled_ticks_per_cycle
+ = ((unsigned long) HZ << FIX_SHIFT) / hwrpb->cycle_freq;
state.last_rtc_update = 0;
#ifdef CONFIG_RTC
@@ -210,22 +238,52 @@ void time_init(void)
/* setup timer */
irq_handler = timer_interrupt;
if (request_irq(TIMER_IRQ, irq_handler, 0, "timer", NULL))
- panic("Could not allocate timer IRQ!");
+ panic("Could not allocate timer IRQ!");
}
/*
- * We could get better timer accuracy by using the alpha
- * time counters or something. Now this is limited to
- * the HZ clock frequency.
+ * Use the cycle counter to estimate an displacement from the last time
+ * tick. Unfortunately the Alpha designers made only the low 32-bits of
+ * the cycle counter active, so we overflow on 8.2 seconds on a 500MHz
+ * part. So we can't do the "find absolute time in terms of cycles" thing
+ * that the other ports do.
*/
void do_gettimeofday(struct timeval *tv)
{
- unsigned long flags;
+ unsigned long flags, now, delta_cycles, delta_usec;
+ unsigned long sec, usec;
- save_flags(flags);
- cli();
- *tv = xtime;
+ now = rpcc();
+ save_and_cli(flags);
+ sec = xtime.tv_sec;
+ usec = xtime.tv_usec;
+ delta_cycles = now - state.last_time;
restore_flags(flags);
+
+ /*
+ * usec = cycles * ticks_per_cycle * 2**48 * 1e6 / (2**48 * ticks)
+ * = cycles * (s_t_p_c) * 1e6 / (2**48 * ticks)
+ * = cycles * (s_t_p_c) * 15625 / (2**42 * ticks)
+ *
+ * which, given a 600MHz cycle and a 1024Hz tick, has a
+ * dynamic range of about 1.7e17, which is less than the
+ * 1.8e19 in an unsigned long, so we are safe from overflow.
+ *
+ * Round, but with .5 up always, since .5 to even is harder
+ * with no clear gain.
+ */
+
+ delta_usec = delta_cycles * state.scaled_ticks_per_cycle * 15625;
+ delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6)) * HZ)) + 1) / 2;
+
+ usec += delta_usec;
+ if (usec >= 1000000) {
+ sec += 1;
+ usec -= 1000000;
+ }
+
+ tv->tv_sec = sec;
+ tv->tv_usec = usec;
}
void do_settimeofday(struct timeval *tv)
@@ -252,10 +310,12 @@ static int set_rtc_mmss(unsigned long nowtime)
int real_seconds, real_minutes, cmos_minutes;
unsigned char save_control, save_freq_select;
- save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
+ /* Tell the clock it's being set */
+ save_control = CMOS_READ(RTC_CONTROL);
CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
- save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
+ /* Stop and reset prescaler */
+ save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
cmos_minutes = CMOS_READ(RTC_MINUTES);
@@ -270,8 +330,10 @@ static int set_rtc_mmss(unsigned long nowtime)
*/
real_seconds = nowtime % 60;
real_minutes = nowtime / 60;
- if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
- real_minutes += 30; /* correct for half hour time zone */
+ if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) {
+ /* correct for half hour time zone */
+ real_minutes += 30;
+ }
real_minutes %= 60;
if (abs(real_minutes - cmos_minutes) < 30) {
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 12bee3fbc..14a8e2010 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -12,6 +12,7 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/tty.h>
+#include <linux/delay.h>
#include <asm/gentrap.h>
#include <asm/uaccess.h>
@@ -20,45 +21,41 @@
#include <asm/smp_lock.h>
-void die_if_kernel(char * str, struct pt_regs * regs, long err,
- unsigned long *r9_15)
+static void dik_show_regs(struct pt_regs *regs, unsigned long *r9_15)
{
- long i;
- unsigned long ra;
- unsigned int * pc;
- unsigned long * sp;
-
- if (regs->ps & 8)
- return;
- printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
- sp = (unsigned long *) (regs+1);
- __get_user(ra, (unsigned long *)sp);
- printk("pc = [<%016lx>] ps = %04lx\n", regs->pc, regs->ps);
- printk("rp = [<%016lx>] ra = [<%016lx>]\n", regs->r26, ra);
- printk("r0 = %016lx r1 = %016lx\n", regs->r0, regs->r1);
- printk("r2 = %016lx r3 = %016lx\n", regs->r2, regs->r3);
- printk("r4 = %016lx r5 = %016lx\n", regs->r4, regs->r5);
- printk("r6 = %016lx r7 = %016lx\n", regs->r6, regs->r7);
+ printk("pc = [<%016lx>] ra = [<%016lx>] ps = %04lx\n",
+ regs->pc, regs->r26, regs->ps);
+ printk("r0 = %016lx r1 = %016lx r2 = %016lx\n",
+ regs->r0, regs->r1, regs->r2);
+ printk("r3 = %016lx r4 = %016lx r5 = %016lx\n",
+ regs->r3, regs->r4, regs->r5);
+ printk("r6 = %016lx r7 = %016lx r8 = %016lx\n",
+ regs->r6, regs->r7, regs->r8);
if (r9_15) {
- printk("r8 = %016lx r9 = %016lx\n", regs->r8, r9_15[9]);
- printk("r10= %016lx r11= %016lx\n", r9_15[10], r9_15[11]);
- printk("r12= %016lx r13= %016lx\n", r9_15[12], r9_15[13]);
- printk("r14= %016lx r15= %016lx\n", r9_15[14], r9_15[15]);
- } else {
- printk("r8 = %016lx\n", regs->r8);
+ printk("r9 = %016lx r10= %016lx r11= %016lx\n",
+ r9_15[9], r9_15[10], r9_15[11]);
+ printk("r12= %016lx r13= %016lx r14= %016lx\n",
+ r9_15[12], r9_15[13], r9_15[14]);
+ printk("r15= %016lx\n", r9_15[15]);
}
- printk("r16= %016lx r17= %016lx\n", regs->r16, regs->r17);
- printk("r18= %016lx r19= %016lx\n", regs->r18, regs->r19);
- printk("r20= %016lx r21= %016lx\n", regs->r20, regs->r21);
- printk("r22= %016lx r23= %016lx\n", regs->r22, regs->r23);
- printk("r24= %016lx r25= %016lx\n", regs->r24, regs->r25);
- printk("r27= %016lx r28= %016lx\n", regs->r27, regs->r28);
- printk("gp = %016lx sp = %p\n", regs->gp, sp);
+ printk("r16= %016lx r17= %016lx r18= %016lx\n",
+ regs->r16, regs->r17, regs->r18);
+ printk("r19= %016lx r20= %016lx r21= %016lx\n",
+ regs->r19, regs->r20, regs->r21);
+ printk("r22= %016lx r23= %016lx r24= %016lx\n",
+ regs->r22, regs->r23, regs->r24);
+ printk("r25= %016lx r27= %016lx r28= %016lx\n",
+ regs->r25, regs->r27, regs->r28);
+ printk("gp = %016lx sp = %p\n", regs->gp, regs+1);
+}
+
+static void dik_show_code(unsigned int *pc)
+{
+ long i;
printk("Code:");
- pc = (unsigned int *) regs->pc;
for (i = -3; i < 6; i++) {
unsigned int insn;
if (__get_user(insn, pc+i))
@@ -66,6 +63,11 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err,
printk("%c%08x%c",i?' ':'<',insn,i?' ':'>');
}
printk("\n");
+}
+
+static void dik_show_trace(unsigned long *sp)
+{
+ long i = 0;
printk("Trace:");
while (0x1ff8 & (unsigned long) sp) {
extern unsigned long _stext, _etext;
@@ -76,9 +78,30 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err,
if (tmp >= (unsigned long) &_etext)
continue;
printk(" [<%lx>]", tmp);
+ if (++i > 40) {
+ printk(" ...");
+ break;
+ }
}
printk("\n");
-
+}
+
+void die_if_kernel(char * str, struct pt_regs *regs, long err,
+ unsigned long *r9_15)
+{
+ if (regs->ps & 8)
+ return;
+ printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
+ dik_show_regs(regs, r9_15);
+ dik_show_code((unsigned int *)regs->pc);
+ dik_show_trace((unsigned long *)(regs+1));
+
+ if (current->tss.flags & (1UL << 63)) {
+ printk("die_if_kernel recursion detected.\n");
+ sti();
+ while (1);
+ }
+ current->tss.flags |= (1UL << 63);
do_exit(SIGSEGV);
}
@@ -397,8 +420,6 @@ asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg,
printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n",
pc, va, opcode, reg);
do_exit(SIGSEGV);
- unlock_kernel();
- return;
got_exception:
/* Ok, we caught the exception, but we don't want it. Is there
@@ -416,13 +437,48 @@ got_exception:
return;
}
- /* Yikes! No one to forward the exception to. */
+ /*
+ * Yikes! No one to forward the exception to.
+ * Since the registers are in a weird format, dump them ourselves.
+ */
lock_kernel();
- printk("%s: unhandled unaligned exception at pc=%lx ra=%lx"
- " (bad address = %p)\n", current->comm,
- pc, una_reg(26), va);
+
+ printk("%s(%d): unhandled unaligned exception\n",
+ current->comm, current->pid);
+
+ printk("pc = [<%016lx>] ra = [<%016lx>] ps = %04lx\n",
+ pc, una_reg(26), regs.ps);
+ printk("r0 = %016lx r1 = %016lx r2 = %016lx\n",
+ una_reg(0), una_reg(1), una_reg(2));
+ printk("r3 = %016lx r4 = %016lx r5 = %016lx\n",
+ una_reg(3), una_reg(4), una_reg(5));
+ printk("r6 = %016lx r7 = %016lx r8 = %016lx\n",
+ una_reg(6), una_reg(7), una_reg(8));
+ printk("r9 = %016lx r10= %016lx r11= %016lx\n",
+ una_reg(9), una_reg(10), una_reg(11));
+ printk("r12= %016lx r13= %016lx r14= %016lx\n",
+ una_reg(12), una_reg(13), una_reg(14));
+ printk("r15= %016lx\n", una_reg(15));
+ printk("r16= %016lx r17= %016lx r18= %016lx\n",
+ una_reg(16), una_reg(17), una_reg(18));
+ printk("r19= %016lx r20= %016lx r21= %016lx\n",
+ una_reg(19), una_reg(20), una_reg(21));
+ printk("r22= %016lx r23= %016lx r24= %016lx\n",
+ una_reg(22), una_reg(23), una_reg(24));
+ printk("r25= %016lx r27= %016lx r28= %016lx\n",
+ una_reg(25), una_reg(27), una_reg(28));
+ printk("gp = %016lx sp = %p\n", regs.gp, &regs+1);
+
+ dik_show_code((unsigned int *)pc);
+ dik_show_trace((unsigned long *)(&regs+1));
+
+ if (current->tss.flags & (1UL << 63)) {
+ printk("die_if_kernel recursion detected.\n");
+ sti();
+ while (1);
+ }
+ current->tss.flags |= (1UL << 63);
do_exit(SIGSEGV);
- unlock_kernel();
}
/*
@@ -800,26 +856,17 @@ give_sigbus:
}
/*
- * DEC means people to use the "retsys" instruction for return from
- * a system call, but they are clearly misguided about this. We use
- * "rti" in all cases, and fill in the stack with the return values.
- * That should make signal handling etc much cleaner.
- *
- * Even more horribly, DEC doesn't allow system calls from kernel mode.
- * "Security" features letting the user do something the kernel can't
- * are a thinko. DEC palcode is strange. The PAL-code designers probably
- * got terminally tainted by VMS at some point.
+ * Unimplemented system calls.
*/
-asmlinkage long do_entSys(unsigned long a0, unsigned long a1, unsigned long a2,
- unsigned long a3, unsigned long a4, unsigned long a5,
- struct pt_regs regs)
+asmlinkage long alpha_ni_syscall(unsigned long a0, unsigned long a1,
+ unsigned long a2, unsigned long a3,
+ unsigned long a4, unsigned long a5,
+ struct pt_regs regs)
{
- lock_kernel();
/* Only report OSF system calls. */
if (regs.r0 != 112 && regs.r0 < 300)
printk("<sc %ld(%lx,%lx,%lx)>", regs.r0, a0, a1, a2);
- unlock_kernel();
- return -1;
+ return -ENOSYS;
}
extern asmlinkage void entMM(void);
diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile
index a4e0fea9f..28dc3d451 100644
--- a/arch/alpha/lib/Makefile
+++ b/arch/alpha/lib/Makefile
@@ -19,9 +19,6 @@ endif
lib.a: $(OBJS)
$(AR) rcs lib.a $(OBJS)
-memset.o: memset.S
- $(CC) -c -o memset.o memset.S
-
__divqu.o: divide.S
$(CC) -DDIV -c -o __divqu.o divide.S
diff --git a/arch/alpha/lib/clear_user.S b/arch/alpha/lib/clear_user.S
index db179adfd..65d7e2f28 100644
--- a/arch/alpha/lib/clear_user.S
+++ b/arch/alpha/lib/clear_user.S
@@ -37,8 +37,8 @@
.set noreorder
.align 4
- .globl __clear_user
- .ent __clear_user
+ .globl __do_clear_user
+ .ent __do_clear_user
.frame $30, 0, $28
.prologue 0
@@ -79,7 +79,7 @@ $tail:
EX( stq_u $5, 0($6) ) # e0 :
ret $31, ($28), 1 # .. e1 :
-__clear_user:
+__do_clear_user:
and $6, 7, $4 # e0 : find dest misalignment
beq $0, $zerolength # .. e1 :
addq $0, $4, $1 # e0 : bias counter
@@ -110,4 +110,4 @@ $zerolength:
$exception:
ret $31, ($28), 1 # .. e1 :
- .end __clear_user
+ .end __do_clear_user
diff --git a/arch/alpha/lib/csum_partial_copy.c b/arch/alpha/lib/csum_partial_copy.c
index 475c84e7d..24a45e7aa 100644
--- a/arch/alpha/lib/csum_partial_copy.c
+++ b/arch/alpha/lib/csum_partial_copy.c
@@ -8,7 +8,7 @@
*/
#include <linux/types.h>
-#include <asm/string.h>
+#include <linux/string.h>
#include <asm/uaccess.h>
diff --git a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S
index 6f68a92d4..30384a3a3 100644
--- a/arch/i386/boot/compressed/head.S
+++ b/arch/i386/boot/compressed/head.S
@@ -37,7 +37,7 @@
startup_32:
cld
cli
- movl $(KERNEL_DS),%eax
+ movl $(__KERNEL_DS),%eax
mov %ax,%ds
mov %ax,%es
mov %ax,%fs
@@ -56,7 +56,7 @@ startup_32:
movl %eax,%esp
pushl 0 # Clear NT
popfl
- ljmp $(KERNEL_CS), $0x100000 # Into C and sanity
+ ljmp $(__KERNEL_CS), $0x100000 # Into C and sanity
2:
#endif
@@ -92,7 +92,7 @@ startup_32:
orl %eax,%eax
jnz 3f
xorl %ebx,%ebx
- ljmp $(KERNEL_CS), $0x100000
+ ljmp $(__KERNEL_CS), $0x100000
/*
* We come here, if we were loaded high.
@@ -116,7 +116,7 @@ startup_32:
popl %eax # hcount
movl $0x100000,%edi
cli # make sure we don't get interrupted
- ljmp $(KERNEL_CS), $0x1000 # and jump to the move routine
+ ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine
/*
* Routine (template) for moving the decompressed kernel in place,
@@ -136,5 +136,5 @@ move_routine_start:
* so we set esp here.
*/
mov $0x90000,%esp
- ljmp $(KERNEL_CS), $0x100000
+ ljmp $(__KERNEL_CS), $0x100000
move_routine_end:
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c
index 9a556baf4..e4a6ede9a 100644
--- a/arch/i386/boot/compressed/misc.c
+++ b/arch/i386/boot/compressed/misc.c
@@ -285,7 +285,7 @@ long user_stack [STACK_SIZE];
struct {
long * a;
short b;
- } stack_start = { & user_stack [STACK_SIZE] , KERNEL_DS };
+ } stack_start = { & user_stack [STACK_SIZE] , __KERNEL_DS };
void setup_normal_output_buffer()
{
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S
index edc0fe0ff..11310bd49 100644
--- a/arch/i386/boot/setup.S
+++ b/arch/i386/boot/setup.S
@@ -594,7 +594,7 @@ flush_instr:
xor bx,bx ! Flag to indicate a boot
! NOTE: For high loaded big kernels we need a
-! jmpi 0x100000,KERNEL_CS
+! jmpi 0x100000,__KERNEL_CS
!
! but we yet haven't reloaded the CS register, so the default size
! of the target offset still is 16 bit.
@@ -603,7 +603,7 @@ flush_instr:
! Manual, Mixing 16-bit and 32-bit code, page 16-6)
db 0x66,0xea ! prefix + jmpi-opcode
code32: dd 0x1000 ! will be set to 0x100000 for big kernels
- dw KERNEL_CS
+ dw __KERNEL_CS
kernel_version: .ascii UTS_RELEASE
diff --git a/arch/i386/config.in b/arch/i386/config.in
index f7042fa33..7595ab5fe 100644
--- a/arch/i386/config.in
+++ b/arch/i386/config.in
@@ -84,6 +84,8 @@ if [ "$CONFIG_NET" = "y" ]; then
endmenu
fi
+source drivers/net/hamradio/Config.in
+
mainmenu_option next_comment
comment 'ISDN subsystem'
@@ -102,6 +104,17 @@ if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
fi
endmenu
+# Conditionally compile in the Uniform CD-ROM driver
+if [ "$CONFIG_BLK_DEV_IDECD" = "y" -o "$CONFIG_BLK_DEV_SR" = "y" -o "$CONFIG_SBPCD" = "y" -o "$CONFIG_MCD" = "y" -o "$CONFIG_CM206" = "y" -o "$CONFIG_CDU31A" = "y" ]; then
+ define_bool CONFIG_CDROM y
+else
+ if [ "$CONFIG_BLK_DEV_IDECD" = "m" -o "$CONFIG_BLK_DEV_SR" = "m" -o "$CONFIG_SBPCD" = "m" -o "$CONFIG_MCD" = "m" -o "$CONFIG_CM206" = "m" -o "$CONFIG_CDU31A" = "m" ]; then
+ define_bool CONFIG_CDROM m
+ else
+ define_bool CONFIG_CDROM n
+ fi
+fi
+
source fs/Config.in
source fs/nls/Config.in
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index bd100e08d..222b10939 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -58,7 +58,7 @@ CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_CMD640=y
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
CONFIG_BLK_DEV_RZ1000=y
-CONFIG_BLK_DEV_TRITON=y
+CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDE_CHIPSETS is not set
#
@@ -74,22 +74,27 @@ CONFIG_BLK_DEV_TRITON=y
#
# Networking options
#
+CONFIG_PACKET=y
# CONFIG_NETLINK is not set
# CONFIG_FIREWALL is not set
# CONFIG_NET_ALIAS is not set
+CONFIG_UNIX=y
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
# CONFIG_IP_ACCT is not set
+# CONFIG_IP_MASQUERADE is not set
# CONFIG_IP_ROUTER is not set
# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
# CONFIG_SYN_COOKIES is not set
#
# (it is safe to leave these untouched)
#
-# CONFIG_INET_PCTCP is not set
# CONFIG_INET_RARP is not set
-CONFIG_PATH_MTU_DISCOVERY=y
CONFIG_IP_NOSR=y
CONFIG_SKB_LARGE=y
@@ -98,7 +103,6 @@ CONFIG_SKB_LARGE=y
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
-# CONFIG_AX25 is not set
#
# SCSI support
@@ -179,14 +183,20 @@ CONFIG_EEXPRESS_PRO100=y
# CONFIG_FDDI is not set
# CONFIG_DLCI is not set
# CONFIG_PPP is not set
-# CONFIG_NET_RADIO is not set
# CONFIG_SLIP is not set
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
# CONFIG_TR is not set
# CONFIG_WAN_DRIVERS is not set
# CONFIG_LAPBETHER is not set
# CONFIG_X25_ASY is not set
#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
# ISDN subsystem
#
# CONFIG_ISDN is not set
@@ -195,6 +205,7 @@ CONFIG_EEXPRESS_PRO100=y
# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
#
# CONFIG_CD_NO_IDESCSI is not set
+CONFIG_CDROM=y
#
# Filesystems
@@ -214,6 +225,7 @@ CONFIG_NFS_FS=y
CONFIG_NFSD=y
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
+# CONFIG_CODA_FS is not set
# CONFIG_SMB_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_SYSV_FS is not set
@@ -234,6 +246,7 @@ CONFIG_AUTOFS_FS=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set
CONFIG_MOUSE=y
diff --git a/arch/i386/kernel/bios32.c b/arch/i386/kernel/bios32.c
index e98819258..8e41188c3 100644
--- a/arch/i386/kernel/bios32.c
+++ b/arch/i386/kernel/bios32.c
@@ -1,7 +1,7 @@
/*
* bios32.c - BIOS32, PCI BIOS functions.
*
- * $Id: bios32.c,v 1.14 1997/08/02 22:20:57 mj Exp $
+ * $Id: bios32.c,v 1.5 1997/12/02 01:48:00 ralf Exp $
*
* Sponsored by
* iX Multiuser Multitasking Magazine
@@ -528,7 +528,7 @@ static unsigned long bios32_entry = 0;
static struct {
unsigned long address;
unsigned short segment;
-} bios32_indirect = { 0, KERNEL_CS };
+} bios32_indirect = { 0, __KERNEL_CS };
/*
* Returns the entry point for the given service, NULL on error
@@ -570,7 +570,7 @@ static long pcibios_entry = 0;
static struct {
unsigned long address;
unsigned short segment;
-} pci_indirect = { 0, KERNEL_CS };
+} pci_indirect = { 0, __KERNEL_CS };
__initfunc(static int check_pcibios(void))
{
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index dffc13795..cf99d6e2e 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -73,15 +73,15 @@ VM_MASK = 0x00020000
state = 0
counter = 4
priority = 8
-signal = 12
-blocked = 16
-flags = 20
-dbgreg6 = 52
-dbgreg7 = 56
-exec_domain = 60
+flags = 12
+sigpending = 16
+dbgreg6 = 44
+dbgreg7 = 48
+exec_domain = 52
ENOSYS = 38
+
#define SAVE_ALL \
cld; \
push %es; \
@@ -93,7 +93,7 @@ ENOSYS = 38
pushl %edx; \
pushl %ecx; \
pushl %ebx; \
- movl $(KERNEL_DS),%edx; \
+ movl $(__KERNEL_DS),%edx; \
mov %dx,%ds; \
mov %dx,%es;
@@ -170,10 +170,7 @@ ret_from_sys_call:
ret_with_reschedule:
cmpl $0,SYMBOL_NAME(need_resched)
jne reschedule
- movl blocked(%ebx),%eax
- movl %eax,%esi # save blocked in %esi for signal handling
- notl %eax
- andl signal(%ebx),%eax
+ cmpl $0,sigpending(%ebx)
jne signal_return
RESTORE_ALL
ALIGN
@@ -181,7 +178,7 @@ signal_return:
testl $(VM_MASK),EFLAGS(%esp)
pushl %esp
jne v86_signal_return
- pushl %esi
+ pushl $0
call SYMBOL_NAME(do_signal)
addl $8,%esp
RESTORE_ALL
@@ -190,7 +187,7 @@ v86_signal_return:
call SYMBOL_NAME(save_v86_state)
movl %eax,%esp
pushl %eax
- pushl %esi
+ pushl $0
call SYMBOL_NAME(do_signal)
addl $8,%esp
RESTORE_ALL
@@ -255,7 +252,7 @@ error_code:
xchgl %ecx, ES(%esp) # get the address and save es.
pushl %eax # push the error code
pushl %edx
- movl $(KERNEL_DS),%edx
+ movl $(__KERNEL_DS),%edx
mov %dx,%ds
mov %dx,%es
GET_CURRENT(%ebx)
@@ -529,6 +526,16 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_setresgid) /* 170 */
.long SYMBOL_NAME(sys_getresgid)
.long SYMBOL_NAME(sys_prctl)
- .rept NR_syscalls-172
+ .long SYMBOL_NAME(sys_rt_sigreturn)
+ .long SYMBOL_NAME(sys_rt_sigaction)
+ .long SYMBOL_NAME(sys_rt_sigprocmask) /* 175 */
+ .long SYMBOL_NAME(sys_rt_sigpending)
+ .long SYMBOL_NAME(sys_rt_sigtimedwait)
+ .long SYMBOL_NAME(sys_rt_sigqueueinfo)
+ .long SYMBOL_NAME(sys_rt_sigsuspend)
+ .long SYMBOL_NAME(sys_pread) /* 180 */
+ .long SYMBOL_NAME(sys_pwrite)
+
+ .rept NR_syscalls-181
.long SYMBOL_NAME(sys_ni_syscall)
.endr
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index 00a8e122e..a21ac6791 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -29,7 +29,7 @@ startup_32:
* Set segments to known values
*/
cld
- movl $(KERNEL_DS),%eax
+ movl $(__KERNEL_DS),%eax
mov %ax,%ds
mov %ax,%es
mov %ax,%fs
@@ -227,14 +227,14 @@ is386: pushl %ecx # restore original EFLAGS
#endif
lgdt gdt_descr
lidt idt_descr
- ljmp $(KERNEL_CS),$1f
-1: movl $(KERNEL_DS),%eax # reload all the segment registers
+ ljmp $(__KERNEL_CS),$1f
+1: movl $(__KERNEL_DS),%eax# reload all the segment registers
mov %ax,%ds # after changing gdt.
mov %ax,%es
mov %ax,%fs
mov %ax,%gs
#ifdef __SMP__
- movl $(KERNEL_DS), %eax
+ movl $(__KERNEL_DS), %eax
mov %ax,%ss # Reload the stack pointer (segment only)
#else
lss stack_start,%esp # Load processor stack
@@ -285,7 +285,7 @@ check_x87:
*/
setup_idt:
lea ignore_int,%edx
- movl $(KERNEL_CS << 16),%eax
+ movl $(__KERNEL_CS << 16),%eax
movw %dx,%ax /* selector = 0x0010 = cs */
movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
@@ -301,7 +301,7 @@ rp_sidt:
ENTRY(stack_start)
.long SYMBOL_NAME(init_task_union)+8192
- .long KERNEL_DS
+ .long __KERNEL_DS
/* This is the default interrupt "handler" :-) */
int_msg:
@@ -314,7 +314,7 @@ ignore_int:
pushl %edx
push %es
push %ds
- movl $(KERNEL_DS),%eax
+ movl $(__KERNEL_DS),%eax
mov %ax,%ds
mov %ax,%es
pushl $int_msg
diff --git a/arch/i386/kernel/init_task.c b/arch/i386/kernel/init_task.c
index cc0a19231..acc206942 100644
--- a/arch/i386/kernel/init_task.c
+++ b/arch/i386/kernel/init_task.c
@@ -1,6 +1,7 @@
#include <linux/mm.h>
#include <linux/sched.h>
+#include <asm/uaccess.h>
#include <asm/pgtable.h>
static struct vm_area_struct init_mmap = INIT_MMAP;
diff --git a/arch/i386/kernel/irq.h b/arch/i386/kernel/irq.h
index 7d70264ba..db70872f1 100644
--- a/arch/i386/kernel/irq.h
+++ b/arch/i386/kernel/irq.h
@@ -44,7 +44,7 @@ static inline void irq_exit(int cpu, int irq)
"pushl %edx\n\t" \
"pushl %ecx\n\t" \
"pushl %ebx\n\t" \
- "movl $" STR(KERNEL_DS) ",%edx\n\t" \
+ "movl $" STR(__KERNEL_DS) ",%edx\n\t" \
"mov %dx,%ds\n\t" \
"mov %dx,%es\n\t"
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index a8fe0315b..5a13e0179 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -281,22 +281,19 @@ void machine_restart(char * __unused)
{
if(!reboot_thru_bios) {
-#if 0
- sti();
-#endif
/* rebooting needs to touch the page at absolute addr 0 */
*((unsigned short *)__va(0x472)) = reboot_mode;
for (;;) {
int i;
for (i=0; i<100; i++) {
- int j;
kb_wait();
- for(j = 0; j < 100000 ; j++)
- /* nothing */;
+ udelay(10);
outb(0xfe,0x64); /* pulse reset low */
udelay(10);
}
- __asm__ __volatile__("\tlidt %0": "=m" (no_idt));
+ /* That didn't work - force a triple fault.. */
+ __asm__ __volatile__("lidt %0": :"m" (no_idt));
+ __asm__ __volatile__("int3");
}
}
@@ -480,13 +477,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
p->tss.tr = _TSS(nr);
p->tss.ldt = _LDT(nr);
- p->tss.es = KERNEL_DS;
- p->tss.cs = KERNEL_CS;
- p->tss.ss = KERNEL_DS;
- p->tss.ds = KERNEL_DS;
- p->tss.fs = USER_DS;
- p->tss.gs = USER_DS;
- p->tss.ss0 = KERNEL_DS;
+ p->tss.es = __KERNEL_DS;
+ p->tss.cs = __KERNEL_CS;
+ p->tss.ss = __KERNEL_DS;
+ p->tss.ds = __KERNEL_DS;
+ p->tss.fs = __USER_DS;
+ p->tss.gs = __USER_DS;
+ p->tss.ss0 = __KERNEL_DS;
p->tss.esp0 = 2*PAGE_SIZE + (unsigned long) p;
childregs = ((struct pt_regs *) (p->tss.esp0)) - 1;
p->tss.esp = (unsigned long) childregs;
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index c8a7f986e..246a6c29b 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -492,7 +492,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
long tmp;
ret = -EIO;
- if ((unsigned long) data > NSIG)
+ if ((unsigned long) data > _NSIG)
goto out;
if (request == PTRACE_SYSCALL)
child->flags |= PF_TRACESYS;
@@ -530,7 +530,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
long tmp;
ret = -EIO;
- if ((unsigned long) data > NSIG)
+ if ((unsigned long) data > _NSIG)
goto out;
child->flags &= ~PF_TRACESYS;
tmp = get_stack_long(child, EFL_OFFSET) | TRAP_FLAG;
@@ -546,7 +546,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
long tmp;
ret = -EIO;
- if ((unsigned long) data > NSIG)
+ if ((unsigned long) data > _NSIG)
goto out;
child->flags &= ~(PF_PTRACED|PF_TRACESYS);
wake_up_process(child);
@@ -585,9 +585,7 @@ asmlinkage void syscall_trace(void)
* stopping signal is not SIGTRAP. -brl
*/
if (current->exit_code) {
- spin_lock_irq(&current->sigmask_lock);
- current->signal |= (1 << (current->exit_code - 1));
- spin_unlock_irq(&current->sigmask_lock);
+ send_sig(current->exit_code, current, 1);
+ current->exit_code = 0;
}
- current->exit_code = 0;
}
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index f5af47201..7d5cf3a95 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -2,6 +2,8 @@
* linux/arch/i386/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
*/
#include <linux/config.h>
@@ -16,40 +18,132 @@
#include <linux/wait.h>
#include <linux/ptrace.h>
#include <linux/unistd.h>
-
+#include <linux/stddef.h>
+#include <asm/ucontext.h>
#include <asm/uaccess.h>
-#define _S(nr) (1<<((nr)-1))
+#define DEBUG_SIG 0
-#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
int options, unsigned long *ru);
-
-asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs);
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
/*
- * atomically swap in the new signal mask, and wait for a signal.
+ * Atomically swap in the new signal mask, and wait for a signal.
*/
-asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, unsigned long set)
+asmlinkage int
+sys_sigsuspend(int history0, int history1, old_sigset_t mask)
{
- struct pt_regs * regs = (struct pt_regs *) &restart;
- unsigned long mask;
+ struct pt_regs * regs = (struct pt_regs *) &history0;
+ sigset_t saveset;
+ mask &= _BLOCKABLE;
spin_lock_irq(&current->sigmask_lock);
- mask = current->blocked;
- current->blocked = set & _BLOCKABLE;
+ saveset = current->blocked;
+ siginitset(&current->blocked, mask);
+ recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
regs->eax = -EINTR;
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(mask, regs))
+ if (do_signal(&saveset, regs))
return -EINTR;
}
}
+asmlinkage int
+sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
+{
+ struct pt_regs * regs = (struct pt_regs *) &unewset;
+ sigset_t saveset, newset;
+
+ /* XXX: Don't preclude handling different sized sigset_t's. */
+ if (sigsetsize != sizeof(sigset_t))
+ return -EINVAL;
+
+ if (copy_from_user(&newset, unewset, sizeof(newset)))
+ return -EFAULT;
+ sigdelsetmask(&newset, ~_BLOCKABLE);
+
+ spin_lock_irq(&current->sigmask_lock);
+ saveset = current->blocked;
+ current->blocked = newset;
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ regs->eax = -EINTR;
+ while (1) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ if (do_signal(&saveset, regs))
+ return -EINTR;
+ }
+}
+
+asmlinkage int
+sys_sigaction(int sig, const struct old_sigaction *act,
+ struct old_sigaction *oact)
+{
+ struct k_sigaction new_ka, old_ka;
+ int ret;
+
+ if (act) {
+ old_sigset_t mask;
+ if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+ __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+ return -EFAULT;
+ __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+ __get_user(mask, &act->sa_mask);
+ siginitset(&new_ka.sa.sa_mask, mask);
+ }
+
+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+ if (!ret && oact) {
+ if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+ return -EFAULT;
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+ }
+
+ return ret;
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+struct sigframe
+{
+ char *pretcode;
+ int sig;
+ struct sigcontext sc;
+ struct _fpstate fpstate;
+ unsigned long extramask[_NSIG_WORDS-1];
+ char retcode[8];
+};
+
+struct rt_sigframe
+{
+ char *pretcode;
+ int sig;
+ struct siginfo *pinfo;
+ void *puc;
+ struct siginfo info;
+ struct ucontext uc;
+ struct _fpstate fpstate;
+ char retcode[8];
+};
+
+
static inline void restore_i387_hard(struct _fpstate *buf)
{
#ifdef __SMP__
@@ -64,94 +158,150 @@ static inline void restore_i387_hard(struct _fpstate *buf)
#endif
current->used_math = 1;
current->flags &= ~PF_USEDFPU;
- copy_from_user(&current->tss.i387.hard, buf, sizeof(*buf));
+ __copy_from_user(&current->tss.i387.hard, buf, sizeof(*buf));
}
-static void restore_i387(struct _fpstate *buf)
+static inline void restore_i387(struct _fpstate *buf)
{
#ifndef CONFIG_MATH_EMULATION
restore_i387_hard(buf);
#else
- if (hard_math) {
+ if (hard_math)
restore_i387_hard(buf);
- return;
- }
- restore_i387_soft(buf);
-#endif
+ else
+ restore_i387_soft(buf);
+#endif
}
-
-/*
- * This sets regs->esp even though we don't actually use sigstacks yet..
- */
-asmlinkage int sys_sigreturn(unsigned long __unused)
+static int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
{
-#define COPY(x) regs->x = context->x
-#define COPY_SEG(seg) \
-{ unsigned int tmp = context->seg; \
-if ( (tmp & 0xfffc) /* not a NULL selectors */ \
- && (tmp & 0x4) != 0x4 /* not a LDT selector */ \
- && (tmp & 3) != 3 /* not a RPL3 GDT selector */ \
- ) goto badframe; \
-regs->x##seg = tmp; }
-#define COPY_SEG_STRICT(seg) \
-{ unsigned int tmp = context->seg; \
-if ((tmp & 0xfffc) && (tmp & 3) != 3) goto badframe; \
-regs->x##seg = tmp; }
-#define GET_SEG(seg) \
-{ unsigned int tmp = context->seg; \
-if ( (tmp & 0xfffc) /* not a NULL selectors */ \
- && (tmp & 0x4) != 0x4 /* not a LDT selector */ \
- && (tmp & 3) != 3 /* not a RPL3 GDT selector */ \
- ) goto badframe; \
-__asm__("mov %w0,%%" #seg: :"r" (tmp)); }
- struct sigcontext * context;
- struct pt_regs * regs;
-
- regs = (struct pt_regs *) &__unused;
- context = (struct sigcontext *) regs->esp;
- if (verify_area(VERIFY_READ, context, sizeof(*context)))
- goto badframe;
- current->blocked = context->oldmask & _BLOCKABLE;
- COPY_SEG(ds);
- COPY_SEG(es);
- GET_SEG(fs);
+ unsigned int tmp;
+
+#define COPY(x) __get_user(regs->x, &sc->x)
+
+#define COPY_SEG(seg) \
+ { __get_user(tmp, &sc->seg); \
+ if ((tmp & 0xfffc) /* not a NULL selectors */ \
+ && (tmp & 0x4) != 0x4 /* not a LDT selector */ \
+ && (tmp & 3) != 3) /* not a RPL3 GDT selector */ \
+ goto badframe; \
+ regs->x##seg = tmp; }
+
+#define COPY_SEG_STRICT(seg) \
+ { __get_user(tmp, &sc->seg); \
+ if ((tmp & 0xfffc) && (tmp & 3) != 3) goto badframe; \
+ regs->x##seg = tmp; }
+
+#define GET_SEG(seg) \
+ { __get_user(tmp, &sc->seg); \
+ if ((tmp & 0xfffc) /* not a NULL selectors */ \
+ && (tmp & 0x4) != 0x4 /* not a LDT selector */ \
+ && (tmp & 3) != 3) /* not a RPL3 GDT selector */ \
+ goto badframe; \
+ __asm__ __volatile__("mov %w0,%%" #seg : : "r"(tmp)); }
+
GET_SEG(gs);
- COPY_SEG_STRICT(ss);
- COPY_SEG_STRICT(cs);
- COPY(eip);
- COPY(ecx); COPY(edx);
+ GET_SEG(fs);
+ COPY_SEG(es);
+ COPY_SEG(ds);
+ COPY(edi);
+ COPY(esi);
+ COPY(ebp);
+ COPY(esp);
COPY(ebx);
- COPY(esp); COPY(ebp);
- COPY(edi); COPY(esi);
- regs->eflags &= ~0x40DD5;
- regs->eflags |= context->eflags & 0x40DD5;
+ COPY(edx);
+ COPY(ecx);
+ COPY(eip);
+ COPY_SEG_STRICT(cs);
+ COPY_SEG_STRICT(ss);
+
+ __get_user(tmp, &sc->eflags);
+ regs->eflags = (regs->eflags & ~0x40DD5) | (tmp & 0x40DD5);
regs->orig_eax = -1; /* disable syscall checks */
- if (context->fpstate) {
- struct _fpstate * buf = context->fpstate;
+
+ __get_user(tmp, (unsigned long *)&sc->fpstate);
+ if (tmp) {
+ struct _fpstate * buf = (struct _fpstate *) tmp;
if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
goto badframe;
restore_i387(buf);
}
- return context->eax;
+
+ __get_user(tmp, &sc->eax);
+ return tmp;
badframe:
lock_kernel();
do_exit(SIGSEGV);
- unlock_kernel();
}
+asmlinkage int sys_sigreturn(unsigned long __unused)
+{
+ struct pt_regs *regs = (struct pt_regs *) &__unused;
+ struct sigframe *frame = (struct sigframe *)(regs->esp - 8);
+ sigset_t set;
+
+ if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__get_user(set.sig[0], &frame->sc.oldmask)
+ || (_NSIG_WORDS > 1
+ && __copy_from_user(&set.sig[1], &frame->extramask,
+ sizeof(frame->extramask))))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sigmask_lock);
+ current->blocked = set;
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ return restore_sigcontext(regs, &frame->sc);
+
+badframe:
+ lock_kernel();
+ do_exit(SIGSEGV);
+}
+
+asmlinkage int sys_rt_sigreturn(unsigned long __unused)
+{
+ struct pt_regs *regs = (struct pt_regs *) &__unused;
+ struct rt_sigframe *frame = (struct rt_sigframe *)(regs->esp - 4);
+ sigset_t set;
+
+ if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sigmask_lock);
+ current->blocked = set;
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ return restore_sigcontext(regs, &frame->uc.uc_mcontext);
+
+badframe:
+ lock_kernel();
+ do_exit(SIGSEGV);
+}
+
+/*
+ * Set up a signal frame.
+ */
+
static inline struct _fpstate * save_i387_hard(struct _fpstate * buf)
{
#ifdef __SMP__
if (current->flags & PF_USEDFPU) {
- __asm__ __volatile__("fnsave %0":"=m" (current->tss.i387.hard));
+ __asm__ __volatile__("fnsave %0":"=m"(current->tss.i387.hard));
stts();
current->flags &= ~PF_USEDFPU;
}
#else
if (current == last_task_used_math) {
- __asm__ __volatile__("fnsave %0":"=m" (current->tss.i387.hard));
+ __asm__ __volatile__("fnsave %0":"=m"(current->tss.i387.hard));
last_task_used_math = NULL;
__asm__ __volatile__("fwait"); /* not needed on 486+ */
stts();
@@ -163,7 +313,7 @@ static inline struct _fpstate * save_i387_hard(struct _fpstate * buf)
return buf;
}
-static struct _fpstate * save_i387(struct _fpstate * buf)
+static struct _fpstate * save_i387(struct _fpstate *buf)
{
if (!current->used_math)
return NULL;
@@ -171,107 +321,197 @@ static struct _fpstate * save_i387(struct _fpstate * buf)
#ifndef CONFIG_MATH_EMULATION
return save_i387_hard(buf);
#else
- if (hard_math)
- return save_i387_hard(buf);
- return save_i387_soft(buf);
+ return hard_math ? save_i387_hard(buf) : save_i387_soft(buf);
#endif
}
-/*
- * Set up a signal frame... Make the stack look the way iBCS2 expects
- * it to look.
- */
-static void setup_frame(struct sigaction * sa,
- struct pt_regs * regs, int signr,
- unsigned long oldmask)
+static void
+setup_sigcontext(struct sigcontext *sc, struct _fpstate *fpstate,
+ struct pt_regs *regs, unsigned long mask)
{
- unsigned long * frame;
+ unsigned int tmp;
+
+ tmp = 0;
+ __asm__("mov %%gs,%w0" : "=r"(tmp): "0"(tmp));
+ __put_user(tmp, (unsigned int *)&sc->gs);
+ __asm__("mov %%fs,%w0" : "=r"(tmp): "0"(tmp));
+ __put_user(tmp, (unsigned int *)&sc->fs);
+
+ __put_user(regs->xes, (unsigned int *)&sc->es);
+ __put_user(regs->xds, (unsigned int *)&sc->ds);
+ __put_user(regs->edi, &sc->edi);
+ __put_user(regs->esi, &sc->esi);
+ __put_user(regs->ebp, &sc->ebp);
+ __put_user(regs->esp, &sc->esp);
+ __put_user(regs->ebx, &sc->ebx);
+ __put_user(regs->edx, &sc->edx);
+ __put_user(regs->ecx, &sc->ecx);
+ __put_user(regs->eax, &sc->eax);
+ __put_user(current->tss.trap_no, &sc->trapno);
+ __put_user(current->tss.error_code, &sc->err);
+ __put_user(regs->eip, &sc->eip);
+ __put_user(regs->xcs, (unsigned int *)&sc->cs);
+ __put_user(regs->eflags, &sc->eflags);
+ __put_user(regs->esp, &sc->esp_at_signal);
+ __put_user(regs->xss, (unsigned int *)&sc->ss);
+
+ __put_user(save_i387(fpstate), &sc->fpstate);
+
+ /* non-iBCS2 extensions.. */
+ __put_user(mask, &sc->oldmask);
+ __put_user(current->tss.cr2, &sc->cr2);
+}
+
+static void setup_frame(int sig, struct k_sigaction *ka,
+ sigset_t *set, struct pt_regs * regs)
+{
+ struct sigframe *frame;
- frame = (unsigned long *) regs->esp;
- if ((regs->xss & 0xffff) != USER_DS && sa->sa_restorer)
- frame = (unsigned long *) sa->sa_restorer;
- frame -= 64;
- if (!access_ok(VERIFY_WRITE,frame,64*4))
- goto segv_and_exit;
+ frame = (struct sigframe *)((regs->esp - sizeof(*frame)) & -8);
-/* set up the "normal" stack seen by the signal handler (iBCS2) */
-#define __CODE ((unsigned long)(frame+24))
-#define CODE(x) ((unsigned long *) ((x)+__CODE))
-
- /* XXX Can possible miss a SIGSEGV when frame crosses a page border
- and a thread unmaps it while we are accessing it.
- So either check all put_user() calls or don't do it at all.
- We use __put_user() here because the access_ok() call was already
- done earlier. */
- if (__put_user(__CODE,frame))
+ /* XXX: Check here if we need to switch stacks.. */
+
+ /* This is legacy signal stack switching. */
+ if ((regs->xss & 0xffff) != __USER_DS
+ && !(ka->sa.sa_flags & SA_RESTORER) && ka->sa.sa_restorer)
+ frame = (struct sigframe *) ka->sa.sa_restorer;
+
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto segv_and_exit;
- if (current->exec_domain && current->exec_domain->signal_invmap)
- __put_user(current->exec_domain->signal_invmap[signr], frame+1);
- else
- __put_user(signr, frame+1);
+
+ __put_user((current->exec_domain
+ && current->exec_domain->signal_invmap
+ && sig < 32
+ ? current->exec_domain->signal_invmap[sig]
+ : sig),
+ &frame->sig);
+
+ setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
+
+ if (_NSIG_WORDS > 1) {
+ __copy_to_user(frame->extramask, &set->sig[1],
+ sizeof(frame->extramask));
+ }
+
+ /* Set up to return from userspace. If provided, use a stub
+ already in userspace. */
+ if (ka->sa.sa_flags & SA_RESTORER) {
+ __put_user(ka->sa.sa_restorer, &frame->pretcode);
+ } else {
+ __put_user(frame->retcode, &frame->pretcode);
+ /* This is popl %eax ; movl $,%eax ; int $0x80 */
+ __put_user(0xb858, (short *)(frame->retcode+0));
+ __put_user(__NR_sigreturn, (int *)(frame->retcode+2));
+ __put_user(0x80cd, (short *)(frame->retcode+6));
+ }
+
+ /* Set up registers for signal handler */
+ regs->esp = (unsigned long) frame;
+ regs->eip = (unsigned long) ka->sa.sa_handler;
{
- unsigned int tmp = 0;
-#define PUT_SEG(seg, mem) \
-__asm__("mov %%" #seg",%w0":"=r" (tmp):"0" (tmp)); __put_user(tmp,mem);
- PUT_SEG(gs, frame+2);
- PUT_SEG(fs, frame+3);
+ unsigned long seg = __USER_DS;
+ __asm__("mov %w0,%%fs ; mov %w0,%%gs": "=r"(seg) : "0"(seg));
+ set_fs(MAKE_MM_SEG(seg));
+ regs->xds = seg;
+ regs->xes = seg;
+ regs->xss = seg;
+ regs->xcs = __USER_CS;
+ }
+ regs->eflags &= ~TF_MASK;
+
+#if DEBUG_SIG
+ printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
+ current->comm, current->pid, frame, regs->eip, frame->pretcode);
+#endif
+
+ return;
+
+segv_and_exit:
+ lock_kernel();
+ do_exit(SIGSEGV);
+}
+
+static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *set, struct pt_regs * regs)
+{
+ struct rt_sigframe *frame;
+
+ frame = (struct rt_sigframe *)((regs->esp - sizeof(*frame)) & -8);
+
+ /* XXX: Check here if we need to switch stacks.. */
+
+ /* This is legacy signal stack switching. */
+ if ((regs->xss & 0xffff) != __USER_DS
+ && !(ka->sa.sa_flags & SA_RESTORER) && ka->sa.sa_restorer)
+ frame = (struct rt_sigframe *) ka->sa.sa_restorer;
+
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ goto segv_and_exit;
+
+ __put_user((current->exec_domain
+ && current->exec_domain->signal_invmap
+ && sig < 32
+ ? current->exec_domain->signal_invmap[sig]
+ : sig),
+ &frame->sig);
+ __put_user(&frame->info, &frame->pinfo);
+ __put_user(&frame->uc, &frame->puc);
+ __copy_to_user(&frame->info, info, sizeof(*info));
+
+ /* Clear all the bits of the ucontext we don't use. */
+ __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
+
+ setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
+ regs, set->sig[0]);
+ __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+ /* Set up to return from userspace. If provided, use a stub
+ already in userspace. */
+ if (ka->sa.sa_flags & SA_RESTORER) {
+ __put_user(ka->sa.sa_restorer, &frame->pretcode);
+ } else {
+ __put_user(frame->retcode, &frame->pretcode);
+ /* This is movl $,%eax ; int $0x80 */
+ __put_user(0xb8, (char *)(frame->retcode+0));
+ __put_user(__NR_rt_sigreturn, (int *)(frame->retcode+1));
+ __put_user(0x80cd, (short *)(frame->retcode+5));
}
- __put_user(regs->xes, frame+4);
- __put_user(regs->xds, frame+5);
- __put_user(regs->edi, frame+6);
- __put_user(regs->esi, frame+7);
- __put_user(regs->ebp, frame+8);
- __put_user(regs->esp, frame+9);
- __put_user(regs->ebx, frame+10);
- __put_user(regs->edx, frame+11);
- __put_user(regs->ecx, frame+12);
- __put_user(regs->eax, frame+13);
- __put_user(current->tss.trap_no, frame+14);
- __put_user(current->tss.error_code, frame+15);
- __put_user(regs->eip, frame+16);
- __put_user(regs->xcs, frame+17);
- __put_user(regs->eflags, frame+18);
- __put_user(regs->esp, frame+19);
- __put_user(regs->xss, frame+20);
- __put_user((unsigned long) save_i387((struct _fpstate *)(frame+32)),frame+21);
-/* non-iBCS2 extensions.. */
- __put_user(oldmask, frame+22);
- __put_user(current->tss.cr2, frame+23);
-/* set up the return code... */
- __put_user(0x0000b858, CODE(0)); /* popl %eax ; movl $,%eax */
- __put_user(0x80cd0000, CODE(4)); /* int $0x80 */
- __put_user(__NR_sigreturn, CODE(2));
-#undef __CODE
-#undef CODE
/* Set up registers for signal handler */
regs->esp = (unsigned long) frame;
- regs->eip = (unsigned long) sa->sa_handler;
+ regs->eip = (unsigned long) ka->sa.sa_handler;
{
- unsigned long seg = USER_DS;
- __asm__("mov %w0,%%fs ; mov %w0,%%gs":"=r" (seg) :"0" (seg));
- set_fs(seg);
+ unsigned long seg = __USER_DS;
+ __asm__("mov %w0,%%fs ; mov %w0,%%gs": "=r"(seg) : "0"(seg));
+ set_fs(MAKE_MM_SEG(seg));
regs->xds = seg;
regs->xes = seg;
regs->xss = seg;
- regs->xcs = USER_CS;
+ regs->xcs = __USER_CS;
}
regs->eflags &= ~TF_MASK;
+
+#if DEBUG_SIG
+ printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
+ current->comm, current->pid, frame, regs->eip, frame->pretcode);
+#endif
+
return;
segv_and_exit:
lock_kernel();
do_exit(SIGSEGV);
- unlock_kernel();
}
/*
* OK, we're invoking a handler
*/
-static void handle_signal(unsigned long signr, struct sigaction *sa,
- unsigned long oldmask, struct pt_regs * regs)
+
+static void
+handle_signal(unsigned long sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
{
- /* are we from a system call? */
+ /* Are we from a system call? */
if (regs->orig_eax >= 0) {
/* If so, check system call restarting.. */
switch (regs->eax) {
@@ -280,7 +520,7 @@ static void handle_signal(unsigned long signr, struct sigaction *sa,
break;
case -ERESTARTSYS:
- if (!(sa->sa_flags & SA_RESTART)) {
+ if (!(ka->sa.sa_flags & SA_RESTART)) {
regs->eax = -EINTR;
break;
}
@@ -291,14 +531,20 @@ static void handle_signal(unsigned long signr, struct sigaction *sa,
}
}
- /* set up the stack frame */
- setup_frame(sa, regs, signr, oldmask);
+ /* Set up the stack frame */
+ if (ka->sa.sa_flags & SA_SIGINFO)
+ setup_rt_frame(sig, ka, info, oldset, regs);
+ else
+ setup_frame(sig, ka, oldset, regs);
+
+ if (ka->sa.sa_flags & SA_ONESHOT)
+ ka->sa.sa_handler = SIG_DFL;
- if (sa->sa_flags & SA_ONESHOT)
- sa->sa_handler = NULL;
- if (!(sa->sa_flags & SA_NOMASK)) {
+ if (!(ka->sa.sa_flags & SA_NODEFER)) {
spin_lock_irq(&current->sigmask_lock);
- current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE;
+ sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+ sigaddset(&current->blocked,sig);
+ recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
}
}
@@ -312,66 +558,82 @@ static void handle_signal(unsigned long signr, struct sigaction *sa,
* the kernel can handle, and then we build all the user-level signal handling
* stack-frames in one go after that.
*/
-asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
{
- unsigned long mask;
- unsigned long signr;
- struct sigaction * sa;
+ siginfo_t info;
+ struct k_sigaction *ka;
/*
- * We want the common case to go fast, which
+ * We want the common case to go fast, which
* is why we may in certain cases get here from
* kernel mode. Just return without doing anything
* if so.
*/
if ((regs->xcs & 3) != 3)
return 1;
- mask = ~current->blocked;
- while ((signr = current->signal & mask)) {
- /*
- * This stops gcc flipping out. Otherwise the assembler
- * including volatiles for the inline function to get
- * current combined with this gets it confused.
- */
- struct task_struct *t=current;
- __asm__("bsf %3,%1\n\t"
-#ifdef __SMP__
- "lock ; "
-#endif
- "btrl %1,%0"
- :"=m" (t->signal),"=r" (signr)
- :"0" (t->signal), "1" (signr));
- sa = current->sig->action + signr;
- signr++;
+
+ if (!oldset)
+ oldset = &current->blocked;
+
+ for (;;) {
+ unsigned long signr;
+
+ spin_lock_irq(&current->sigmask_lock);
+ signr = dequeue_signal(&current->blocked, &info);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ if (!signr)
+ break;
+
if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+ /* Let the debugger run. */
current->exit_code = signr;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
schedule();
+
+ /* We're back. Did the debugger cancel the sig? */
if (!(signr = current->exit_code))
continue;
current->exit_code = 0;
+
+ /* The debugger continued. Ignore SIGSTOP. */
if (signr == SIGSTOP)
continue;
- if (_S(signr) & current->blocked) {
- spin_lock_irq(&current->sigmask_lock);
- current->signal |= _S(signr);
- spin_unlock_irq(&current->sigmask_lock);
+
+ /* Update the siginfo structure. Is this good? */
+ if (signr != info.si_signo) {
+ info.si_signo = signr;
+ info.si_errno = 0;
+ info.si_code = SI_USER;
+ info.si_pid = current->p_pptr->pid;
+ info.si_uid = current->p_pptr->uid;
+ }
+
+ /* If the (new) signal is now blocked, requeue it. */
+ if (sigismember(&current->blocked, signr)) {
+ send_sig_info(signr, &info, current);
continue;
}
- sa = current->sig->action + signr - 1;
}
- if (sa->sa_handler == SIG_IGN) {
+
+ ka = &current->sig->action[signr-1];
+ if (ka->sa.sa_handler == SIG_IGN) {
if (signr != SIGCHLD)
continue;
- /* check for SIGCHLD: it's special */
- while (sys_wait4(-1,NULL,WNOHANG, NULL) > 0)
+ /* Check for SIGCHLD: it's special. */
+ while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
/* nothing */;
continue;
}
- if (sa->sa_handler == SIG_DFL) {
+
+ if (ka->sa.sa_handler == SIG_DFL) {
+ int exit_code = signr;
+
+ /* Init gets no signals it doesn't want. */
if (current->pid == 1)
continue;
+
switch (signr) {
case SIGCONT: case SIGCHLD: case SIGWINCH:
continue;
@@ -379,13 +641,12 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
case SIGTSTP: case SIGTTIN: case SIGTTOU:
if (is_orphaned_pgrp(current->pgrp))
continue;
+ /* FALLTHRU */
+
case SIGSTOP:
- if (current->flags & PF_PTRACED)
- continue;
current->state = TASK_STOPPED;
current->exit_code = signr;
- if (!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags &
- SA_NOCLDSTOP))
+ if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
notify_parent(current, SIGCHLD);
schedule();
continue;
@@ -393,25 +654,24 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
lock_kernel();
- if (current->binfmt && current->binfmt->core_dump) {
- if (current->binfmt->core_dump(signr, regs))
- signr |= 0x80;
- }
+ if (current->binfmt
+ && current->binfmt->core_dump
+ && current->binfmt->core_dump(signr, regs))
+ exit_code |= 0x80;
unlock_kernel();
- /* fall through */
- default:
- spin_lock_irq(&current->sigmask_lock);
- current->signal |= _S(signr & 0x7f);
- spin_unlock_irq(&current->sigmask_lock);
+ /* FALLTHRU */
+ default:
+ lock_kernel();
+ sigaddset(&current->signal, signr);
current->flags |= PF_SIGNALED;
-
- lock_kernel(); /* 8-( */
- do_exit(signr);
- unlock_kernel();
+ do_exit(exit_code);
+ /* NOTREACHED */
}
}
- handle_signal(signr, sa, oldmask, regs);
+
+ /* Whee! Actually deliver the signal. */
+ handle_signal(signr, ka, &info, oldset, regs);
return 1;
}
diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c
index f43dfe726..80ef4be47 100644
--- a/arch/i386/kernel/sys_i386.c
+++ b/arch/i386/kernel/sys_i386.c
@@ -180,7 +180,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
}
case 1: /* iBCS2 emulator entry point */
ret = -EINVAL;
- if (get_fs() != get_ds())
+ if (!segment_eq(get_fs(), get_ds()))
goto out;
ret = sys_shmat (first, (char *) ptr, second, (ulong *) third);
goto out;
@@ -225,15 +225,16 @@ asmlinkage int sys_olduname(struct oldold_utsname * name)
return -EFAULT;
error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
- error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
- error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
- error -= __put_user(0,name->release+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
- error -= __put_user(0,name->version+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
- error = __put_user(0,name->machine+__OLD_UTS_LEN);
+ error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
+ error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
+ error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
+ error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
+ error |= __put_user(0,name->release+__OLD_UTS_LEN);
+ error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
+ error |= __put_user(0,name->version+__OLD_UTS_LEN);
+ error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
+ error |= __put_user(0,name->machine+__OLD_UTS_LEN);
+
error = error ? -EFAULT : 0;
return error;
diff --git a/arch/i386/kernel/trampoline.S b/arch/i386/kernel/trampoline.S
index f44b9abde..9cee704f1 100644
--- a/arch/i386/kernel/trampoline.S
+++ b/arch/i386/kernel/trampoline.S
@@ -53,7 +53,7 @@ r_base = .
lmsw %ax # into protected mode
jmp flush_instr
flush_instr:
- ljmp $KERNEL_CS, $0x00100000
+ ljmp $__KERNEL_CS, $0x00100000
# jump to startup_32
idt_48:
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index f08b7de6b..bd125a041 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -127,7 +127,7 @@ static void show_registers(struct pt_regs *regs)
extern char _stext, _etext;
esp = (unsigned long) &regs->esp;
- ss = KERNEL_DS;
+ ss = __KERNEL_DS;
if (regs->xcs & 3) {
esp = regs->esp;
ss = regs->xss & 0xffff;
@@ -184,7 +184,7 @@ static void show_registers(struct pt_regs *regs)
spinlock_t die_lock;
-/*static*/ void die_if_kernel(const char * str, struct pt_regs * regs, long err)
+void die_if_kernel(const char * str, struct pt_regs * regs, long err)
{
if ((regs->eflags & VM_MASK) || (3 & regs->xcs) == 3)
return;
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index a09fa6419..0628e2d68 100644
--- a/arch/i386/kernel/vm86.c
+++ b/arch/i386/kernel/vm86.c
@@ -438,8 +438,13 @@ int handle_vm86_trap(struct kernel_vm86_regs * regs, long error_code, int trapno
}
if (trapno !=1)
return 1; /* we let this handle by the calling routine */
- if (current->flags & PF_PTRACED)
- current->blocked &= ~(1 << (SIGTRAP-1));
+ if (current->flags & PF_PTRACED) {
+ unsigned long flags;
+ spin_lock_irqsave(&current->sigmask_lock, flags);
+ sigdelset(&current->blocked, SIGTRAP);
+ recalc_sigpending(current);
+ spin_unlock_irqrestore(&current->sigmask_lock, flags);
+ }
send_sig(SIGTRAP, current, 1);
current->tss.trap_no = trapno;
current->tss.error_code = error_code;
diff --git a/arch/i386/lib/delay.c b/arch/i386/lib/delay.c
index c3c29a7d9..4afc206e5 100644
--- a/arch/i386/lib/delay.c
+++ b/arch/i386/lib/delay.c
@@ -9,7 +9,7 @@
*/
#include <linux/sched.h>
-#include <asm/delay.h>
+#include <linux/delay.h>
#ifdef __SMP__
#include <asm/smp.h>
diff --git a/arch/i386/math-emu/errors.c b/arch/i386/math-emu/errors.c
index f76020d1f..38a72e572 100644
--- a/arch/i386/math-emu/errors.c
+++ b/arch/i386/math-emu/errors.c
@@ -42,7 +42,7 @@ void Un_impl(void)
RE_ENTRANT_CHECK_OFF;
/* No need to verify_area(), we have previously fetched these bytes. */
printk("Unimplemented FPU Opcode at eip=%p : ", (void *) address);
- if ( FPU_CS == USER_CS )
+ if ( FPU_CS == __USER_CS )
{
while ( 1 )
{
@@ -93,7 +93,7 @@ void emu_printall(void)
RE_ENTRANT_CHECK_OFF;
/* No need to verify_area(), we have previously fetched these bytes. */
printk("At %p:", (void *) address);
- if ( FPU_CS == USER_CS )
+ if ( FPU_CS == __USER_CS )
{
#define MAX_PRINTED_BYTES 20
for ( i = 0; i < MAX_PRINTED_BYTES; i++ )
diff --git a/arch/i386/math-emu/fpu_entry.c b/arch/i386/math-emu/fpu_entry.c
index 07c32db9a..943daf3b9 100644
--- a/arch/i386/math-emu/fpu_entry.c
+++ b/arch/i386/math-emu/fpu_entry.c
@@ -179,11 +179,11 @@ asmlinkage void math_emulate(long arg)
FPU_EIP += code_base = FPU_CS << 4;
code_limit = code_base + 0xffff; /* Assumes code_base <= 0xffff0000 */
}
- else if ( FPU_CS == USER_CS && FPU_DS == USER_DS )
+ else if ( FPU_CS == __USER_CS && FPU_DS == __USER_DS )
{
addr_modes.default_mode = 0;
}
- else if ( FPU_CS == KERNEL_CS )
+ else if ( FPU_CS == __KERNEL_CS )
{
printk("math_emulate: %04x:%08lx\n",FPU_CS,FPU_EIP);
panic("Math emulation needed in kernel");
diff --git a/arch/m68k/config.in b/arch/m68k/config.in
index 569da18ce..ab460947b 100644
--- a/arch/m68k/config.in
+++ b/arch/m68k/config.in
@@ -207,6 +207,17 @@ endmenu
fi
+# Conditionally compile in the Uniform CD-ROM driver
+if [ "$CONFIG_BLK_DEV_IDECD" = "y" -o "$CONFIG_BLK_DEV_SR" = "y" ]; then
+ define_bool CONFIG_CDROM y
+else
+ if [ "$CONFIG_BLK_DEV_IDECD" = "m" -o "$CONFIG_BLK_DEV_SR" = "m" ]; then
+ define_bool CONFIG_CDROM m
+ else
+ define_bool CONFIG_CDROM n
+ fi
+fi
+
source fs/Config.in
source fs/nls/Config.in
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 10b1581ea..5d38e46ca 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -569,6 +569,8 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_poll)
.long SYMBOL_NAME(sys_nfsservctl)
.long SYMBOL_NAME(sys_prctl)
+ .long SYMBOL_NAME(sys_pread)
+ .long SYMBOL_NAME(sys_pwrite)
.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
.long SYMBOL_NAME(sys_ni_syscall)
.endr
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 2624d2d0c..174de5799 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -13,7 +13,7 @@
# Copyright (C) 1994, 1995, 1996 by Ralf Baechle
# DECStation modifications by Paul M. Antoine, 1996
#
-# $Id: Makefile,v 1.9 1997/09/19 08:34:54 ralf Exp $
+# $Id: Makefile,v 1.9 1997/12/02 01:48:01 ralf Exp $
#
#
@@ -100,22 +100,6 @@ CORE_FILES += arch/mips/algor/algor.o
SUBDIRS += arch/mips/algor
#LOADADDR += 0x80000000
endif
-ifdef CONFIG_DECSTATION
-CORE_FILES += arch/mips/dec/dec.o
-SUBDIRS += arch/mips/dec
-LINKSCRIPT += arch/mips/dec/ld.script
-LOADADDR += 0x80000000
-endif
-ifdef CONFIG_DESKSTATION_RPC44
-CORE_FILES += arch/mips/deskstation/deskstation.o
-SUBDIRS += arch/mips/deskstation
-LOADADDR += 0x80100000
-endif
-ifdef CONFIG_DESKSTATION_TYNE
-CORE_FILES += arch/mips/deskstation/deskstation.o
-SUBDIRS += arch/mips/deskstation
-LOADADDR += 0x80000000
-endif
#
# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
#
@@ -124,9 +108,6 @@ CORE_FILES += arch/mips/jazz/jazz.o
SUBDIRS += arch/mips/jazz
LOADADDR += 0x80000000
endif
-ifdef CONFIG_MIPS_MAGNUM_3000
-LOADADDR += 0x80000000
-endif
ifdef CONFIG_SNI_RM200_PCI
CORE_FILES += arch/mips/sni/sni.o
SUBDIRS += arch/mips/sni
diff --git a/arch/mips/config.in b/arch/mips/config.in
index 44c78e270..1913421be 100644
--- a/arch/mips/config.in
+++ b/arch/mips/config.in
@@ -14,20 +14,10 @@ comment 'Machine selection'
bool 'Support for Acer PICA 1 chipset' CONFIG_ACER_PICA_61
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'Support for Algorithmics P4032' CONFIG_ALGOR_P4032
- bool 'Support for DECstation' CONFIG_DECSTATION
- bool 'Support for Deskstation RPC44' CONFIG_DESKSTATION_RPC44
- bool 'Support for Deskstation Tyne' CONFIG_DESKSTATION_TYNE
- bool 'Support for Mips Magnum 3000' CONFIG_MIPS_MAGNUM_3000
fi
bool 'Support for Mips Magnum 4000' CONFIG_MIPS_MAGNUM_4000
bool 'Support for Olivetti M700-10' CONFIG_OLIVETTI_M700
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- bool 'Support for SGI workstations' CONFIG_SGI
- if [ "$CONFIG_SGI" = "y" ]; then
- bool 'Support for SGI graphic devices' CONFIG_SGI_GRAPHICS
- define_bool CONFIG_UMISC y
- fi
-fi
+bool 'Support for SGI workstations' CONFIG_SGI
bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
#
@@ -44,10 +34,6 @@ if [ "$CONFIG_MIPS_MAGNUM_4000" = "y" -o \
"$CONFIG_OLIVETTI_M700" = "y" ]; then
define_bool CONFIG_VIDEO_G364 y
fi
-if [ "$CONFIG_DESKSTATION_RPC44" = "y" -o \
- "$CONFIG_DESKSTATION_TYNE" = "y" ]; then
- define_bool CONFIG_MIPS_ARC y
-fi
if [ "$CONFIG_ACER_PICA_61" = "y" -o \
"$CONFIG_OLIVETTI_M700" = "y" -o \
"$CONFIG_MIPS_MAGNUM_4000" = "y" ]; then
@@ -174,6 +160,8 @@ if [ "$CONFIG_NET" = "y" ]; then
fi
if [ "$CONFIG_SGI" != "y" ]; then
+ source drivers/net/hamradio/Config.in
+
mainmenu_option next_comment
comment 'ISDN subsystem'
@@ -193,32 +181,34 @@ if [ "$CONFIG_SGI" != "y" ]; then
endmenu
fi
+# Conditionally compile in the Uniform CD-ROM driver
+if [ "$CONFIG_BLK_DEV_IDECD" = "y" -o "$CONFIG_BLK_DEV_SR" = "y" -o "$CONFIG_SBPCD" = "y" -o "$CONFIG_MCD" = "y" -o "$CONFIG_CM206" = "y" -o "$CONFIG_CDU31A" = "y" ]; then
+ define_bool CONFIG_CDROM y
+else
+ if [ "$CONFIG_BLK_DEV_IDECD" = "m" -o "$CONFIG_BLK_DEV_SR" = "m" -o "$CONFIG_SBPCD" = "m" -o "$CONFIG_MCD" = "m" -o "$CONFIG_CM206" = "m" -o "$CONFIG_CDU31A" = "m" ]; then
+ define_bool CONFIG_CDROM m
+ else
+ define_bool CONFIG_CDROM n
+ fi
+fi
+
source fs/Config.in
source fs/nls/Config.in
-if [ "$CONFIG_SGI" != "y" ]; then
- source drivers/char/Config.in
+source drivers/char/Config.in
- mainmenu_option next_comment
- comment 'Sound'
+mainmenu_option next_comment
+comment 'Sound'
- tristate 'Sound card support' CONFIG_SOUND
- if [ "$CONFIG_SOUND" != "n" ]; then
- source drivers/sound/Config.in
- fi
- endmenu
-else
- comment 'SGI Character Devices'
- bool 'Virtual terminal' CONFIG_VT
- if [ "$CONFIG_VT" = "y" ]; then
- bool 'Console on virtual terminal' CONFIG_VT_CONSOLE
- fi
- tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE
- bool 'SGI Zilog85C30 serial support' CONFIG_SGI_SERIAL
- if [ "$CONFIG_SGI_SERIAL" != "n" ]; then
- define_bool CONFIG_SERIAL y
- fi
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+ source drivers/sound/Config.in
+fi
+endmenu
+
+if [ "$CONFIG_SGI" = "y" ]; then
+ source drivers/sgi/char/Config.in
fi
mainmenu_option next_comment
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 147145db6..3120b4b28 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -13,6 +13,7 @@
CONFIG_ACER_PICA_61=y
# CONFIG_MIPS_MAGNUM_4000 is not set
# CONFIG_OLIVETTI_M700 is not set
+# CONFIG_SGI is not set
CONFIG_SNI_RM200_PCI=y
CONFIG_MIPS_JAZZ=y
CONFIG_PCI=y
@@ -64,7 +65,7 @@ CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDESCSI is not set
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_TRITON is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
# CONFIG_IDE_CHIPSETS is not set
#
@@ -80,22 +81,27 @@ CONFIG_BLK_DEV_IDECD=y
#
# Networking options
#
+# CONFIG_PACKET is not set
# CONFIG_NETLINK is not set
# CONFIG_FIREWALL is not set
# CONFIG_NET_ALIAS is not set
+CONFIG_UNIX=y
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
# CONFIG_IP_ACCT is not set
+# CONFIG_IP_MASQUERADE is not set
# CONFIG_IP_ROUTER is not set
# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
# CONFIG_SYN_COOKIES is not set
#
# (it is safe to leave these untouched)
#
-# CONFIG_INET_PCTCP is not set
# CONFIG_INET_RARP is not set
-CONFIG_PATH_MTU_DISCOVERY=y
CONFIG_IP_NOSR=y
# CONFIG_SKB_LARGE is not set
@@ -104,7 +110,6 @@ CONFIG_IP_NOSR=y
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
-# CONFIG_AX25 is not set
#
# SCSI support
@@ -138,14 +143,20 @@ CONFIG_PCNET32=y
# CONFIG_FDDI is not set
# CONFIG_DLCI is not set
# CONFIG_PPP is not set
-# CONFIG_NET_RADIO is not set
# CONFIG_SLIP is not set
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
# CONFIG_TR is not set
# CONFIG_WAN_DRIVERS is not set
# CONFIG_LAPBETHER is not set
# CONFIG_X25_ASY is not set
#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
# ISDN subsystem
#
# CONFIG_ISDN is not set
@@ -154,6 +165,7 @@ CONFIG_PCNET32=y
# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
#
# CONFIG_CD_NO_IDESCSI is not set
+CONFIG_CDROM=y
#
# Filesystems
@@ -169,12 +181,10 @@ CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_PROC_FS=y
CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_RNFS_BOOTP=y
-# CONFIG_RNFS_RARP is not set
CONFIG_NFSD=y
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
+# CONFIG_CODA_FS is not set
# CONFIG_SMB_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_SYSV_FS is not set
@@ -221,6 +231,7 @@ CONFIG_NLS_ISO8859_1=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_MOUSE is not set
@@ -228,6 +239,9 @@ CONFIG_SERIAL=y
# CONFIG_APM is not set
# CONFIG_WATCHDOG is not set
# CONFIG_RTC is not set
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_PMS is not set
# CONFIG_NVRAM is not set
# CONFIG_JOYSTICK is not set
# CONFIG_MISC_RADIO is not set
diff --git a/arch/mips/jazz/g364.c b/arch/mips/jazz/g364.c
index dc0c7fac0..92522dcd1 100644
--- a/arch/mips/jazz/g364.c
+++ b/arch/mips/jazz/g364.c
@@ -432,3 +432,11 @@ void
set_vesa_blanking(const unsigned long arg)
{
}
+
+/*
+ * FIXME: how can we probe for the video board?
+ */
+__initfunc(int con_is_present())
+{
+ return;
+}
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 2e286da80..e0e98d9b5 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -7,7 +7,7 @@
*
* Copyright (C) 1994, 1995 by Ralf Baechle
*
- * $Id: entry.S,v 1.4 1997/09/20 19:20:13 root Exp $
+ * $Id: entry.S,v 1.4 1997/12/01 17:57:25 ralf Exp $
*/
/*
@@ -57,24 +57,17 @@ EXPORT(ret_from_irq)
bnez t0,handle_bottom_half
9: lw t0,PT_STATUS(sp) # returning to kernel mode?
- andi t1,t0, 0x10
- beqz t1,return # -> yes
- lw t1,need_resched
- bnez t1,reschedule
+ andi t1, t0, 0x10
+ beqz t1, return # -> yes
+ lw t1, need_resched
+ bnez t1, reschedule
GET_CURRENT(s0)
- lw t0,task
- lw a0,TASK_BLOCKED(s0)
-
- beq s0,t0,return # task[0] cannot have signals
- lw t0,TASK_SIGNAL(s0)
-
- nor t1,zero,a0
- and t1,t0,t1
- beqz t1,return
+ lw v0, TASK_SIGPENDING(s0)
+ move a0, zero
+ beqz v0, return
nop
-
jal do_signal
- move a1,sp
+ move a1, sp
EXPORT(return) .set noat
RESTORE_ALL
diff --git a/arch/mips/kernel/ipc.c b/arch/mips/kernel/ipc.c
index 2e91b6755..2e764a607 100644
--- a/arch/mips/kernel/ipc.c
+++ b/arch/mips/kernel/ipc.c
@@ -101,7 +101,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
}
case 1: /* iBCS2 emulator entry point */
ret = -EINVAL;
- if (get_fs() != get_ds())
+ if (!segment_eq(get_fs(), get_ds()))
goto out;
ret = sys_shmat (first, (char *) ptr, second, (ulong *) third);
goto out;
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index a64ebd1f6..b29bc0563 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -447,7 +447,8 @@ static inline int look_for_irix_interpreter(char **name,
struct elf_phdr *epp,
struct linux_binprm *bprm, int pnum)
{
- int i, old_fs;
+ mm_segment_t old_fs;
+ int i;
int retval = -EINVAL;
struct dentry *dentry = NULL;
@@ -551,7 +552,7 @@ static inline void map_executable(struct file *fp, struct elf_phdr *epp, int pnu
static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp,
struct dentry *identry, unsigned int *iladdr,
- int pnum, int old_fs,
+ int pnum, mm_segment_t old_fs,
unsigned int *eentry)
{
int i;
@@ -616,8 +617,9 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
unsigned int load_addr, elf_bss, elf_brk;
unsigned int elf_entry, interp_load_addr = 0;
unsigned int start_code, end_code, end_data, elf_stack;
- int old_fs, elf_exec_fileno, retval, has_interp, has_ephdr, i;
+ int elf_exec_fileno, retval, has_interp, has_ephdr, i;
char *elf_interpreter;
+ mm_segment_t old_fs;
load_addr = 0;
has_interp = has_ephdr = 0;
@@ -1124,7 +1126,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs)
struct file file;
struct dentry *dentry;
struct inode *inode;
- unsigned short fs;
+ mm_segment_t fs;
char corefile[6+sizeof(current->comm)];
int segs;
int i;
diff --git a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c
index 1483da812..4dea62d59 100644
--- a/arch/mips/kernel/irixioctl.c
+++ b/arch/mips/kernel/irixioctl.c
@@ -1,4 +1,4 @@
-/* $Id: irixioctl.c,v 1.1.1.1 1997/06/01 03:16:43 ralf Exp $
+/* $Id: irixioctl.c,v 1.3 1997/12/15 10:37:27 ralf Exp $
* irixioctl.c: A fucking mess...
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -55,8 +55,8 @@ static struct tty_struct *get_real_tty(struct tty_struct *tp)
asmlinkage int irix_ioctl(int fd, unsigned long cmd, unsigned long arg)
{
struct tty_struct *tp, *rtp;
+ mm_segment_t old_fs;
int error = 0;
- int old_fs;
lock_kernel();
#ifdef DEBUG_IOCTLS
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 76c5abf71..b2f9d592b 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -1,4 +1,4 @@
-/* $Id: irixsig.c,v 1.5 1997/12/01 17:57:27 ralf Exp $
+/* $Id: irixsig.c,v 1.8 1997/12/15 17:38:34 ralf Exp $
* irixsig.c: WHEEE, IRIX signals! YOW, am I compatable or what?!?!
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -15,12 +15,19 @@
#include <asm/ptrace.h>
#include <asm/uaccess.h>
+asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
+ int options, unsigned long *ru);
+
#undef DEBUG_SIG
#define _S(nr) (1<<((nr)-1))
#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
+typedef struct {
+ unsigned long sig[4];
+} irix_sigset_t;
+
struct sigctx_irix5 {
u32 rmask, cp0_status;
u64 pc;
@@ -29,7 +36,7 @@ struct sigctx_irix5 {
u32 usedfp, fpcsr, fpeir, sstk_flags;
u64 hi, lo;
u64 cp0_cause, cp0_badvaddr, _unused0;
- u32 sigset[4];
+ irix_sigset_t sigset;
u64 weird_fpu_thing;
u64 _unused1[31];
};
@@ -63,14 +70,15 @@ static inline void dump_irix5_sigctx(struct sigctx_irix5 *c)
(unsigned long) c->hi, (unsigned long) c->lo,
(unsigned long) c->cp0_cause, (unsigned long) c->cp0_badvaddr);
printk("misc: sigset<0>[%08lx] sigset<1>[%08lx] sigset<2>[%08lx] "
- "sigset<3>[%08lx]\n", (unsigned long) c->sigset[0],
- (unsigned long) c->sigset[1], (unsigned long) c->sigset[2],
- (unsigned long) c->sigset[3]);
+ "sigset<3>[%08lx]\n", (unsigned long) c->sigset.sig[0],
+ (unsigned long) c->sigset.sig[1],
+ (unsigned long) c->sigset.sig[2],
+ (unsigned long) c->sigset.sig[3]);
}
#endif
-static void setup_irix_frame(struct sigaction * sa, struct pt_regs *regs,
- int signr, unsigned long oldmask)
+static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
+ int signr, sigset_t *oldmask)
{
unsigned long sp;
struct sigctx_irix5 *ctx;
@@ -98,10 +106,7 @@ static void setup_irix_frame(struct sigaction * sa, struct pt_regs *regs,
__put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */
- __put_user(0, &ctx->sigset[1]);
- __put_user(0, &ctx->sigset[2]);
- __put_user(0, &ctx->sigset[3]);
- __put_user(oldmask, &ctx->sigset[0]);
+ __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t));
#ifdef DEBUG_SIG
dump_irix5_sigctx(ctx);
@@ -110,7 +115,7 @@ static void setup_irix_frame(struct sigaction * sa, struct pt_regs *regs,
regs->regs[5] = 0; /* XXX sigcode XXX */
regs->regs[4] = (unsigned long) signr;
regs->regs[6] = regs->regs[29] = sp;
- regs->regs[7] = (unsigned long) sa->sa_handler;
+ regs->regs[7] = (unsigned long) ka->sa.sa_handler;
regs->regs[25] = regs->cp0_epc = current->tss.irix_trampoline;
return;
@@ -120,52 +125,126 @@ segv_and_exit:
unlock_kernel();
}
-asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
- int options, unsigned long *ru);
+static void inline
+setup_irix_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *oldmask, siginfo_t *info)
+{
+ lock_kernel();
+ printk("Aiee: setup_tr_frame wants to be written");
+ do_exit(SIGSEGV);
+ unlock_kernel();
+}
+
+static inline void handle_signal(unsigned long sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
+{
+ if (ka->sa.sa_flags & SA_SIGINFO)
+ setup_irix_rt_frame(ka, regs, sig, oldset, info);
+ else
+ setup_irix_frame(ka, regs, sig, oldset);
+
+ if (ka->sa.sa_flags & SA_ONESHOT)
+ ka->sa.sa_handler = SIG_DFL;
+ if (!(ka->sa.sa_flags & SA_NODEFER)) {
+ spin_lock_irq(&current->sigmask_lock);
+ sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+ sigaddset(&current->blocked,sig);
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+ }
+}
+
+static inline void syscall_restart(unsigned long r0, unsigned long or2,
+ unsigned long or7, struct pt_regs *regs,
+ struct sigaction *sa)
+{
+ switch(r0) {
+ case ERESTARTNOHAND:
+ no_system_call_restart:
+ regs->regs[0] = regs->regs[2] = EINTR;
+ break;
+ case ERESTARTSYS:
+ if(!(sa->sa_flags & SA_RESTART))
+ goto no_system_call_restart;
+ /* fallthrough */
+ case ERESTARTNOINTR:
+ regs->regs[0] = regs->regs[2] = or2;
+ regs->regs[7] = or7;
+ regs->cp0_epc -= 8;
+ }
+}
-asmlinkage int do_irix_signal(unsigned long oldmask, struct pt_regs * regs)
+asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
{
- unsigned long mask = ~current->blocked;
- unsigned long handler_signal = 0;
+ unsigned long r0 = regs->regs[0];
+ unsigned long r7 = regs->orig_reg7;
+ struct k_sigaction *ka;
unsigned long signr;
- struct sigaction * sa;
+ sigset_t _oldset;
+ siginfo_t info;
+
+ if (!oldset)
+ oldset = &current->blocked;
+
+ for (;;) {
+ unsigned long signr;
+
+ spin_lock_irq(&current->sigmask_lock);
+ signr = dequeue_signal(&current->blocked, &info);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ if (!signr)
+ break;
-#ifdef DEBUG_SIG
- printk("[%s:%d] Delivering IRIX signal oldmask=%08lx\n",
- current->comm, current->pid, oldmask);
-#endif
- while ((signr = current->signal & mask)) {
- signr = ffz(~signr);
- clear_bit(signr, &current->signal);
- sa = current->sig->action + signr;
- signr++;
if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+ /* Let the debugger run. */
current->exit_code = signr;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
schedule();
+
+ /* We're back. Did the debugger cancel the sig? */
if (!(signr = current->exit_code))
continue;
current->exit_code = 0;
+
+ /* The debugger continued. Ignore SIGSTOP. */
if (signr == SIGSTOP)
continue;
- if (_S(signr) & current->blocked) {
- current->signal |= _S(signr);
+
+ /* Update the siginfo structure. Is this good? */
+ if (signr != info.si_signo) {
+ info.si_signo = signr;
+ info.si_errno = 0;
+ info.si_code = SI_USER;
+ info.si_pid = current->p_pptr->pid;
+ info.si_uid = current->p_pptr->uid;
+ }
+
+ /* If the (new) signal is now blocked, requeue it. */
+ if (sigismember(&current->blocked, signr)) {
+ send_sig_info(signr, &info, current);
continue;
}
- sa = current->sig->action + signr - 1;
}
- if (sa->sa_handler == SIG_IGN) {
+
+ ka = &current->sig->action[signr-1];
+ if (ka->sa.sa_handler == SIG_IGN) {
if (signr != SIGCHLD)
continue;
- /* check for SIGCHLD: it's special */
- while (sys_wait4(-1,NULL,WNOHANG, NULL) > 0)
+ /* Check for SIGCHLD: it's special. */
+ while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
/* nothing */;
continue;
}
- if (sa->sa_handler == SIG_DFL) {
+
+ if (ka->sa.sa_handler == SIG_DFL) {
+ int exit_code = signr;
+
+ /* Init gets no signals it doesn't want. */
if (current->pid == 1)
continue;
+
switch (signr) {
case SIGCONT: case SIGCHLD: case SIGWINCH:
continue;
@@ -173,78 +252,56 @@ asmlinkage int do_irix_signal(unsigned long oldmask, struct pt_regs * regs)
case SIGTSTP: case SIGTTIN: case SIGTTOU:
if (is_orphaned_pgrp(current->pgrp))
continue;
+ /* FALLTHRU */
+
case SIGSTOP:
- if (current->flags & PF_PTRACED)
- continue;
current->state = TASK_STOPPED;
current->exit_code = signr;
- if (!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags &
- SA_NOCLDSTOP))
+ if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
notify_parent(current, SIGCHLD);
schedule();
continue;
case SIGQUIT: case SIGILL: case SIGTRAP:
- case SIGIOT: case SIGFPE: case SIGSEGV: case SIGBUS:
+ case SIGABRT: case SIGFPE: case SIGSEGV:
lock_kernel();
- if (current->binfmt && current->binfmt->core_dump) {
- if (current->binfmt->core_dump(signr, regs))
- signr |= 0x80;
- }
+ if (current->binfmt
+ && current->binfmt->core_dump
+ && current->binfmt->core_dump(signr, regs))
+ exit_code |= 0x80;
unlock_kernel();
- /* fall through */
+ /* FALLTHRU */
+
default:
- current->signal |= _S(signr & 0x7f);
+ lock_kernel();
+ sigaddset(&current->signal, signr);
current->flags |= PF_SIGNALED;
- lock_kernel(); /* 8-( */
- do_exit(signr);
- unlock_kernel();
- }
- }
- /*
- * OK, we're invoking a handler
- */
- if (regs->orig_reg2 >= 0) {
- if (regs->regs[2] == ERESTARTNOHAND) {
- regs->regs[2] = EINTR;
- } else if((regs->regs[2] == ERESTARTSYS &&
- !(sa->sa_flags & SA_RESTART))) {
- regs->regs[2] = regs->orig_reg2;
- regs->cp0_epc -= 8;
+ do_exit(exit_code);
+ /* NOTREACHED */
}
}
- handler_signal |= 1 << (signr-1);
- mask &= ~sa->sa_mask;
+
+ if (r0)
+ syscall_restart(r0, regs->orig_reg2, r7, regs, &ka->sa);
+ /* Whee! Actually deliver the signal. */
+ handle_signal(signr, ka, &info, oldset, regs);
+ return 1;
}
+
/*
* Who's code doesn't conform to the restartable syscall convention
* dies here!!! The li instruction, a single machine instruction,
* must directly be followed by the syscall instruction.
*/
- if (regs->orig_reg2 >= 0 &&
+ if (r0 &&
(regs->regs[2] == ERESTARTNOHAND ||
regs->regs[2] == ERESTARTSYS ||
regs->regs[2] == ERESTARTNOINTR)) {
- regs->regs[2] = regs->orig_reg2;
+ regs->regs[0] = regs->regs[2] = regs->orig_reg2;
+ regs->regs[7] = r7;
regs->cp0_epc -= 8;
}
- if (!handler_signal) /* no handler will be called - return 0 */
- return 0;
- signr = 1;
- sa = current->sig->action;
- for (mask = 1 ; mask ; sa++,signr++,mask += mask) {
- if (mask > handler_signal)
- break;
- if (!(mask & handler_signal))
- continue;
- setup_irix_frame(sa, regs, signr, oldmask);
- if (sa->sa_flags & SA_ONESHOT)
- sa->sa_handler = NULL;
- current->blocked |= sa->sa_mask;
- oldmask |= sa->sa_mask;
- }
-
- return 1;
+ return 0;
}
asmlinkage unsigned long irix_sigreturn(struct pt_regs *regs)
@@ -253,6 +310,7 @@ asmlinkage unsigned long irix_sigreturn(struct pt_regs *regs)
unsigned long umask, mask;
u64 *fregs, res;
int sig, i, base = 0;
+ sigset_t blocked;
if(regs->regs[2] == 1000)
base = 1;
@@ -291,10 +349,18 @@ asmlinkage unsigned long irix_sigreturn(struct pt_regs *regs)
/* XXX do sigstack crapola here... XXX */
+ if (__copy_from_user(&blocked, &context->sigset, sizeof(blocked)))
+ goto badframe;
+
+ sigdelsetmask(&blocked, ~_BLOCKABLE);
+ spin_lock_irq(&current->sigmask_lock);
+ current->blocked = blocked;
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+
regs->orig_reg2 = -1;
- __get_user(current->blocked, &context->sigset[0]);
- current->blocked &= _BLOCKABLE;
__get_user(res, &context->regs[2]);
+
return res;
badframe:
@@ -321,27 +387,12 @@ static inline void dump_sigact_irix5(struct sigact_irix5 *p)
}
#endif
-static inline void check_pending(int signum)
+asmlinkage int
+irix_sigaction(int sig, const struct sigaction *act,
+ struct sigaction *oact, unsigned long trampoline)
{
- struct sigaction *p;
-
- p = signum - 1 + current->sig->action;
- spin_lock(&current->sigmask_lock);
- if (p->sa_handler == SIG_IGN) {
- current->signal &= ~_S(signum);
- } else if (p->sa_handler == SIG_DFL) {
- if (signum != SIGCONT && signum != SIGCHLD && signum != SIGWINCH)
- return;
- current->signal &= ~_S(signum);
- }
- spin_unlock(&current->sigmask_lock);
-}
-
-asmlinkage int irix_sigaction(int sig, struct sigact_irix5 *new,
- struct sigact_irix5 *old, unsigned long trampoline)
-{
- struct sigaction new_sa, *p;
- int res;
+ struct k_sigaction new_ka, old_ka;
+ int ret;
#ifdef DEBUG_SIG
printk(" (%d,%s,%s,%08lx) ", sig, (!new ? "0" : "NEW"),
@@ -350,110 +401,103 @@ asmlinkage int irix_sigaction(int sig, struct sigact_irix5 *new,
dump_sigact_irix5(new); printk(" ");
}
#endif
- if(sig < 1 || sig > 32) {
- return -EINVAL;
- }
- p = sig - 1 + current->sig->action;
+ if (act) {
+ sigset_t mask;
+ if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+ __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+ __get_user(new_ka.sa.sa_flags, &act->sa_flags))
+ return -EFAULT;
- if(new) {
- res = verify_area(VERIFY_READ, new, sizeof(*new));
- if(res)
- return res;
- if(sig == SIGKILL || sig == SIGSTOP) {
- return -EINVAL;
- }
- __get_user(new_sa.sa_flags, &new->flags);
- __get_user(new_sa.sa_handler, &(__sighandler_t) new->handler);
- __get_user(new_sa.sa_mask, &new->sigset[0]);
-
- if(new_sa.sa_handler != SIG_DFL && new_sa.sa_handler != SIG_IGN) {
- res = verify_area(VERIFY_READ, new_sa.sa_handler, 1);
- if(res)
- return res;
- }
+ __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t));
+ new_ka.ka_restorer = NULL;
}
- /* Hmmm... methinks IRIX libc always passes a valid trampoline
+
+ /*
+ * Hmmm... methinks IRIX libc always passes a valid trampoline
* value for all invocations of sigaction. Will have to
* investigate. POSIX POSIX, die die die...
*/
current->tss.irix_trampoline = trampoline;
- if(old) {
- int res = verify_area(VERIFY_WRITE, old, sizeof(*old));
- if(res)
- return res;
- __put_user(p->sa_flags, &old->flags);
- __put_user(p->sa_handler, &old->handler);
- __put_user(p->sa_mask, &old->sigset[0]);
- __put_user(0, &old->sigset[1]);
- __put_user(0, &old->sigset[2]);
- __put_user(0, &old->sigset[3]);
- __put_user(0, &old->_unused0[0]);
- __put_user(0, &old->_unused0[1]);
- }
- if(new) {
- spin_lock_irq(&current->sig->siglock);
- *p = new_sa;
- check_pending(sig);
- spin_unlock_irq(&current->sig->siglock);
+
+/* XXX Implement SIG_SETMASK32 for IRIX compatibility */
+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+ if (!ret && oact) {
+ if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
+ return -EFAULT;
+ __copy_to_user(&old_ka.sa.sa_mask, &oact->sa_mask,
+ sizeof(sigset_t));
}
- return 0;
+ return ret;
}
-asmlinkage int irix_sigpending(unsigned long *set)
+asmlinkage int irix_sigpending(irix_sigset_t *set)
{
- int res;
-
lock_kernel();
- res = verify_area(VERIFY_WRITE, set, (sizeof(unsigned long) * 4));
- if(!res) {
- /* fill in "set" with signals pending but blocked. */
- spin_lock_irq(&current->sigmask_lock);
- __put_user(0, &set[1]);
- __put_user(0, &set[2]);
- __put_user(0, &set[3]);
- __put_user((current->blocked & current->signal), &set[0]);
- spin_unlock_irq(&current->sigmask_lock);
- }
- return res;
+ if (verify_area(VERIFY_WRITE, set, sizeof(*set)) < 0)
+ return -EFAULT;
+
+ /* fill in "set" with signals pending but blocked. */
+ spin_lock_irq(&current->sigmask_lock);
+ __put_user(current->blocked.sig[0] & current->signal.sig[0],
+ &set->sig[0]);
+ __put_user(current->blocked.sig[1] & current->signal.sig[1],
+ &set->sig[1]);
+ __put_user(current->blocked.sig[2] & current->signal.sig[2],
+ &set->sig[2]);
+ __put_user(current->blocked.sig[3] & current->signal.sig[3],
+ &set->sig[3]);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ return 0;
}
-asmlinkage int irix_sigprocmask(int how, unsigned long *new, unsigned long *old)
+asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
{
- unsigned long bits, oldbits = current->blocked;
+ sigset_t oldbits, newbits;
int error;
+
if(new) {
- error = verify_area(VERIFY_READ, new, (sizeof(unsigned long) * 4));
+ error = verify_area(VERIFY_READ, new, sizeof(*new));
if(error)
return error;
- bits = new[0] & _BLOCKABLE;
+ __copy_from_user(&newbits, new, sizeof(unsigned long)*4);
+ sigdelsetmask(&newbits, ~_BLOCKABLE);
+
+ spin_lock_irq(&current->sigmask_lock);
+ oldbits = current->blocked;
+
switch(how) {
case 1:
- current->blocked |= bits;
+ sigorsets(&newbits, &oldbits, &newbits);
break;
case 2:
- current->blocked &= ~bits;
+ sigandsets(&newbits, &oldbits, &newbits);
break;
case 3:
+ break;
+
case 256:
- current->blocked = bits;
+ siginitset(&newbits, newbits.sig[0]);
break;
default:
return -EINVAL;
}
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
}
if(old) {
- error = verify_area(VERIFY_WRITE, old, (sizeof(unsigned long) * 4));
+ error = verify_area(VERIFY_WRITE, old, sizeof(*old));
if(error)
return error;
- __put_user(0, &old[1]);
- __put_user(0, &old[2]);
- __put_user(0, &old[3]);
- __put_user(oldbits, &old[0]);
+ __copy_to_user(old, &current->blocked, sizeof(unsigned long)*4);
}
return 0;
@@ -461,26 +505,25 @@ asmlinkage int irix_sigprocmask(int how, unsigned long *new, unsigned long *old)
asmlinkage int irix_sigsuspend(struct pt_regs *regs)
{
- unsigned int mask;
- unsigned long *uset;
- int base = 0, error;
+ sigset_t *uset, saveset, newset;
- if(regs->regs[2] == 1000)
- base = 1;
-
- uset = (unsigned long *) regs->regs[base + 4];
- if(verify_area(VERIFY_READ, uset, (sizeof(unsigned long) * 4)))
+ uset = (sigset_t *) regs->regs[4];
+ if (copy_from_user(&newset, uset, sizeof(sigset_t)))
return -EFAULT;
- mask = current->blocked;
+ sigdelsetmask(&newset, ~_BLOCKABLE);
- current->blocked = uset[0] & _BLOCKABLE;
- while(1) {
+ spin_lock_irq(&current->sigmask_lock);
+ saveset = current->blocked;
+ current->blocked = newset;
+ spin_unlock_irq(&current->sigmask_lock);
+
+ regs->regs[2] = -EINTR;
+ while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if(do_irix_signal(mask, regs))
+ if (do_irix_signal(&saveset, regs))
return -EINTR;
}
- return error;
}
/* hate hate hate... */
@@ -524,8 +567,9 @@ static inline unsigned long timespectojiffies(struct timespec *value)
asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
struct timespec *tp)
{
- unsigned long mask, kset, expire = 0;
- int sig, error, timeo = 0;
+ unsigned long expire = 0;
+ sigset_t kset;
+ int i, sig, error, timeo = 0;
lock_kernel();
#ifdef DEBUG_SIG
@@ -537,11 +581,15 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
if(!set)
return -EINVAL;
- error = get_user(kset, &set[0]);
- if(error)
+ error = verify_area(VERIFY_READ, set, sizeof(kset));
+ if (error)
+ goto out;
+
+ __copy_from_user(&kset, set, sizeof(set));
+ if (error)
goto out;
- if(info && clear_user(info, sizeof(*info))) {
+ if (info && clear_user(info, sizeof(*info))) {
error = -EFAULT;
goto out;
}
@@ -559,21 +607,32 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
}
while(1) {
+ long tmp = 0;
+
current->state = TASK_INTERRUPTIBLE; schedule();
- if(current->signal & kset) break;
- if(tp && expire <= jiffies) {
+
+ for (i=0; i<=4; i++)
+ tmp |= (current->signal.sig[i] & kset.sig[i]);
+
+ if (tmp)
+ break;
+ if (tp && expire <= jiffies) {
timeo = 1;
break;
}
- if(signal_pending(current)) return -EINTR;
+ if (signal_pending(current))
+ return -EINTR;
}
+ if (timeo)
+ return -EAGAIN;
- if(timeo) return -EAGAIN;
- for(sig = 1, mask = 2; mask; mask <<= 1, sig++) {
- if(!(mask & kset)) continue;
- if(mask & current->signal) {
+ for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
+ if (sigismember (&kset, sig))
+ continue;
+ if (sigismember (&current->signal, sig)) {
/* XXX need more than this... */
- if(info) info->sig = sig;
+ if (info)
+ info->sig = sig;
error = 0;
goto out;
}
@@ -724,6 +783,7 @@ asmlinkage int irix_getcontext(struct pt_regs *regs)
{
int error, i, base = 0;
struct irix5_context *ctx;
+ unsigned long flags;
lock_kernel();
if(regs->regs[2] == 1000)
@@ -738,28 +798,32 @@ asmlinkage int irix_getcontext(struct pt_regs *regs)
error = verify_area(VERIFY_WRITE, ctx, sizeof(*ctx));
if(error)
goto out;
- ctx->flags = 0x0f;
- ctx->link = current->tss.irix_oldctx;
- ctx->sigmask[1] = ctx->sigmask[2] = ctx->sigmask[4] = 0;
- ctx->sigmask[0] = current->blocked;
+ __put_user(current->tss.irix_oldctx, &ctx->link);
+
+ __copy_to_user(&ctx->sigmask, &current->blocked, sizeof(irix_sigset_t));
/* XXX Do sigstack stuff someday... */
- ctx->stack.sp = ctx->stack.size = ctx->stack.flags = 0;
+ __put_user(0, &ctx->stack.sp);
+ __put_user(0, &ctx->stack.size);
+ __put_user(0, &ctx->stack.flags);
- ctx->weird_graphics_thing = 0;
- ctx->regs[0] = 0;
+ __put_user(0, &ctx->weird_graphics_thing);
+ __put_user(0, &ctx->regs[0]);
for(i = 1; i < 32; i++)
- ctx->regs[i] = regs->regs[i];
- ctx->regs[32] = regs->lo;
- ctx->regs[33] = regs->hi;
- ctx->regs[34] = regs->cp0_cause;
- ctx->regs[35] = regs->cp0_epc;
+ __put_user(regs->regs[i], &ctx->regs[i]);
+ __put_user(regs->lo, &ctx->regs[32]);
+ __put_user(regs->hi, &ctx->regs[33]);
+ __put_user(regs->cp0_cause, &ctx->regs[34]);
+ __put_user(regs->cp0_epc, &ctx->regs[35]);
+
+ flags = 0x0f;
if(!current->used_math) {
- ctx->flags &= ~(0x08);
+ flags &= ~(0x08);
} else {
/* XXX wheee... */
printk("Wheee, no code for saving IRIX FPU context yet.\n");
}
+ __put_user(flags, &ctx->flags);
error = 0;
out:
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 6d28d6e98..941abec8f 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -36,7 +36,7 @@
#include <asm/sgialib.h>
#endif
-int active_ds = USER_DS;
+mm_segment_t active_ds = USER_DS;
asmlinkage void ret_from_sys_call(void);
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index b5a5a4428..ebd657d4c 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -435,7 +435,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
case PTRACE_CONT: { /* restart after signal. */
- if ((unsigned long) data > NSIG) {
+ if ((unsigned long) data > _NSIG) {
res = -EIO;
goto out;
}
@@ -464,7 +464,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
}
case PTRACE_DETACH: { /* detach a process that was attached. */
- if ((unsigned long) data > NSIG) {
+ if ((unsigned long) data > _NSIG) {
res = -EIO;
goto out;
}
@@ -502,9 +502,7 @@ asmlinkage void syscall_trace(void)
* stopping signal is not SIGTRAP. -brl
*/
if (current->exit_code) {
- spin_lock_irq(&current->sigmask_lock);
- current->signal |= (1 << (current->exit_code - 1));
- spin_unlock_irq(&current->sigmask_lock);
+ send_sig(current->exit_code, current, 1);
+ current->exit_code = 0;
}
- current->exit_code = 0;
}
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 474437ef5..98f99f9f5 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -5,7 +5,7 @@
* Copyright (C) 1995, 1996 Ralf Baechle
* Copyright (C) 1996 Stoned Elipot
*
- * $Id: setup.c,v 1.4 1997/12/01 17:57:31 ralf Exp $
+ * $Id: setup.c,v 1.5 1997/12/02 23:44:02 ralf Exp $
*/
#include <linux/config.h>
#include <linux/errno.h>
@@ -175,20 +175,6 @@ __initfunc(void setup_arch(char **cmdline_p,
switch(mips_machgroup)
{
-#ifdef CONFIG_MIPS_DECSTATION
- case MACH_GROUP_DEC:
- decstation_setup();
- break;
-#endif
-#if defined(CONFIG_MIPS_ARC)
- /*
- * Perhaps arch/mips/deskstation should be renamed to arch/mips/arc.
- * For now CONFIG_MIPS_ARC means DeskStation. -Stoned.
- */
- case MACH_GROUP_ARC:
- deskstation_setup();
- break;
-#endif
#ifdef CONFIG_MIPS_JAZZ
case MACH_GROUP_JAZZ:
jazz_setup();
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 481a34147..2095d63fb 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -4,7 +4,7 @@
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright (C) 1994, 1995, 1996 Ralf Baechle
*
- * $Id: signal.c,v 1.8 1997/12/01 16:26:34 ralf Exp $
+ * $Id: signal.c,v 1.7 1997/12/01 17:57:31 ralf Exp $
*/
#include <linux/config.h>
#include <linux/sched.h>
@@ -23,58 +23,94 @@
#include <asm/pgtable.h>
#include <asm/uaccess.h>
-#define _S(nr) (1<<((nr)-1))
+#define DEBUG_SIG 0
-#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
int options, unsigned long *ru);
-asmlinkage int do_signal(unsigned long oldmask, struct pt_regs *regs);
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
extern asmlinkage void (*save_fp_context)(struct sigcontext *sc);
extern asmlinkage void (*restore_fp_context)(struct sigcontext *sc);
/*
* Atomically swap in the new signal mask, and wait for a signal.
- * Unlike on Intel we pass a sigset_t *, not sigset_t.
*/
-asmlinkage int sys_sigsuspend(struct pt_regs *regs)
+asmlinkage inline int
+sys_sigsuspend(struct pt_regs *regs)
{
- unsigned long mask;
- sigset_t *uset, set;
+ sigset_t *uset, saveset, newset;
uset = (sigset_t *) regs->regs[4];
- if (get_user(set, uset))
+ if (copy_from_user(&newset, uset, sizeof(sigset_t)))
return -EFAULT;
+ sigdelsetmask(&newset, ~_BLOCKABLE);
spin_lock_irq(&current->sigmask_lock);
- mask = current->blocked;
- current->blocked = set & _BLOCKABLE;
+ saveset = current->blocked;
+ current->blocked = newset;
spin_unlock_irq(&current->sigmask_lock);
regs->regs[2] = -EINTR;
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(mask, regs))
+ if (do_signal(&saveset, regs))
return -EINTR;
}
- return -EINTR;
}
-asmlinkage int sys_sigreturn(struct pt_regs *regs)
+asmlinkage int
+sys_rt_sigsuspend(struct pt_regs *regs)
+{
+ if (regs->regs[5] != sizeof(sigset_t))
+ return -EINVAL;
+ return sys_sigsuspend(regs);
+}
+
+asmlinkage int
+sys_sigaction(int sig, const struct sigaction *act,
+ struct sigaction *oact)
+{
+ struct k_sigaction new_ka, old_ka;
+ int ret;
+
+ if (act) {
+ sigset_t mask;
+ if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+ __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+ __get_user(new_ka.sa.sa_flags, &act->sa_flags))
+ return -EFAULT;
+
+ __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t));
+ new_ka.ka_restorer = NULL;
+ }
+
+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+ if (!ret && oact) {
+ if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
+ return -EFAULT;
+ __copy_to_user(&old_ka.sa.sa_mask, &oact->sa_mask,
+ sizeof(sigset_t));
+ }
+
+ return ret;
+}
+
+/*
+ * To do: this entire function should be accessed over a function pointer
+ * such that we can handle stack frames for different ABIs.
+ */
+
+asmlinkage void
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *context)
{
- struct sigcontext *context;
- unsigned long blocked;
long long reg;
int i;
- context = (struct sigcontext *)(long) regs->regs[29];
- if (!access_ok(VERIFY_READ, context, sizeof(struct sigcontext)) ||
- (regs->regs[29] & (SZREG - 1)))
- goto badframe;
-
- __get_user(blocked, &context->sc_sigset);
- current->blocked = blocked & _BLOCKABLE;
__get_user(regs->cp0_epc, &context->sc_pc);
/*
@@ -89,11 +125,66 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
__get_user(reg, &context->sc_mdlo);
regs->lo = (int) reg;
+#define restore_gp_reg(i) __get_user(reg, &context->sc_regs[i]); \
+ regs->regs[i] = (int) reg;
+ restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
+ restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
+ restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
+ restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
+ restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
+ restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
+ restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
+ restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
+ restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
+ restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
+ restore_gp_reg(31);
+#undef restore_gp_reg
+
/*
* FP depends on what FPU in what mode we have. Best done in
* Assembler ...
*/
restore_fp_context(context);
+}
+
+/*
+ * The structure sc describes the stackframe on the userstack. The frames
+ * are identical for normal and realtime signal stackframes with the
+ * exception of the additional struct ucontext for rt frames.
+ */
+struct sigframe {
+ unsigned long ass[4]; /* argument save space for o32 */
+ unsigned int code[4]; /* signal trampoline */
+ struct sigcontext scc;
+};
+
+struct rt_sigframe {
+ unsigned long ass[4];
+ unsigned int code[4];
+ struct sigcontext scc;
+ // struct ucontext uc;
+};
+
+asmlinkage int sys_sigreturn(struct pt_regs *regs)
+{
+ struct sigcontext *context;
+ sigset_t blocked;
+
+ context = (struct sigcontext *)(long) regs->regs[29];
+ if (!access_ok(VERIFY_READ, context, sizeof(struct sigcontext)) ||
+ (regs->regs[29] & (SZREG - 1)))
+ goto badframe;
+
+ if (__copy_from_user(&blocked, &context->sc_sigset, sizeof(blocked)))
+ goto badframe;
+
+ sigdelsetmask(&blocked, ~_BLOCKABLE);
+ spin_lock_irq(&current->sigmask_lock);
+ current->blocked = blocked;
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ restore_sigcontext(regs, context);
/*
* Disable syscall checks
@@ -116,103 +207,95 @@ badframe:
unlock_kernel();
}
+/* same as sys_sigreturn for now */
+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+{
+ return -ENOSYS;
+}
+
+#define scc_offset ((size_t)&((struct sigframe *)0)->scc)
+
/*
- * Set up a signal frame...
- *
- * This routine is somewhat complicated by the fact that if the kernel may be
- * entered by an exception other than a system call; e.g. a bus error or other
- * "bad" exception. If this is the case, then *all* the context on the kernel
- * stack frame must be saved.
- *
- * For a large number of exceptions, the stack frame format is the same
- * as that which will be created when the process traps back to the kernel
- * when finished executing the signal handler. In this case, nothing
- * must be done. This information is saved on the user stack and restored
- * when the signal handler is returned.
- *
- * The signal handler will be called with ra pointing to code1 (see below) and
- * one parameters in a0 (signum).
+ * Set up the return code ...
*
- * usp -> [unused] ; first free word on stack
- * arg save space ; 16/32 bytes arg. save space
- * code1 (addiu sp,#1-offset) ; pop stackframe
- * code2 (li v0,__NR_sigreturn) ; syscall number
- * code3 (syscall) ; do sigreturn(2)
- * #1| $0, at, v0, v1, a0, a1, a2, a3 ; All integer registers
- * | t0, t1, t2, t3, t4, t5, t6, t7 ; $0, k0 and k1 are placeholders
- * | s0, s1, s2, s3, s4, s5, s6, s7
- * | k0, k1, t8, t9, gp, sp, fp, ra;
- * | epc ; old program counter
- * | cause ; CP0 cause register
- * | oldmask
+ * .set noreorder
+ * addiu sp,0x20
+ * li v0,__NR_sigreturn
+ * syscall
+ * .set reorder
*/
+static void inline
+setup_trampoline(unsigned int *code)
+{
+ __put_user(0x27bd0000 + scc_offset , code + 0);
+ __put_user(0x24020000 + __NR_sigreturn, code + 1);
+ __put_user(0x0000000c , code + 2);
-struct sc {
- unsigned long ass[4];
- unsigned int code[4];
- struct sigcontext scc;
-};
-#define scc_offset ((size_t)&((struct sc *)0)->scc)
+ /*
+ * Flush caches so that the instructions will be correctly executed.
+ */
+ flush_cache_sigtramp((unsigned long) code);
+}
+
+static void inline
+setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc, sigset_t *set)
+{
+ __put_user(regs->cp0_epc, &sc->sc_pc);
+ __put_user(regs->cp0_status, &sc->sc_status); /* Status register */
+
+#define save_gp_reg(i) __put_user(regs->regs[(i)], &sc->sc_regs[(i)])
+ __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
+ save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
+ save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
+ save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
+ save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
+ save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
+ save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
+ save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
+ save_gp_reg(31);
+#undef save_gp_reg
+
+ save_fp_context(sc); /* cpu dependand */
+ __put_user(regs->hi, &sc->sc_mdhi);
+ __put_user(regs->lo, &sc->sc_mdlo);
+ __put_user(regs->cp0_cause, &sc->sc_cause);
+ __put_user((regs->cp0_status & ST0_CU1) != 0, &sc->sc_ownedfp);
+
+ __copy_to_user(sc->sc_sigset, set, sizeof(*set));
+}
-static void setup_frame(struct sigaction * sa, struct pt_regs *regs,
- int signr, unsigned long oldmask)
+static void inline
+setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *oldmask)
{
- struct sc *frame;
+ struct sigframe *frame;
struct sigcontext *sc;
- int i;
/* Align the stackframe to an adequate boundary for the architecture. */
- frame = (struct sc *) (long) regs->regs[29];
+ frame = (struct sigframe *) (long) regs->regs[29];
frame--;
- frame = (struct sc *)((unsigned long)frame & ALMASK);
+ frame = (struct sigframe *)((unsigned long)frame & ALMASK);
if (verify_area(VERIFY_WRITE, frame, sizeof (*frame)))
goto segv_and_exit;
sc = &frame->scc;
- /*
- * Set up the return code ...
- *
- * .set noreorder
- * addiu sp,0x20
- * li v0,__NR_sigreturn
- * syscall
- * .set reorder
- */
- __put_user(0x27bd0000 + scc_offset, &frame->code[0]);
- __put_user(0x24020000 + __NR_sigreturn, &frame->code[1]);
- __put_user(0x0000000c, &frame->code[2]);
+ setup_trampoline(frame->code);
+ setup_sigcontext(regs, &frame->scc, oldmask);
- /*
- * Flush caches so that the instructions will be correctly executed.
- */
- flush_cache_sigtramp((unsigned long) frame->code);
+ regs->regs[4] = signr; /* arguments */
+ regs->regs[5] = 0; /* should be cause */
+ regs->regs[6] = (long) frame; /* ptr to sigcontext */
+ regs->regs[29] = (unsigned long) frame; /* Stack pointer */
+ regs->regs[31] = (unsigned long) frame->code; /* Return address */
+ regs->cp0_epc = (unsigned long) ka->sa.sa_handler; /* handler address */
+ regs->regs[25] = regs->cp0_epc; /* PIC shit... */
- /*
- * Set up the "normal" sigcontext
- */
- __put_user(regs->cp0_epc, &sc->sc_pc);
- __put_user(regs->cp0_status, &sc->sc_status); /* Status register */
- for(i = 31;i >= 0;i--)
- __put_user(regs->regs[i], &sc->sc_regs[i]);
- save_fp_context(sc);
- __put_user(regs->hi, &sc->sc_mdhi);
- __put_user(regs->lo, &sc->sc_mdlo);
- __put_user(regs->cp0_cause, &sc->sc_cause);
- __put_user((regs->cp0_status & ST0_CU1) != 0, &sc->sc_ownedfp);
- __put_user(oldmask, &sc->sc_sigset);
- __put_user(0, &sc->__pad0[0]);
- __put_user(0, &sc->__pad0[1]);
- __put_user(0, &sc->__pad0[2]);
-
- regs->regs[4] = signr; /* Arguments for handler */
- regs->regs[5] = 0; /* For now. */
- regs->regs[6] = (long) frame; /* Pointer to sigcontext */
- regs->regs[29] = (unsigned long) frame; /* Stack pointer */
- regs->regs[31] = (unsigned long) frame->code; /* Return address */
- regs->cp0_epc = (unsigned long) sa->sa_handler; /* "return" to the first handler */
- regs->regs[25] = regs->cp0_epc; /* PIC shit... */
- return;
+#if DEBUG_SIG
+ printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
+ current->comm, current->pid, frame, regs->cp0_epc, frame->code);
+#endif
+ return;
segv_and_exit:
lock_kernel();
@@ -220,16 +303,30 @@ segv_and_exit:
unlock_kernel();
}
-static inline void handle_signal(unsigned long signr, struct sigaction *sa,
- unsigned long oldmask, struct pt_regs * regs)
+static void inline
+setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
+ int signr, sigset_t *oldmask, siginfo_t *info)
{
- setup_frame(sa, regs, signr, oldmask);
+ printk("Aiee: setup_tr_frame wants to be written");
+}
- if (sa->sa_flags & SA_ONESHOT)
- sa->sa_handler = NULL;
- if (!(sa->sa_flags & SA_NOMASK)) {
+/* ------------------------------------------------------------------------- */
+
+static inline void handle_signal(unsigned long sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
+{
+ if (ka->sa.sa_flags & SA_SIGINFO)
+ setup_rt_frame(ka, regs, sig, oldset, info);
+ else
+ setup_frame(ka, regs, sig, oldset);
+
+ if (ka->sa.sa_flags & SA_ONESHOT)
+ ka->sa.sa_handler = SIG_DFL;
+ if (!(ka->sa.sa_flags & SA_NODEFER)) {
spin_lock_irq(&current->sigmask_lock);
- current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE;
+ sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+ sigaddset(&current->blocked,sig);
+ recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
}
}
@@ -254,62 +351,82 @@ static inline void syscall_restart(unsigned long r0, unsigned long or2,
}
}
-extern int do_irix_signal(unsigned long oldmask, struct pt_regs *regs);
+extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
-/*
- * Note that 'init' is a special process: it doesn't get signals it doesn't
- * want to handle. Thus you cannot kill init even with a SIGKILL even by
- * mistake.
- *
- * Note that we go through the signals twice: once to check the signals that
- * the kernel can handle, and then we build all the user-level signal handling
- * stack-frames in one go after that.
- */
-asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
{
- unsigned long mask = ~current->blocked;
- unsigned long signr, r0 = regs->regs[0];
+ unsigned long r0 = regs->regs[0];
unsigned long r7 = regs->orig_reg7;
- struct sigaction * sa;
+ struct k_sigaction *ka;
+ siginfo_t info;
#ifdef CONFIG_BINFMT_IRIX
- if(current->personality != PER_LINUX)
- return do_irix_signal(oldmask, regs);
+ if (current->personality != PER_LINUX) /* XXX */
+ return do_irix_signal(oldset, regs);
#endif
- while ((signr = current->signal & mask)) {
- signr = ffz(~signr);
- clear_bit(signr, &current->signal);
- sa = current->sig->action + signr;
- signr++;
+
+ if (!oldset)
+ oldset = &current->blocked;
+
+ for (;;) {
+ unsigned long signr;
+
+ spin_lock_irq(&current->sigmask_lock);
+ signr = dequeue_signal(&current->blocked, &info);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ if (!signr)
+ break;
+
if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+ /* Let the debugger run. */
current->exit_code = signr;
current->state = TASK_STOPPED;
notify_parent(current, SIGCHLD);
schedule();
+
+ /* We're back. Did the debugger cancel the sig? */
if (!(signr = current->exit_code))
continue;
current->exit_code = 0;
+
+ /* The debugger continued. Ignore SIGSTOP. */
if (signr == SIGSTOP)
continue;
- if (_S(signr) & current->blocked) {
- spin_lock_irq(&current->sigmask_lock);
- current->signal |= _S(signr);
- spin_unlock_irq(&current->sigmask_lock);
+
+ /* Update the siginfo structure. Is this good? */
+ if (signr != info.si_signo) {
+ info.si_signo = signr;
+ info.si_errno = 0;
+ info.si_code = SI_USER;
+ info.si_pid = current->p_pptr->pid;
+ info.si_uid = current->p_pptr->uid;
+ }
+
+ /* If the (new) signal is now blocked, requeue it. */
+ if (sigismember(&current->blocked, signr)) {
+ send_sig_info(signr, &info, current);
continue;
}
- sa = current->sig->action + signr - 1;
}
- if (sa->sa_handler == SIG_IGN) {
+
+ ka = &current->sig->action[signr-1];
+ if (ka->sa.sa_handler == SIG_IGN) {
if (signr != SIGCHLD)
continue;
- /* check for SIGCHLD: it's special */
- while (sys_wait4(-1,NULL,WNOHANG, NULL) > 0)
+ /* Check for SIGCHLD: it's special. */
+ while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
/* nothing */;
continue;
}
- if (sa->sa_handler == SIG_DFL) {
+
+ if (ka->sa.sa_handler == SIG_DFL) {
+ int exit_code = signr;
+
+ /* Init gets no signals it doesn't want. */
if (current->pid == 1)
continue;
+
switch (signr) {
case SIGCONT: case SIGCHLD: case SIGWINCH:
continue;
@@ -317,48 +434,42 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
case SIGTSTP: case SIGTTIN: case SIGTTOU:
if (is_orphaned_pgrp(current->pgrp))
continue;
+ /* FALLTHRU */
+
case SIGSTOP:
- if (current->flags & PF_PTRACED)
- continue;
current->state = TASK_STOPPED;
current->exit_code = signr;
- if (!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags &
- SA_NOCLDSTOP))
+ if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
notify_parent(current, SIGCHLD);
schedule();
continue;
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- case SIGBUS:
lock_kernel();
- if (current->binfmt && current->binfmt->core_dump) {
- if (current->binfmt->core_dump(signr, regs))
- signr |= 0x80;
- }
+ if (current->binfmt
+ && current->binfmt->core_dump
+ && current->binfmt->core_dump(signr, regs))
+ exit_code |= 0x80;
unlock_kernel();
- /* fall through */
- default:
- spin_lock_irq(&current->sigmask_lock);
- current->signal |= _S(signr & 0x7f);
- spin_unlock_irq(&current->sigmask_lock);
+ /* FALLTHRU */
+ default:
+ lock_kernel();
+ sigaddset(&current->signal, signr);
current->flags |= PF_SIGNALED;
-
- lock_kernel(); /* 8-( */
- do_exit(signr);
- unlock_kernel();
+ do_exit(exit_code);
+ /* NOTREACHED */
}
}
- /*
- * OK, we're invoking a handler
- */
- if(r0)
- syscall_restart(r0, regs->orig_reg2,
- r7, regs, sa);
- handle_signal(signr, sa, oldmask, regs);
+
+ if (r0)
+ syscall_restart(r0, regs->orig_reg2, r7, regs, &ka->sa);
+ /* Whee! Actually deliver the signal. */
+ handle_signal(signr, ka, &info, oldset, regs);
return 1;
}
+
/*
* Who's code doesn't conform to the restartable syscall convention
* dies here!!! The li instruction, a single machine instruction,
@@ -376,16 +487,6 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
}
/*
- * The signal(2) syscall is no longer available in the kernel
- * because GNU libc doesn't use it. Maybe I'll add it back to the
- * kernel for the binary compatibility stuff.
- */
-asmlinkage unsigned long sys_signal(int signum, __sighandler_t handler)
-{
- return -ENOSYS;
-}
-
-/*
* Compatibility syscall. Can be replaced in libc.
*/
asmlinkage int sys_pause(void)
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index ffcf176e4..91cc6a3ae 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -11,7 +11,7 @@
* Don't waste that much memory for empty entries in the syscall
* table.
*
- * $Id: syscall.c,v 1.4 1997/09/18 07:57:30 root Exp $
+ * $Id: syscall.c,v 1.4 1997/12/01 17:57:31 ralf Exp $
*/
#undef CONF_PRINT_SYSCALLS
#undef CONF_DEBUG_IRIX
@@ -365,7 +365,7 @@ void do_sys(struct pt_regs *regs)
if ((current->flags & PF_TRACESYS) == 0)
{
errno = do_syscalls(regs, syscall, narg);
- if ((errno < 0 && errno > (-ENOIOCTLCMD - 1)) || current->errno) {
+ if (errno < 0 && errno > (-ENOIOCTLCMD - 1)) {
goto bad_syscall;
}
regs->regs[2] = errno;
@@ -376,7 +376,7 @@ void do_sys(struct pt_regs *regs)
syscall_trace();
errno = do_syscalls(regs, syscall, narg);
- if (errno < 0 || current->errno)
+ if (errno < 0)
{
regs->regs[2] = -errno;
regs->regs[7] = 1;
diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h
index 6b0e2d3c6..f0614b69f 100644
--- a/arch/mips/kernel/syscalls.h
+++ b/arch/mips/kernel/syscalls.h
@@ -7,7 +7,7 @@
*
* Copyright (C) 1995, 1996 by Ralf Baechle
*
- * $Id: syscalls.h,v 1.8 1997/12/01 17:57:32 ralf Exp $
+ * $Id: syscalls.h,v 1.9 1997/12/06 23:52:06 ralf Exp $
*/
/*
@@ -66,7 +66,7 @@ SYS(sys_ni_syscall, 0)
SYS(sys_brk, 1) /* 4045 */
SYS(sys_setgid, 1)
SYS(sys_getgid, 0)
-SYS(sys_signal, 2)
+SYS(sys_ni_syscall, 0) /* was signal(2) */
SYS(sys_geteuid, 0)
SYS(sys_getegid, 0) /* 4050 */
SYS(sys_acct, 0)
@@ -211,3 +211,12 @@ SYS(sys_nfsservctl, 3)
SYS(sys_setresgid, 3) /* 4190 */
SYS(sys_getresgid, 3)
SYS(sys_prctl, 5)
+SYS(sys_rt_sigreturn, 0)
+SYS(sys_rt_sigaction, 4)
+SYS(sys_rt_sigprocmask, 4) /* 4195 */
+SYS(sys_rt_sigpending, 2)
+SYS(sys_rt_sigtimedwait, 4)
+SYS(sys_rt_sigqueueinfo, 3)
+SYS(sys_rt_sigsuspend, 2)
+SYS(sys_pread, 4) /* 4200 */
+SYS(sys_pwrite, 4)
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 711a52791..64941c67c 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -1,8 +1,10 @@
-/* $Id: sysirix.c,v 1.7 1997/09/13 23:49:30 shaver Exp $
+/*
* sysirix.c: IRIX system call emulation.
*
* Copyright (C) 1996 David S. Miller
* Copyright (C) 1997 Miguel de Icaza
+ *
+ * $Id: sysirix.c,v 1.8 1997/09/21 22:58:44 miguel Exp $
*/
#include <linux/kernel.h>
@@ -56,7 +58,7 @@ asmlinkage int irix_sysmp(struct pt_regs *regs)
error = NR_CPUS;
break;
default:
- printk("SYSMP[%s:%d]: Unsupported opcode %d\n",
+ printk("SYSMP[%s:%ld]: Unsupported opcode %d\n",
current->comm, current->pid, (int)cmd);
error = -EINVAL;
break;
@@ -95,7 +97,7 @@ asmlinkage int irix_prctl(struct pt_regs *regs)
cmd = regs->regs[base + 4];
switch(cmd) {
case PR_MAXPROCS:
- printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_MAXPROCS\n",
current->comm, current->pid);
error = NR_TASKS;
break;
@@ -103,7 +105,7 @@ asmlinkage int irix_prctl(struct pt_regs *regs)
case PR_ISBLOCKED: {
struct task_struct *task;
- printk("irix_prctl[%s:%d]: Wants PR_ISBLOCKED\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_ISBLOCKED\n",
current->comm, current->pid);
task = find_task_by_pid(regs->regs[base + 5]);
if(!task) {
@@ -118,7 +120,7 @@ asmlinkage int irix_prctl(struct pt_regs *regs)
case PR_SETSTACKSIZE: {
long value = regs->regs[base + 5];
- printk("irix_prctl[%s:%d]: Wants PR_SETSTACKSIZE<%08lx>\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_SETSTACKSIZE<%08lx>\n",
current->comm, current->pid, (unsigned long) value);
if(value > RLIM_INFINITY)
value = RLIM_INFINITY;
@@ -138,25 +140,25 @@ asmlinkage int irix_prctl(struct pt_regs *regs)
}
case PR_GETSTACKSIZE:
- printk("irix_prctl[%s:%d]: Wants PR_GETSTACKSIZE\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_GETSTACKSIZE\n",
current->comm, current->pid);
error = current->rlim[RLIMIT_STACK].rlim_cur;
break;
case PR_MAXPPROCS:
- printk("irix_prctl[%s:%d]: Wants PR_MAXPROCS\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_MAXPROCS\n",
current->comm, current->pid);
error = 1;
break;
case PR_UNBLKONEXEC:
- printk("irix_prctl[%s:%d]: Wants PR_UNBLKONEXEC\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_UNBLKONEXEC\n",
current->comm, current->pid);
error = -EINVAL;
break;
case PR_SETEXITSIG:
- printk("irix_prctl[%s:%d]: Wants PR_SETEXITSIG\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_SETEXITSIG\n",
current->comm, current->pid);
/* We can probably play some game where we set the task
@@ -167,31 +169,31 @@ asmlinkage int irix_prctl(struct pt_regs *regs)
break;
case PR_RESIDENT:
- printk("irix_prctl[%s:%d]: Wants PR_RESIDENT\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_RESIDENT\n",
current->comm, current->pid);
error = 0; /* Compatability indeed. */
break;
case PR_ATTACHADDR:
- printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDR\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_ATTACHADDR\n",
current->comm, current->pid);
error = -EINVAL;
break;
case PR_DETACHADDR:
- printk("irix_prctl[%s:%d]: Wants PR_DETACHADDR\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_DETACHADDR\n",
current->comm, current->pid);
error = -EINVAL;
break;
case PR_TERMCHILD:
- printk("irix_prctl[%s:%d]: Wants PR_TERMCHILD\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_TERMCHILD\n",
current->comm, current->pid);
error = -EINVAL;
break;
case PR_GETSHMASK:
- printk("irix_prctl[%s:%d]: Wants PR_GETSHMASK\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_GETSHMASK\n",
current->comm, current->pid);
error = -EINVAL; /* Until I have the sproc() stuff in. */
break;
@@ -201,24 +203,24 @@ asmlinkage int irix_prctl(struct pt_regs *regs)
break;
case PR_COREPID:
- printk("irix_prctl[%s:%d]: Wants PR_COREPID\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_COREPID\n",
current->comm, current->pid);
error = -EINVAL;
break;
case PR_ATTACHADDRPERM:
- printk("irix_prctl[%s:%d]: Wants PR_ATTACHADDRPERM\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_ATTACHADDRPERM\n",
current->comm, current->pid);
error = -EINVAL;
break;
case PR_PTHREADEXIT:
- printk("irix_prctl[%s:%d]: Wants PR_PTHREADEXIT\n",
+ printk("irix_prctl[%s:%ld]: Wants PR_PTHREADEXIT\n",
current->comm, current->pid);
do_exit(regs->regs[base + 5]);
default:
- printk("irix_prctl[%s:%d]: Non-existant opcode %d\n",
+ printk("irix_prctl[%s:%ld]: Non-existant opcode %d\n",
current->comm, current->pid, (int)cmd);
error = -EINVAL;
break;
@@ -339,7 +341,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
case SGI_SETPGID: {
#ifdef DEBUG_PROCGRPS
- printk("[%s:%d] setpgid(%d, %d) ",
+ printk("[%s:%ld] setpgid(%d, %d) ",
current->comm, current->pid,
(int) regs->regs[base + 5], (int)regs->regs[base + 6]);
#endif
@@ -436,7 +438,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs)
case SGI_GETSID:
#ifdef DEBUG_PROCGRPS
- printk("[%s:%d] getsid(%d) ", current->comm, current->pid,
+ printk("[%s:%ld] getsid(%d) ", current->comm, current->pid,
(int) regs->regs[base + 5]);
#endif
retval = sys_getsid(regs->regs[base + 5]);
@@ -636,7 +638,8 @@ out:
return ret;
}
-extern int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue);
+extern int do_setitimer(int which, struct itimerval *value,
+ struct itimerval *ovalue);
static inline void jiffiestotv(unsigned long jiffies, struct timeval *value)
{
@@ -677,7 +680,7 @@ asmlinkage unsigned int irix_alarm(unsigned int seconds)
it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
it_new.it_value.tv_sec = seconds;
it_new.it_value.tv_usec = 0;
- _setitimer(ITIMER_REAL, &it_new, &it_old);
+ do_setitimer(ITIMER_REAL, &it_new, &it_old);
}
oldalarm = it_old.it_value.tv_sec;
/* ehhh.. We can't return 0 if we have an alarm pending.. */
@@ -707,7 +710,7 @@ asmlinkage int irix_mount(char *dev_name, char *dir_name, unsigned long flags,
int ret;
lock_kernel();
- printk("[%s:%d] irix_mount(%p,%p,%08lx,%p,%p,%d)\n",
+ printk("[%s:%ld] irix_mount(%p,%p,%08lx,%p,%p,%d)\n",
current->comm, current->pid,
dev_name, dir_name, flags, type, data, datalen);
ret = sys_mount(dev_name, dir_name, type, flags, data);
@@ -727,8 +730,9 @@ asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
{
struct dentry *dentry;
struct inode *inode;
+ mm_segment_t old_fs;
struct statfs kbuf;
- int error, old_fs, i;
+ int error, i;
/* We don't support this feature yet. */
if(fs_type) {
@@ -776,8 +780,9 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
struct dentry *dentry;
struct inode *inode;
struct statfs kbuf;
+ mm_segment_t old_fs;
struct file *file;
- int error, old_fs, i;
+ int error, i;
lock_kernel();
error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
@@ -839,7 +844,7 @@ asmlinkage int irix_setpgrp(int flags)
lock_kernel();
#ifdef DEBUG_PROCGRPS
- printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);
+ printk("[%s:%ld] setpgrp(%d) ", current->comm, current->pid, flags);
#endif
if(!flags)
error = current->pgrp;
@@ -919,7 +924,7 @@ out:
asmlinkage unsigned long irix_gethostid(void)
{
lock_kernel();
- printk("[%s:%d]: irix_gethostid() called...\n",
+ printk("[%s:%ld]: irix_gethostid() called...\n",
current->comm, current->pid);
unlock_kernel();
return -EINVAL;
@@ -928,7 +933,7 @@ asmlinkage unsigned long irix_gethostid(void)
asmlinkage unsigned long irix_sethostid(unsigned long val)
{
lock_kernel();
- printk("[%s:%d]: irix_sethostid(%08lx) called...\n",
+ printk("[%s:%ld]: irix_sethostid(%08lx) called...\n",
current->comm, current->pid, val);
unlock_kernel();
return -EINVAL;
@@ -1057,8 +1062,9 @@ extern asmlinkage int sys_llseek(unsigned int fd, unsigned long offset_high,
asmlinkage int irix_lseek64(int fd, int _unused, int offhi, int offlow, int base)
{
+ mm_segment_t old_fs;
loff_t junk;
- int old_fs, error;
+ int error;
lock_kernel();
old_fs = get_fs(); set_fs(get_ds());
@@ -1139,7 +1145,7 @@ out:
asmlinkage int irix_madvise(unsigned long addr, int len, int behavior)
{
lock_kernel();
- printk("[%s:%d] Wheee.. irix_madvise(%08lx,%d,%d)\n",
+ printk("[%s:%ld] Wheee.. irix_madvise(%08lx,%d,%d)\n",
current->comm, current->pid, addr, len, behavior);
unlock_kernel();
return -EINVAL;
@@ -1148,7 +1154,7 @@ asmlinkage int irix_madvise(unsigned long addr, int len, int behavior)
asmlinkage int irix_pagelock(char *addr, int len, int op)
{
lock_kernel();
- printk("[%s:%d] Wheee.. irix_pagelock(%p,%d,%d)\n",
+ printk("[%s:%ld] Wheee.. irix_pagelock(%p,%d,%d)\n",
current->comm, current->pid, addr, len, op);
unlock_kernel();
return -EINVAL;
@@ -1157,7 +1163,7 @@ asmlinkage int irix_pagelock(char *addr, int len, int op)
asmlinkage int irix_quotactl(struct pt_regs *regs)
{
lock_kernel();
- printk("[%s:%d] Wheee.. irix_quotactl()\n",
+ printk("[%s:%ld] Wheee.. irix_quotactl()\n",
current->comm, current->pid);
unlock_kernel();
return -EINVAL;
@@ -1169,7 +1175,7 @@ asmlinkage int irix_BSDsetpgrp(int pid, int pgrp)
lock_kernel();
#ifdef DEBUG_PROCGRPS
- printk("[%s:%d] BSDsetpgrp(%d, %d) ", current->comm, current->pid,
+ printk("[%s:%ld] BSDsetpgrp(%d, %d) ", current->comm, current->pid,
pid, pgrp);
#endif
if(!pid)
@@ -1192,7 +1198,7 @@ asmlinkage int irix_BSDsetpgrp(int pid, int pgrp)
asmlinkage int irix_systeminfo(int cmd, char *buf, int cnt)
{
lock_kernel();
- printk("[%s:%d] Wheee.. irix_systeminfo(%d,%p,%d)\n",
+ printk("[%s:%ld] Wheee.. irix_systeminfo(%d,%p,%d)\n",
current->comm, current->pid, cmd, buf, cnt);
unlock_kernel();
return -EINVAL;
@@ -1320,13 +1326,13 @@ asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
lock_kernel();
#ifdef DEBUG_XSTAT
- printk("[%s:%d] Wheee.. irix_xstat(%d,%s,%p) ",
+ printk("[%s:%ld] Wheee.. irix_xstat(%d,%s,%p) ",
current->comm, current->pid, version, filename, statbuf);
#endif
switch(version) {
case 2: {
struct stat kb;
- int old_fs;
+ mm_segment_t old_fs;
old_fs = get_fs(); set_fs(get_ds());
retval = sys_newstat(filename, &kb);
@@ -1371,13 +1377,13 @@ asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
lock_kernel();
#ifdef DEBUG_XSTAT
- printk("[%s:%d] Wheee.. irix_lxstat(%d,%s,%p) ",
+ printk("[%s:%ld] Wheee.. irix_lxstat(%d,%s,%p) ",
current->comm, current->pid, version, filename, statbuf);
#endif
switch(version) {
case 2: {
struct stat kb;
- int old_fs;
+ mm_segment_t old_fs;
old_fs = get_fs(); set_fs(get_ds());
error = sys_newlstat(filename, &kb);
@@ -1422,13 +1428,13 @@ asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
lock_kernel();
#ifdef DEBUG_XSTAT
- printk("[%s:%d] Wheee.. irix_fxstat(%d,%d,%p) ",
+ printk("[%s:%ld] Wheee.. irix_fxstat(%d,%d,%p) ",
current->comm, current->pid, version, fd, statbuf);
#endif
switch(version) {
case 2: {
struct stat kb;
- int old_fs;
+ mm_segment_t old_fs;
old_fs = get_fs(); set_fs(get_ds());
error = sys_newfstat(fd, &kb);
@@ -1472,7 +1478,7 @@ asmlinkage int irix_xmknod(int ver, char *filename, int mode, dev_t dev)
int retval;
lock_kernel();
- printk("[%s:%d] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",
+ printk("[%s:%ld] Wheee.. irix_xmknod(%d,%s,%x,%x)\n",
current->comm, current->pid, ver, filename, mode, (int) dev);
switch(ver) {
case 2:
@@ -1492,7 +1498,7 @@ out:
asmlinkage int irix_swapctl(int cmd, char *arg)
{
lock_kernel();
- printk("[%s:%d] Wheee.. irix_swapctl(%d,%p)\n",
+ printk("[%s:%ld] Wheee.. irix_swapctl(%d,%p)\n",
current->comm, current->pid, cmd, arg);
unlock_kernel();
return -EINVAL;
@@ -1510,11 +1516,12 @@ asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf)
{
struct dentry *dentry;
struct inode *inode;
+ mm_segment_t old_fs;
struct statfs kbuf;
- int error, old_fs, i;
+ int error, i;
lock_kernel();
- printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
+ printk("[%s:%ld] Wheee.. irix_statvfs(%s,%p)\n",
current->comm, current->pid, fname, buf);
error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
if(error)
@@ -1569,12 +1576,13 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
{
struct dentry *dentry;
struct inode *inode;
+ mm_segment_t old_fs;
struct statfs kbuf;
struct file *file;
- int error, old_fs, i;
+ int error, i;
lock_kernel();
- printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
+ printk("[%s:%ld] Wheee.. irix_fstatvfs(%d,%p)\n",
current->comm, current->pid, fd, buf);
error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
@@ -1725,7 +1733,7 @@ asmlinkage int irix_lchown(const char *filename, int uid, int gid)
asmlinkage int irix_priocntl(struct pt_regs *regs)
{
lock_kernel();
- printk("[%s:%d] Wheee.. irix_priocntl()\n",
+ printk("[%s:%ld] Wheee.. irix_priocntl()\n",
current->comm, current->pid);
unlock_kernel();
return -EINVAL;
@@ -1734,7 +1742,7 @@ asmlinkage int irix_priocntl(struct pt_regs *regs)
asmlinkage int irix_sigqueue(int pid, int sig, int code, int val)
{
lock_kernel();
- printk("[%s:%d] Wheee.. irix_sigqueue(%d,%d,%d,%d)\n",
+ printk("[%s:%ld] Wheee.. irix_sigqueue(%d,%d,%d,%d)\n",
current->comm, current->pid, pid, sig, code, val);
unlock_kernel();
return -EINVAL;
@@ -1842,7 +1850,7 @@ out:
asmlinkage int irix_dmi(struct pt_regs *regs)
{
lock_kernel();
- printk("[%s:%d] Wheee.. irix_dmi()\n",
+ printk("[%s:%ld] Wheee.. irix_dmi()\n",
current->comm, current->pid);
unlock_kernel();
return -EINVAL;
@@ -1852,7 +1860,7 @@ asmlinkage int irix_pread(int fd, char *buf, int cnt, int off64,
int off1, int off2)
{
lock_kernel();
- printk("[%s:%d] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n",
+ printk("[%s:%ld] Wheee.. irix_pread(%d,%p,%d,%d,%d,%d)\n",
current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
unlock_kernel();
return -EINVAL;
@@ -1862,7 +1870,7 @@ asmlinkage int irix_pwrite(int fd, char *buf, int cnt, int off64,
int off1, int off2)
{
lock_kernel();
- printk("[%s:%d] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n",
+ printk("[%s:%ld] Wheee.. irix_pwrite(%d,%p,%d,%d,%d,%d)\n",
current->comm, current->pid, fd, buf, cnt, off64, off1, off2);
unlock_kernel();
return -EINVAL;
@@ -1873,7 +1881,7 @@ asmlinkage int irix_sgifastpath(int cmd, unsigned long arg0, unsigned long arg1,
unsigned long arg4, unsigned long arg5)
{
lock_kernel();
- printk("[%s:%d] Wheee.. irix_fastpath(%d,%08lx,%08lx,%08lx,%08lx,"
+ printk("[%s:%ld] Wheee.. irix_fastpath(%d,%08lx,%08lx,%08lx,%08lx,"
"%08lx,%08lx)\n",
current->comm, current->pid, cmd, arg0, arg1, arg2,
arg3, arg4, arg5);
@@ -1896,10 +1904,11 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
{
struct dentry *dentry;
struct inode *inode;
+ mm_segment_t old_fs;
struct statfs kbuf;
- int error, old_fs, i;
+ int error, i;
- printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
+ printk("[%s:%ld] Wheee.. irix_statvfs(%s,%p)\n",
current->comm, current->pid, fname, buf);
error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
if(error)
@@ -1953,12 +1962,13 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
{
struct dentry *dentry;
struct inode *inode;
+ mm_segment_t old_fs;
struct statfs kbuf;
struct file *file;
- int error, old_fs, i;
+ int error, i;
lock_kernel();
- printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
+ printk("[%s:%ld] Wheee.. irix_fstatvfs(%d,%p)\n",
current->comm, current->pid, fd, buf);
error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
@@ -2021,7 +2031,7 @@ asmlinkage int irix_getmountid(char *fname, unsigned long *midbuf)
int error;
lock_kernel();
- printk("[%s:%d] irix_getmountid(%s, %p)\n",
+ printk("[%s:%ld] irix_getmountid(%s, %p)\n",
current->comm, current->pid, fname, midbuf);
error = verify_area(VERIFY_WRITE, midbuf, (sizeof(unsigned long) * 4));
if(error)
@@ -2048,7 +2058,7 @@ asmlinkage int irix_nsproc(unsigned long entry, unsigned long mask,
unsigned long arg, unsigned long sp, int slen)
{
lock_kernel();
- printk("[%s:%d] Wheee.. irix_nsproc(%08lx,%08lx,%08lx,%08lx,%d)\n",
+ printk("[%s:%ld] Wheee.. irix_nsproc(%08lx,%08lx,%08lx,%08lx,%d)\n",
current->comm, current->pid, entry, mask, arg, sp, slen);
unlock_kernel();
return -EINVAL;
@@ -2121,7 +2131,7 @@ asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count
lock_kernel();
#ifdef DEBUG_GETDENTS
- printk("[%s:%d] ngetdents(%d, %p, %d, %p) ", current->comm,
+ printk("[%s:%ld] ngetdents(%d, %p, %d, %p) ", current->comm,
current->pid, fd, dirent, count, eob);
#endif
error = -EBADF;
@@ -2353,41 +2363,41 @@ asmlinkage int irix_uadmin(unsigned long op, unsigned long func, unsigned long a
switch(op) {
case 1:
/* Reboot */
- printk("[%s:%d] irix_uadmin: Wants to reboot...\n",
+ printk("[%s:%ld] irix_uadmin: Wants to reboot...\n",
current->comm, current->pid);
retval = -EINVAL;
goto out;
case 2:
/* Shutdown */
- printk("[%s:%d] irix_uadmin: Wants to shutdown...\n",
+ printk("[%s:%ld] irix_uadmin: Wants to shutdown...\n",
current->comm, current->pid);
retval = -EINVAL;
goto out;
case 4:
/* Remount-root */
- printk("[%s:%d] irix_uadmin: Wants to remount root...\n",
+ printk("[%s:%ld] irix_uadmin: Wants to remount root...\n",
current->comm, current->pid);
retval = -EINVAL;
goto out;
case 8:
/* Kill all tasks. */
- printk("[%s:%d] irix_uadmin: Wants to kill all tasks...\n",
+ printk("[%s:%ld] irix_uadmin: Wants to kill all tasks...\n",
current->comm, current->pid);
retval = -EINVAL;
goto out;
case 256:
/* Set magic mushrooms... */
- printk("[%s:%d] irix_uadmin: Wants to set magic mushroom[%d]...\n",
+ printk("[%s:%ld] irix_uadmin: Wants to set magic mushroom[%d]...\n",
current->comm, current->pid, (int) func);
retval = -EINVAL;
goto out;
default:
- printk("[%s:%d] irix_uadmin: Unknown operation [%d]...\n",
+ printk("[%s:%ld] irix_uadmin: Unknown operation [%d]...\n",
current->comm, current->pid, (int) op);
retval = -EINVAL;
goto out;
@@ -2411,20 +2421,20 @@ asmlinkage int irix_utssys(char *inbuf, int arg, int type, char *outbuf)
case 2:
/* ustat() */
- printk("[%s:%d] irix_utssys: Wants to do ustat()\n",
+ printk("[%s:%ld] irix_utssys: Wants to do ustat()\n",
current->comm, current->pid);
retval = -EINVAL;
goto out;
case 3:
/* fusers() */
- printk("[%s:%d] irix_utssys: Wants to do fusers()\n",
+ printk("[%s:%ld] irix_utssys: Wants to do fusers()\n",
current->comm, current->pid);
retval = -EINVAL;
goto out;
default:
- printk("[%s:%d] irix_utssys: Wants to do unknown type[%d]\n",
+ printk("[%s:%ld] irix_utssys: Wants to do unknown type[%d]\n",
current->comm, current->pid, (int) type);
retval = -EINVAL;
goto out;
@@ -2448,7 +2458,7 @@ asmlinkage int irix_fcntl(int fd, int cmd, int arg)
lock_kernel();
#ifdef DEBUG_FCNTL
- printk("[%s:%d] irix_fcntl(%d, %d, %d) ", current->comm,
+ printk("[%s:%ld] irix_fcntl(%d, %d, %d) ", current->comm,
current->pid, fd, cmd, arg);
#endif
if (cmd == IRIX_F_ALLOCSP){
@@ -2469,26 +2479,26 @@ asmlinkage int irix_ulimit(int cmd, int arg)
lock_kernel();
switch(cmd) {
case 1:
- printk("[%s:%d] irix_ulimit: Wants to get file size limit.\n",
+ printk("[%s:%ld] irix_ulimit: Wants to get file size limit.\n",
current->comm, current->pid);
retval = -EINVAL;
goto out;
case 2:
- printk("[%s:%d] irix_ulimit: Wants to set file size limit.\n",
+ printk("[%s:%ld] irix_ulimit: Wants to set file size limit.\n",
current->comm, current->pid);
retval = -EINVAL;
goto out;
case 3:
- printk("[%s:%d] irix_ulimit: Wants to get brk limit.\n",
+ printk("[%s:%ld] irix_ulimit: Wants to get brk limit.\n",
current->comm, current->pid);
retval = -EINVAL;
goto out;
case 4:
#if 0
- printk("[%s:%d] irix_ulimit: Wants to get fd limit.\n",
+ printk("[%s:%ld] irix_ulimit: Wants to get fd limit.\n",
current->comm, current->pid);
retval = -EINVAL;
goto out;
@@ -2497,13 +2507,13 @@ asmlinkage int irix_ulimit(int cmd, int arg)
goto out;
case 5:
- printk("[%s:%d] irix_ulimit: Wants to get txt offset.\n",
+ printk("[%s:%ld] irix_ulimit: Wants to get txt offset.\n",
current->comm, current->pid);
retval = -EINVAL;
goto out;
default:
- printk("[%s:%d] irix_ulimit: Unknown command [%d].\n",
+ printk("[%s:%ld] irix_ulimit: Unknown command [%d].\n",
current->comm, current->pid, cmd);
retval = -EINVAL;
goto out;
@@ -2516,7 +2526,7 @@ out:
asmlinkage int irix_unimp(struct pt_regs *regs)
{
lock_kernel();
- printk("irix_unimp [%s:%d] v0=%d v1=%d a0=%08lx a1=%08lx a2=%08lx "
+ printk("irix_unimp [%s:%ld] v0=%d v1=%d a0=%08lx a1=%08lx a2=%08lx "
"a3=%08lx\n", current->comm, current->pid,
(int) regs->regs[2], (int) regs->regs[3],
regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index fc0dd091c..b80dc6dc8 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -8,7 +8,7 @@
* Copyright 1994, 1995, 1996, 1997 by Ralf Baechle
* Modified for R3000 by Paul M. Antoine, 1995, 1996
*
- * $Id: traps.c,v 1.7 1997/12/01 16:33:28 ralf Exp $
+ * $Id: traps.c,v 1.5 1997/12/01 17:57:33 ralf Exp $
*/
#include <linux/config.h>
#include <linux/init.h>
@@ -105,7 +105,7 @@ void show_registers(char * str, struct pt_regs * regs, long err)
/*
* Dump the stack
*/
- printk("Process %s (pid: %d, stackpage=%08lx)\nStack: ",
+ printk("Process %s (pid: %ld, stackpage=%08lx)\nStack: ",
current->comm, current->pid, (unsigned long)current);
for(i=0;i<5;i++)
printk("%08x ", *sp++);
@@ -337,7 +337,7 @@ void do_ri(struct pt_regs *regs)
#ifdef CONF_DEBUG_EXCEPTIONS
show_regs(regs);
#endif
- printk("[%s:%d] Illegal instruction at %08lx ra=%08lx\n",
+ printk("[%s:%ld] Illegal instruction at %08lx ra=%08lx\n",
current->comm, current->pid, regs->cp0_epc, regs->regs[31]);
if (compute_return_epc(regs))
goto out;
@@ -489,7 +489,6 @@ __initfunc(void trap_init(void))
unsigned long i;
if(mips_machtype == MACH_MIPS_MAGNUM_4000 ||
- mips_machtype == MACH_DESKSTATION_RPC44 ||
mips_machtype == MACH_SNI_RM200_PCI)
EISA_bus = 1;
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index fd706165c..7da90c6d0 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -17,10 +17,9 @@ L_TARGET = lib.a
L_OBJS = beep.o checksum.o copy_user.o csum.o dump_tlb.o memset.o memcpy.o \
strlen_user.o strncpy_user.o tags.o watch.o
-ifdef CONFIG_DECSTATION
-L_OBJS += pmaxcon.o pmaxio.o
-else
+#
+# Debug console, works without other support from the kernel
+#
L_OBJS += tinycon.o
-endif
include $(TOPDIR)/Rules.make
diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c
index 0c7f81877..6205719f5 100644
--- a/arch/mips/lib/dump_tlb.c
+++ b/arch/mips/lib/dump_tlb.c
@@ -20,17 +20,6 @@ static char *region_map [] = {
"u", "s", "k", "!"
};
-static char *cache_map [] = {
- "c/nc/wt/nwa,",
- "c/nc/wt/wa, ",
- "uncached, ",
- "c/nc/wb, "
- "unknown, ",
- "unknown, ",
- "unknown, ",
- "unknown, "
-};
-
void
dump_tlb(int first, int last)
{
@@ -69,9 +58,9 @@ dump_tlb(int first, int last)
c0 = (entrylo0 >> 3) & 7;
c1 = (entrylo1 >> 3) & 7;
- printk("%s vpn2=%08x "
- "[pfn=%06x c=%d d=%d v=%d g=%d]"
- "[pfn=%06x c=%d d=%d v=%d g=%d]",
+ printk("%s vpn2=%08Lx "
+ "[pfn=%06Lx c=%d d=%d v=%d g=%Ld]"
+ "[pfn=%06Lx c=%d d=%d v=%d g=%Ld]",
region_map [r], (entryhi >> 13) & 0xffffffff,
(entrylo0 >> 6) & 0xffffff, c0,
(entrylo0 & 4) ? 1 : 0,
diff --git a/arch/mips/lib/pmaxcon.c b/arch/mips/lib/pmaxcon.c
index 3b2cb1216..e69de29bb 100644
--- a/arch/mips/lib/pmaxcon.c
+++ b/arch/mips/lib/pmaxcon.c
@@ -1,150 +0,0 @@
-/* ----------------------------------------------------------------------
- * console.c
- *
- * Copyright (C) 1994 by Waldorf Electronic,
- * written by Ralf Baechle and Andreas Busse
- * Copyright (C) 1995 Paul M. Antoine (PMAX)
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- * ---------------------------------------------------------------------- */
-/*
- * FIXME: This file is hacked to be hardwired for the Personal DECStation
- * Only thought of as a debugging console output
- */
-
-#include <linux/tty.h>
-#include <asm/bootinfo.h>
-
-static unsigned int size_x;
-static unsigned int size_y;
-static unsigned short cursor_x;
-static unsigned short cursor_y;
-static volatile unsigned short *vram_addr;
-static int console_needs_init = 1;
-
-extern struct bootinfo boot_info;
-extern struct screen_info screen_info;
-
-/*
- * Here is the base address of the prom calls
- */
-unsigned long pmax_rex_base = 0;
-
-/* ----------------------------------------------------------------------
- * init_console()
- * ---------------------------------------------------------------------- */
-
-void init_console(void)
-{
- size_x = 80;
- size_y = 50;
- cursor_x = 0;
- cursor_y = 0;
-
- vram_addr = (unsigned short *)0xe10b8000;
-
- console_needs_init = 0;
-}
-
-void
-set_size_x(unsigned int x)
-{
- size_x = x;
-}
-
-void
-set_size_y(unsigned int y)
-{
- size_y = y;
-}
-
-void
-set_vram(unsigned short *vram)
-{
- vram_addr = vram;
-}
-
-/*
- * FIXME: Temporary hack - changed its name to avoid conflict in
- * drivers/char/vga.c that shouldn't be there <sigh> PMA
- */
-void
-set_pmax_cursor(unsigned int x, unsigned int y)
-{
- cursor_x = x;
- cursor_y = y;
-}
-
-void
-print_char(unsigned int x, unsigned int y, unsigned char c)
-{
- volatile unsigned short *caddr;
-
-/* caddr = vram_addr + (y * size_x) + x;
- *caddr = (*caddr & 0xff00) | 0x0f00 | (unsigned short) c;
-*/
- pmax_putch(c);
-}
-
-static void
-scroll(void)
-{
- volatile unsigned short *caddr;
- register int i;
-/*
- caddr = vram_addr;
- for(i=0; i<size_x * (size_y-1); i++)
- *(caddr++) = *(caddr + size_x);
-
- blank last line
-
- caddr = vram_addr + (size_x * (size_y-1));
- for(i=0; i<size_x; i++)
- *(caddr++) = (*caddr & 0xff00) | (unsigned short) ' ';
-*/
- pmax_putch('\n');
-}
-
-void print_string(const unsigned char *str)
-{
- unsigned char c;
-
- if (console_needs_init)
- init_console();
-/*
- while((c = *str++))
- switch(c)
- {
- case '\n':
- cursor_x = 0;
- cursor_y++;
- if(cursor_y == size_y)
- {
- scroll();
- cursor_y = size_y - 1;
- }
- break;
-
- default:
- print_char(cursor_x, cursor_y, c);
- cursor_x++;
- if(cursor_x == size_x)
- {
- cursor_x = 0;
- cursor_y++;
- if(cursor_y == size_y)
- {
- scroll();
- cursor_y = size_y - 1;
- }
- }
- break;
- }
-*/
- pmax_printf(str);
-
-}
-
-/* end of file */
diff --git a/arch/mips/lib/pmaxio.S b/arch/mips/lib/pmaxio.S
index 66e216a55..e69de29bb 100644
--- a/arch/mips/lib/pmaxio.S
+++ b/arch/mips/lib/pmaxio.S
@@ -1,40 +0,0 @@
-#include <asm/regdef.h>
-#include <asm/decstation.h>
-
- .text
- .set reorder
-/*
- * pmax_printf - call the PROM printf() function
- */
- .globl pmax_printf
-pmax_printf:
- lw v0,pmax_rex_base
- lw v0,REX_PRINTF(v0)
- j v0
-
-/*
- * pmax_getchar - call the PROM getchar() function
- */
- .globl pmax_getch
-pmax_getch:
- lw v0,pmax_rex_base
- lw v0,REX_GETCHAR(v0)
- j v0
-
-/*
- * pmax_putchar - call the PROM putchar() function
- */
- .globl pmax_putch
-pmax_putch:
- lw v0,pmax_rex_base
- lw v0,REX_PUTCHAR(v0)
- j v0
-
-/*
- * pmax_halt - call the PROM halt() function
- */
- .globl pmax_halt
-pmax_halt:
- lw v0,pmax_rex_base
- lw v0,REX_HALT(v0)
- j v0
diff --git a/arch/mips/mips/Makefile b/arch/mips/mips/Makefile
index b252e2fe4..e69de29bb 100644
--- a/arch/mips/mips/Makefile
+++ b/arch/mips/mips/Makefile
@@ -1,39 +0,0 @@
-#
-# PROM Entries for the big endian firmware used in the Mips Computer
-# System, Inc. machines. Beware: some of the machines seem to be
-# different.
-#
-# Copyright (C) 1997 Ralf Baechle
-#
-prom-entries= reset exec restart reinit reboot autoboot open read write ioctl \
- close getchar putchar showchar gets puts printf initproto protoenable \
- protodisable getpkt putpkt orw_rmw orh_rmw orb_rmw andw_rmw andh_rmw \
- andb_rmw flushcache clearcache setjmp longjmp bevutlb getenv setenv \
- atob strcmp strlen strcpy strcat parser range argvize help dumpcmd \
- setenvcmd unsetenvcmd printenvcmd bevexcept enablecmd disablecmd \
- clearnofault notimplement nv_get nv_set
-asm-files=$(addsuffix .S,$(prom-entries))
-object-files=$(addsuffix .o,$(prom-entries))
-
-CC=mipsel-linux-gcc
-AR=mipsel-linux-ar
-CFLAGS=-O2 -mno-abicalls -fno-pic -G0 -Wall
-
-all: libprom.a
-
-libprom.a: $(asm-files)
- set -e;for i in $(prom-entries); do \
- $(CC) $(CFLAGS) -c -o $$i.o $$i.S; \
- $(AR) rcv libprom.a $$i.o; \
- done
-
-$(asm-files): mkprom
- set -e;for i in $(prom-entries); do \
- mkprom $$i; \
- done
-
-clean:
- rm -f $(object-files)
-
-distclean:
- rm -rf $(asm-files) libprom.a
diff --git a/arch/mips/mips/mkprom b/arch/mips/mips/mkprom
index 9e4cdf465..e69de29bb 100755
--- a/arch/mips/mips/mkprom
+++ b/arch/mips/mips/mkprom
@@ -1,25 +0,0 @@
-#
-# Generate PROM library stubs for the firmware used in the
-# Mips Computer System, Inc. machines. Beware: some of the
-# machines seem to be different.
-#
-# Copyright (C) 1997 Ralf Baechle
-#
-fname=$1
-ucase=`echo $fname | tr 'a-z' 'A-Z'`
-cat << EOF | sed -e "s/@1@/$fname/" -e "s/@2@/$ucase/" >$fname.S
-/*
- * WARNING: This file has been generated automatically. Do not edit!
- *
- * Stub for the Mips firmware @1@() function.
- */
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/mipsprom.h>
-
-LEAF(mips_prom_@1@)
- lw t0,__mips_prom_entry_offset
- addu t0,PROM_@2@
- jr t0
- END(mips_prom_@1@)
-EOF
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 72e13336b..8385eb22f 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -85,7 +85,7 @@ bad_area:
if (user_mode(regs)) {
tsk->tss.cp0_badvaddr = address;
tsk->tss.error_code = writeaccess;
-#if 1
+#if 0
printk("do_page_fault() #2: sending SIGSEGV to %s for illegal %s\n"
"%08lx (epc == %08lx, ra == %08lx)\n",
tsk->comm,
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index b62e571d6..9cb47cefa 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -229,27 +229,11 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
for(tmp = MAP_NR(start_mem);tmp < max_mapnr;tmp++)
clear_bit(PG_reserved, &mem_map[tmp].flags);
- /*
- * For rPC44 and RM200 we've reserved some memory too much. Free
- * the memory from PAGE_SIZE to PAGE_OFFSET + 0xa0000 again. We
- * don't free the lowest page where the exception handlers will
- * reside.
- */
- if (mips_machgroup == MACH_GROUP_ARC &&
- mips_machtype == MACH_DESKSTATION_RPC44)
- for(tmp = MAP_NR(PAGE_OFFSET + PAGE_SIZE);
- tmp < MAP_NR(PAGE_OFFSET + 0xa000); tmp++)
- clear_bit(PG_reserved, &mem_map[tmp].flags);
-
#ifdef CONFIG_SGI
prom_fixup_mem_map(start_mem, (unsigned long)high_memory);
#endif
-#ifdef CONFIG_DESKSTATION_TYNE
- deskstation_tyne_dma_init();
-#endif
-
for (tmp = PAGE_OFFSET; tmp < end_mem; tmp += PAGE_SIZE) {
/*
* This is only for PC-style DMA. The onboard DMA
diff --git a/arch/mips/mm/r4xx0.c b/arch/mips/mm/r4xx0.c
index a0786131f..4c7ebd6f0 100644
--- a/arch/mips/mm/r4xx0.c
+++ b/arch/mips/mm/r4xx0.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
- * $Id: r4xx0.c,v 1.9 1997/12/01 17:57:36 ralf Exp $
+ * $Id: r4xx0.c,v 1.10 1997/12/02 14:49:20 ralf Exp $
*
* To do:
*
@@ -2424,6 +2424,38 @@ static void probe_dcache(unsigned long config)
(int)(dcache_size >> 10), (int)dc_lsize);
}
+/*
+ * Activate the chipset controlled R4600 and R5000 caches of the Indy
+ */
+static inline void enable_indy_scache(void)
+{
+ unsigned long addr, tmp1, tmp2;
+
+ /* This is really cool... */
+ printk("Enabling R4600 SCACHE\n");
+ __asm__ __volatile__("
+ .set noreorder
+ .set mips3
+ mfc0 %2, $12
+ nop; nop; nop; nop;
+ li %1, 0x80
+ mtc0 %1, $12
+ nop; nop; nop; nop;
+ li %0, 0x1
+ dsll %0, 31
+ lui %1, 0x9000
+ dsll32 %1, 0
+ or %0, %1, %0
+ sb $0, 0(%0)
+ mtc0 $0, $12
+ nop; nop; nop; nop;
+ mtc0 %2, $12
+ nop; nop; nop; nop;
+ .set mips0
+ .set reorder"
+ : "=r" (tmp1), "=r" (tmp2), "=r" (addr));
+}
+
static int probe_scache_eeprom(unsigned long config)
{
#ifdef CONFIG_SGI
@@ -2487,7 +2519,7 @@ static int probe_scache_eeprom(unsigned long config)
printk("linesize %d bytes\n", sc_lsize);
scache_size = data;
if(data) {
- unsigned long addr, tmp1, tmp2;
+ unsigned long addr;
/* Enable r4600/r5000 cache. But flush it first. */
for(addr = KSEG0; addr < (KSEG0 + dcache_size);
@@ -2500,42 +2532,26 @@ static int probe_scache_eeprom(unsigned long config)
addr += sc_lsize)
flush_scache_line_indexed(addr);
- /* R5000 scache enable is in CP0 config, on R4600 variants
+ /*
+ * R5000 scache enable is in CP0 config, on R4600 variants
* the scache is enable by the memory mapped cache controller.
*/
+ if (mips_cputype == CPU_R4600 ||
+ mips_cputype == CPU_R5000) {
+ enable_indy_scache();
+ return 1;
+ }
+#if 0
if(mips_cputype == CPU_R5000) {
unsigned long config;
config = read_32bit_cp0_register(CP0_CONFIG);
config |= 0x1000;
write_32bit_cp0_register(CP0_CONFIG, config);
- } else {
- /* This is really cool... */
- printk("Enabling R4600 SCACHE\n");
- __asm__ __volatile__("
- .set noreorder
- .set mips3
- mfc0 %2, $12
- nop; nop; nop; nop;
- li %1, 0x80
- mtc0 %1, $12
- nop; nop; nop; nop;
- li %0, 0x1
- dsll %0, 31
- lui %1, 0x9000
- dsll32 %1, 0
- or %0, %1, %0
- sb $0, 0(%0)
- mtc0 $0, $12
- nop; nop; nop; nop;
- mtc0 %2, $12
- nop; nop; nop; nop;
- .set mips0
- .set reorder
- " : "=r" (tmp1), "=r" (tmp2), "=r" (addr));
}
-
+#endif
return 1;
+
} else {
if(mips_cputype == CPU_R5000)
return -1;
@@ -2831,7 +2847,8 @@ void ld_mmu_r4xx0(void)
} else {
/* Lacks true secondary cache. */
setup_noscache_funcs();
- if((mips_cputype != CPU_R5000)) { /* XXX */
+ if (mips_cputype == CPU_R4600 ||
+ mips_cputype == CPU_R5000) {
flush_cache_page =
r4k_flush_cache_page_d32i32_r4600;
flush_page_to_ram =
diff --git a/arch/mips/sgi/kernel/reset.c b/arch/mips/sgi/kernel/reset.c
index 6bb8616fa..578a20574 100644
--- a/arch/mips/sgi/kernel/reset.c
+++ b/arch/mips/sgi/kernel/reset.c
@@ -6,6 +6,7 @@
#include <asm/io.h>
#include <asm/system.h>
#include <asm/reboot.h>
+#include <asm/sgialib.h>
/* XXX How to pass the reboot command to the firmware??? */
void sgi_machine_restart(char *command)
diff --git a/arch/mips/tools/offset.c b/arch/mips/tools/offset.c
index cc6b7b7d3..88926ebfd 100644
--- a/arch/mips/tools/offset.c
+++ b/arch/mips/tools/offset.c
@@ -4,7 +4,7 @@
* Copyright (C) 1996 David S. Miller
* Made portable by Ralf Baechle
*
- * $Id: offset.c,v 1.3 1997/07/29 18:57:11 ralf Exp $
+ * $Id: offset.c,v 1.3 1997/12/01 17:57:41 ralf Exp $
*/
#include <linux/types.h>
@@ -81,9 +81,8 @@ void output_task_defines(void)
offset("#define TASK_STATE ", struct task_struct, state);
offset("#define TASK_COUNTER ", struct task_struct, counter);
offset("#define TASK_PRIORITY ", struct task_struct, priority);
- offset("#define TASK_SIGNAL ", struct task_struct, signal);
- offset("#define TASK_BLOCKED ", struct task_struct, blocked);
offset("#define TASK_FLAGS ", struct task_struct, flags);
+ offset("#define TASK_SIGPENDING ", struct task_struct, sigpending);
offset("#define TASK_MM ", struct task_struct, mm);
linefeed;
}
diff --git a/arch/ppc/config.in b/arch/ppc/config.in
index cdd5c4a03..7ce44ea4c 100644
--- a/arch/ppc/config.in
+++ b/arch/ppc/config.in
@@ -89,6 +89,7 @@ if [ "$CONFIG_NET" = "y" ]; then
endmenu
fi
+source drivers/net/hamradio/Config.in
mainmenu_option next_comment
comment 'ISDN subsystem'
@@ -106,6 +107,17 @@ if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
fi
endmenu
+# Conditionally compile in the Uniform CD-ROM driver
+if [ "$CONFIG_BLK_DEV_SR" = "y" -o "$CONFIG_SBPCD" = "y" -o "$CONFIG_MCD" = "y" -o "$CONFIG_CM206" = "y" -o "$CONFIG_CDU31A" = "y" ]; then
+ define_bool CONFIG_CDROM y
+else
+ if [ "$CONFIG_BLK_DEV_SR" = "m" -o "$CONFIG_SBPCD" = "m" -o "$CONFIG_MCD" = "m" -o "$CONFIG_CM206" = "m" -o "$CONFIG_CDU31A" = "m" ]; then
+ define_bool CONFIG_CDROM m
+ else
+ define_bool CONFIG_CDROM n
+ fi
+fi
+
source fs/Config.in
source fs/nls/Config.in
diff --git a/arch/sparc/config.in b/arch/sparc/config.in
index ae8568b25..ef4bb3777 100644
--- a/arch/sparc/config.in
+++ b/arch/sparc/config.in
@@ -144,6 +144,17 @@ if [ "$CONFIG_NET" = "y" ]; then
endmenu
fi
+# Conditionally compile in the Uniform CD-ROM driver
+if [ "$CONFIG_BLK_DEV_SR" = "y" ]; then
+ define_bool CONFIG_CDROM y
+else
+ if [ "$CONFIG_BLK_DEV_SR" = "m" ]; then
+ define_bool CONFIG_CDROM m
+ else
+ define_bool CONFIG_CDROM n
+ fi
+fi
+
source fs/Config.in
source fs/nls/Config.in
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
index 13f056050..14d545e39 100644
--- a/arch/sparc64/config.in
+++ b/arch/sparc64/config.in
@@ -181,6 +181,17 @@ if [ "$CONFIG_NET" = "y" ]; then
endmenu
fi
+# Conditionally compile in the Uniform CD-ROM driver
+if [ "$CONFIG_BLK_DEV_IDECD" = "y" -o "$CONFIG_BLK_DEV_SR" = "y" ]; then
+ define_bool CONFIG_CDROM y
+else
+ if [ "$CONFIG_BLK_DEV_IDECD" = "m" -o "$CONFIG_BLK_DEV_SR" = "m" ]; then
+ define_bool CONFIG_CDROM m
+ else
+ define_bool CONFIG_CDROM n
+ fi
+fi
+
source fs/Config.in
source fs/nls/Config.in
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index e2c199f60..81640c8e6 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -38,9 +38,9 @@
#include <linux/nfsd/xdr.h>
#include <linux/nfsd/syscall.h>
#include <linux/module.h>
+#include <linux/poll.h>
#include <asm/types.h>
-#include <asm/poll.h>
#include <asm/ipc.h>
#include <asm/uaccess.h>
#include <asm/fpumacro.h>
@@ -1075,104 +1075,139 @@ out:
/* end of readdir & getdents */
-extern asmlinkage int sys_select(int n, fd_set *inp, fd_set *outp,
- fd_set *exp, struct timeval *tvp);
+/*
+ * Ooo, nasty. We need here to frob 32-bit unsigned longs to
+ * 64-bit unsigned longs.
+ */
-asmlinkage int sys32_select(int n, u32 inp, u32 outp, u32 exp, u32 tvp)
+static inline int
+get_fd_set32(unsigned long n, unsigned long *fdset, u32 ufdset_x)
{
- struct timeval kern_tv, *ktvp;
- unsigned long old_fs;
- char *p;
- u32 *q, *Inp, *Outp, *Exp;
- int i, ret = -EINVAL, nn;
-
- if (n < 0 || n > PAGE_SIZE*2)
- return -EINVAL;
-
- lock_kernel ();
- p = (char *)__get_free_page (GFP_KERNEL);
- if (!p)
- goto out_nofree;
+ u32 *ufdset = (u32 *)A(ufdset_x);
- q = (u32 *)p;
- Inp = (u32 *)A(inp);
- Outp = (u32 *)A(outp);
- Exp = (u32 *)A(exp);
+ if (ufdset) {
+ unsigned long odd;
- ret = -EFAULT;
+ if (verify_area(VERIFY_WRITE, ufdset, nn*sizeof(u32)))
+ return -EFAULT;
- nn = (n + (8 * sizeof(long)) - 1) / (8 * sizeof(long));
- if (inp && verify_area(VERIFY_WRITE, Inp, nn*sizeof(long)))
- goto out;
- if (outp && verify_area(VERIFY_WRITE, Outp, nn*sizeof(long)))
- goto out;
- if (exp && verify_area(VERIFY_WRITE, Exp, nn*sizeof(long)))
- goto out;
- for (i = 0; i < nn; i++, Inp += 2, Outp += 2, Exp += 2, q += 2) {
- if(inp && (__get_user (q[1], Inp) || __get_user (q[0], Inp+1)))
- goto out;
- if(outp && (__get_user (q[1+(PAGE_SIZE/4/sizeof(u32))], Outp) ||
- __get_user (q[(PAGE_SIZE/4/sizeof(u32))], Outp+1)))
- goto out;
- if(exp && (__get_user (q[1+(PAGE_SIZE/2/sizeof(u32))], Exp) ||
- __get_user (q[(PAGE_SIZE/2/sizeof(u32))], Exp+1)))
- goto out;
+ odd = n & 1UL;
+ n &= ~1UL;
+ while (n) {
+ unsigned long h, l;
+ __get_user(l, ufdset);
+ __get_user(h, ufdset+1);
+ ufdset += 2;
+ *fdset++ = h << 32 | l;
+ n -= 2;
+ }
+ if (odd)
+ __get_user(*fdset, ufdset);
+ } else {
+ /* Tricky, must clear full unsigned long in the kernel
+ fdset at the end, this makes sure that actually
+ happens. */
+ memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
}
- ktvp = NULL;
- if(tvp) {
- if (get_tv32(&kern_tv, (struct timeval32 *)A(tvp)))
- goto out;
- ktvp = &kern_tv;
- }
+ return 0;
+}
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- q = (u32 *) p;
- ret = sys_select(n,
- inp ? (fd_set *)&q[0] : (fd_set *)0,
- outp ? (fd_set *)&q[PAGE_SIZE/4/sizeof(u32)] : (fd_set *)0,
- exp ? (fd_set *)&q[PAGE_SIZE/2/sizeof(u32)] : (fd_set *)0,
- ktvp);
- set_fs (old_fs);
+static inline void
+set_fd_set32(unsigned long n, u32 ufdset_x, unsigned long *fdset)
+{
+ unsigned long odd;
+ u32 *ufdset = (u32 *)A(ufdset_x);
- if(tvp && !(current->personality & STICKY_TIMEOUTS)) {
- if (put_tv32((struct timeval32 *)A(tvp), &kern_tv)) {
- ret = -EFAULT;
- goto out;
- }
+ if (!ufdset)
+ return;
+
+ odd = n & 1UL;
+ n &= ~1UL;
+ while (n) {
+ unsigned long h, l;
+ l = *fdset++;
+ h = l >> 32;
+ __put_user(l, ufdset);
+ __put_user(h, ufdset+1);
+ ufdset += 2;
+ n -= 2;
}
+ if (odd)
+ __put_user(*fdset, ufdset);
+}
+
+asmlinkage int sys32_select(int n, u32 inp, u32 outp, u32 exp, u32 tvp_x)
+{
+ fd_set_buffer *fds;
+ struct timeval32 *tvp = (struct timeval32 *)A(tvp_x);
+ unsigned long timeout, nn;
+ int ret;
- q = (u32 *)p;
- Inp = (u32 *)A(inp);
- Outp = (u32 *)A(outp);
- Exp = (u32 *)A(exp);
+ timeout = ~0UL;
+ if (tvp) {
+ time_t sec, usec;
- if(ret < 0)
- goto out;
+ if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
+ || (ret = __get_user(sec, &tvp->tv_sec))
+ || (ret = __get_user(usec, &tvp->tv_usec)))
+ goto out_nofds;
- for (i = 0;
- i < nn;
- i++, Inp += 2, Outp += 2, Exp += 2, q += 2) {
- if(inp && (__put_user (q[1], Inp) || __put_user (q[0], Inp+1))) {
- ret = -EFAULT;
- goto out;
- }
- if(outp && (__put_user (q[1+(PAGE_SIZE/4/sizeof(u32))], Outp) ||
- __put_user (q[(PAGE_SIZE/4/sizeof(u32))], Outp+1))) {
- ret = -EFAULT;
- goto out;
+ timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
+ timeout += sec * HZ;
+ if (timeout)
+ timeout += jiffies + 1;
+ }
+
+ ret = -ENOMEM;
+ fds = (fd_set_buffer *) __get_free_page(GFP_KERNEL);
+ if (!fds)
+ goto out_nofds;
+ ret = -EINVAL;
+ if (n < 0)
+ goto out;
+ if (n > KFDS_NR)
+ n = KFDS_NR;
+
+ nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
+ if ((ret = get_fd_set32(nn, fds->in, inp)) ||
+ (ret = get_fd_set32(nn, fds->out, outp)) ||
+ (ret = get_fd_set32(nn, fds->ex, exp)))
+ goto out;
+ zero_fd_set(n, fds->res_in);
+ zero_fd_set(n, fds->res_out);
+ zero_fd_set(n, fds->res_ex);
+
+ ret = do_select(n, fds, timeout);
+
+ if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
+ unsigned long timeout = current->timeout - jiffies - 1;
+ time_t sec = 0, usec = 0;
+ if ((long) timeout > 0) {
+ sec = timeout / HZ;
+ usec = timeout % HZ;
+ usec *= (1000000/HZ);
}
- if(exp && (__put_user (q[1+(PAGE_SIZE/2/sizeof(u32))], Exp) ||
- __put_user (q[(PAGE_SIZE/2/sizeof(u32))], Exp+1))) {
- ret = -EFAULT;
+ put_user(sec, &tvp->tv_sec);
+ put_user(usec, &tvp->tv_usec);
+ }
+
+ if (ret < 0)
+ goto out;
+ if (!ret) {
+ ret = -ERESTARTNOHAND;
+ if (current->signal & ~current->blocked)
goto out;
- }
+ ret = 0;
}
+
+ set_fd_set32(nn, inp, fds->res_in);
+ set_fd_set32(nn, outp, fds->res_out);
+ set_fd_set32(nn, exp, fds->res_ex);
+
out:
- free_page ((unsigned long)p);
-out_nofree:
- unlock_kernel();
+ free_page ((unsigned long)fds);
+out_nofds:
return ret;
}