summaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/Makefile3
-rw-r--r--arch/mips/boot/elf2ecoff.c1
-rw-r--r--arch/mips/config.in4
-rw-r--r--arch/mips/defconfig31
-rw-r--r--arch/mips/defconfig-ip22297
-rw-r--r--arch/mips/kernel/irixelf.c75
-rw-r--r--arch/mips/kernel/irixioctl.c19
-rw-r--r--arch/mips/kernel/irixsig.c40
-rw-r--r--arch/mips/kernel/irq.c6
-rw-r--r--arch/mips/kernel/process.c18
-rw-r--r--arch/mips/kernel/ptrace.c233
-rw-r--r--arch/mips/kernel/r2300_fpu.S13
-rw-r--r--arch/mips/kernel/r4k_fpu.S16
-rw-r--r--arch/mips/kernel/r4k_misc.S6
-rw-r--r--arch/mips/kernel/setup.c12
-rw-r--r--arch/mips/kernel/signal.c438
-rw-r--r--arch/mips/kernel/syscalls.h8
-rw-r--r--arch/mips/mm/fault.c30
-rw-r--r--arch/mips/mm/r4xx0.c6
-rw-r--r--arch/mips/sgi/kernel/indy_sc.c3
-rw-r--r--arch/mips/tools/offset.c16
21 files changed, 747 insertions, 528 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index e6e83b34a..f839b134f 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.19 1999/08/18 23:37:42 ralf Exp $
+# $Id: Makefile,v 1.20 1999/08/20 21:59:01 ralf Exp $
#
# 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
@@ -117,7 +117,6 @@ SUBDIRS += arch/mips/sgi/kernel arch/mips/arc
# 8kb aligned or the handling of the current variable will break.
#
LOADADDR += 0x88002000
-HOSTCC = cc
endif
#
diff --git a/arch/mips/boot/elf2ecoff.c b/arch/mips/boot/elf2ecoff.c
index 55f5896c5..dc8e981e6 100644
--- a/arch/mips/boot/elf2ecoff.c
+++ b/arch/mips/boot/elf2ecoff.c
@@ -35,7 +35,6 @@
#include <stdio.h>
#include <string.h>
-#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>
diff --git a/arch/mips/config.in b/arch/mips/config.in
index f7fb7b2e9..9a1d95025 100644
--- a/arch/mips/config.in
+++ b/arch/mips/config.in
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.29 1999/08/18 23:37:42 ralf Exp $
+# $Id: config.in,v 1.30 1999/08/20 21:59:01 ralf Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
@@ -123,7 +123,7 @@ bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
bool 'Sysctl support' CONFIG_SYSCTL
if [ "$CONFIG_SGI_IP22" != "y" -a "$CONFIG_DECSTATION" != "y" -a "$CONFIG_BAGET_MIPS" != "y" ]; then
- tristate 'Parallel port support' CONFIG_PARPORT
+ source drivers/misc/Config.in
fi
endmenu
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 828f2477e..3aa72b746 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -28,6 +28,9 @@ CONFIG_CPU_R4X00=y
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R8000 is not set
# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_WB is not set
#
# General setup
@@ -63,11 +66,6 @@ CONFIG_KMOD=y
# CONFIG_I2O_PROC is not set
#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
# Block devices
#
CONFIG_BLK_DEV_FD=m
@@ -87,6 +85,7 @@ CONFIG_BLK_DEV_IDECD=m
# CONFIG_BLK_DEV_RZ1000 is not set
# CONFIG_BLK_DEV_IDEPCI is not set
# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_CPQ_DA is not set
#
# Additional Block Devices
@@ -202,9 +201,17 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20
# Network device support
#
CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
# CONFIG_EQUALIZER is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
CONFIG_NET_ETHERNET=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
@@ -217,7 +224,6 @@ CONFIG_PCNET32=y
# CONFIG_CS89x0 is not set
# CONFIG_DE4X5 is not set
# CONFIG_DEC_ELCP is not set
-# CONFIG_DEC_ELCP is not set
# CONFIG_DGRS is not set
# CONFIG_EEXPRESS_PRO100 is not set
# CONFIG_NE2K_PCI is not set
@@ -225,14 +231,22 @@ CONFIG_PCNET32=y
# CONFIG_VIA_RHINE is not set
# CONFIG_NET_POCKET is not set
# CONFIG_FDDI is not set
-# CONFIG_DLCI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_NET_RADIO is not set
+
+#
+# Token ring devices
+#
# CONFIG_TR is not set
+
+#
+# Wan interfaces
+#
# CONFIG_HOSTESS_SV11 is not set
# CONFIG_COSA is not set
-# CONFIG_RCPCI is not set
+# CONFIG_SEALEVEL_4021 is not set
+# CONFIG_DLCI is not set
# CONFIG_WAN_DRIVERS is not set
# CONFIG_LAPBETHER is not set
# CONFIG_X25_ASY is not set
@@ -387,5 +401,4 @@ CONFIG_VGA_CONSOLE=y
#
# CONFIG_CROSSCOMPILE is not set
# CONFIG_MIPS_FPE_MODULE is not set
-# CONFIG_REMOTE_DEBUG is not set
# CONFIG_MAGIC_SYSRQ is not set
diff --git a/arch/mips/defconfig-ip22 b/arch/mips/defconfig-ip22
new file mode 100644
index 000000000..6658c84ea
--- /dev/null
+++ b/arch/mips/defconfig-ip22
@@ -0,0 +1,297 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Machine selection
+#
+# CONFIG_ACER_PICA_61 is not set
+# CONFIG_ALGOR_P4032 is not set
+# CONFIG_BAGET_MIPS is not set
+# CONFIG_DECSTATION is not set
+# CONFIG_MIPS_MAGNUM_4000 is not set
+# CONFIG_OLIVETTI_M700 is not set
+CONFIG_SGI_IP22=y
+# CONFIG_SNI_RM200_PCI is not set
+
+#
+# CPU selection
+#
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_ADVANCED is not set
+CONFIG_CPU_HAS_LLSC=y
+# CONFIG_CPU_HAS_WB is not set
+
+#
+# General setup
+#
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_ELF_KERNEL=y
+CONFIG_BINFMT_IRIX=y
+CONFIG_FORWARD_KEYBOARD=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+# CONFIG_FB is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_IDE is not set
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_CPQ_DA is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE_PARPORT=m
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_NETLINK is not set
+# CONFIG_FIREWALL is not set
+# CONFIG_FILTER 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_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_RARP is not set
+# CONFIG_SKB_LARGE is not set
+# CONFIG_IPV6 is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+# CONFIG_CPU_IS_SLOW is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CDrom)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+
+#
+# SCSI low-level drivers
+#
+CONFIG_SCSI_SGIWD93=y
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_SLIP is not set
+# CONFIG_PPP is not set
+CONFIG_SGISEEQ=y
+
+#
+# Character devices
+#
+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_UNIX98_PTYS is not set
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+CONFIG_MOUSE=y
+
+#
+# Mice
+#
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_DTLK is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+
+#
+# USB drivers - not for the faint of heart
+#
+# CONFIG_USB is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFSD=y
+# CONFIG_NFSD_SUN is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_SMD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+CONFIG_SGI_DISKLABEL=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_NLS is not set
+
+#
+# Console drivers
+#
+CONFIG_SGI_NEWPORT_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# SGI devices
+#
+CONFIG_SGI_SERIAL=y
+CONFIG_SERIAL=y
+CONFIG_SGI_DS1286=y
+# CONFIG_SGI_NEWPORT_GFX is not set
+
+#
+# Kernel hacking
+#
+CONFIG_CROSSCOMPILE=y
+# CONFIG_MIPS_FPE_MODULE is not set
+# CONFIG_REMOTE_DEBUG is not set
+# CONFIG_MAGIC_SYSRQ is not set
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 4b512e14b..3eadd1832 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -1,4 +1,4 @@
-/* $Id: irixelf.c,v 1.19 1999/08/04 05:28:51 ulfc Exp $
+/* $Id: irixelf.c,v 1.20 1999/08/04 14:54:04 ulfc Exp $
*
* irixelf.c: Code to load IRIX ELF executables which conform to
* the MIPS ABI.
@@ -624,9 +624,10 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
has_interp = has_ephdr = 0;
elf_ihdr = elf_ephdr = 0;
elf_ex = *((struct elfhdr *) bprm->buf);
-
- if(verify_binary(&elf_ex, bprm))
- return -ENOEXEC;
+ retval = -ENOEXEC;
+
+ if (verify_binary(&elf_ex, bprm))
+ goto out;
#ifdef DEBUG_ELF
print_elfhdr(&elf_ex);
@@ -634,15 +635,19 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
/* Now read in all of the header information */
size = elf_ex.e_phentsize * elf_ex.e_phnum;
+ if (size > 65536)
+ goto out;
elf_phdata = (struct elf_phdr *) kmalloc(size, GFP_KERNEL);
- if (elf_phdata == NULL)
- return -ENOMEM;
-
+ if (elf_phdata == NULL) {
+ retval = -ENOMEM;
+ goto out;
+ }
+
retval = read_exec(bprm->dentry, elf_ex.e_phoff,
(char *) elf_phdata, size, 1);
if (retval < 0)
- goto out_phdata;
-
+ goto out_free_ph;
+
#ifdef DEBUG_ELF
dump_phdrs(elf_phdata, elf_ex.e_phnum);
#endif
@@ -668,39 +673,39 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
elf_brk = 0;
retval = open_dentry(bprm->dentry, O_RDONLY);
if (retval < 0)
- goto out_phdata;
+ goto out_free_ph;
file = fget(elf_exec_fileno = retval);
-
+
elf_stack = 0xffffffff;
elf_interpreter = NULL;
start_code = 0xffffffff;
end_code = 0;
end_data = 0;
-
+
retval = look_for_irix_interpreter(&elf_interpreter,
&interpreter_dentry,
&interp_elf_ex, elf_phdata, bprm,
elf_ex.e_phnum);
if(retval)
- goto out_file;
-
+ goto out_free_file;
+
if(elf_interpreter) {
retval = verify_irix_interpreter(&interp_elf_ex);
if(retval)
- goto out_interp;
+ goto out_free_interp;
}
-
+
/* OK, we are done with that, now set up the arg stuff,
* and then start this sucker up.
*/
retval = -E2BIG;
if (!bprm->sh_bang && !bprm->p)
- goto out_interp;
-
+ goto out_free_interp;
+
/* Flush all traces of the currently running executable */
retval = flush_old_exec(bprm);
if (retval)
- goto out_interp;
+ goto out_free_dentry;
/* OK, This is the point of no return */
current->mm->end_data = 0;
@@ -715,15 +720,16 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
current->mm->rss = 0;
setup_arg_pages(bprm);
current->mm->start_stack = bprm->p;
-
+
/* At this point, we assume that the image should be loaded at
* fixed address, not at a variable address.
*/
old_fs = get_fs();
set_fs(get_ds());
-
- map_executable(file, elf_phdata, elf_ex.e_phnum, &elf_stack, &load_addr,
- &start_code, &elf_bss, &end_code, &end_data, &elf_brk);
+
+ map_executable(file, elf_phdata, elf_ex.e_phnum, &elf_stack,
+ &load_addr, &start_code, &elf_bss, &end_code,
+ &end_data, &elf_brk);
if(elf_interpreter) {
retval = map_interpreter(elf_phdata, &interp_elf_ex,
@@ -740,7 +746,7 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
}
set_fs(old_fs);
-
+
kfree(elf_phdata);
fput(file);
sys_close(elf_exec_fileno);
@@ -805,17 +811,20 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm,
if (current->flags & PF_PTRACED)
send_sig(SIGTRAP, current, 0);
return 0;
+out:
+ return retval;
-out_interp:
- if(elf_interpreter) {
- kfree(elf_interpreter);
- }
-out_file:
+out_free_dentry:
+ dput(interpreter_dentry);
+out_free_interp:
+ if (elf_interpreter)
+ kfree(elf_interpreter);
+out_free_file:
fput(file);
sys_close(elf_exec_fileno);
-out_phdata:
+out_free_ph:
kfree (elf_phdata);
- return retval;
+ goto out;
}
static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs)
@@ -1069,11 +1078,11 @@ struct memelfnote
static int notesize(struct memelfnote *en)
{
int sz;
-
+
sz = sizeof(struct elf_note);
sz += roundup(strlen(en->name), 4);
sz += roundup(en->datasz, 4);
-
+
return sz;
}
diff --git a/arch/mips/kernel/irixioctl.c b/arch/mips/kernel/irixioctl.c
index c05c6609a..10ca5b15e 100644
--- a/arch/mips/kernel/irixioctl.c
+++ b/arch/mips/kernel/irixioctl.c
@@ -1,4 +1,4 @@
-/* $Id: irixioctl.c,v 1.5 1999/02/01 01:28:55 ralf Exp $
+/* $Id: irixioctl.c,v 1.6 1999/02/06 05:12:56 adevries Exp $
* irixioctl.c: A fucking mess...
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -29,20 +29,21 @@ extern asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd,
unsigned long arg);
extern asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count);
extern void start_tty(struct tty_struct *tty);
-
static struct tty_struct *get_tty(int fd)
{
struct file *filp;
+ struct tty_struct *ttyp = NULL;
- if(!(filp = fcheck(fd)))
- return ((struct tty_struct *) 0);
- if(filp->private_data) {
- struct tty_struct *ttyp = (struct tty_struct *) filp->private_data;
+ read_lock(&current->files->file_lock);
+ filp = fcheck(fd);
+ if(filp && filp->private_data) {
+ ttyp = (struct tty_struct *) filp->private_data;
- if(ttyp->magic == TTY_MAGIC)
- return ttyp;
+ if(ttyp->magic != TTY_MAGIC)
+ ttyp =NULL;
}
- return ((struct tty_struct *) 0);
+ read_unlock(&current->files->file_lock);
+ return ttyp;
}
static struct tty_struct *get_real_tty(struct tty_struct *tp)
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 693d72110..7ec7b175c 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*
- * $Id: irixsig.c,v 1.10 1999/01/03 17:50:50 ralf Exp $
+ * $Id: irixsig.c,v 1.11 1999/06/17 13:25:46 ralf Exp $
*/
#include <linux/kernel.h>
@@ -114,17 +114,17 @@ static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
dump_irix5_sigctx(ctx);
#endif
- regs->regs[5] = 0; /* XXX sigcode XXX */
regs->regs[4] = (unsigned long) signr;
+ regs->regs[5] = 0; /* XXX sigcode XXX */
regs->regs[6] = regs->regs[29] = sp;
regs->regs[7] = (unsigned long) ka->sa.sa_handler;
- regs->regs[25] = regs->cp0_epc = current->tss.irix_trampoline;
+ regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa.sa_restorer;
return;
segv_and_exit:
- lock_kernel();
- do_exit(SIGSEGV);
- unlock_kernel();
+ if (signr == SIGSEGV)
+ ka->sa.sa_handler = SIG_DFL;
+ force_sig(SIGSEGV, current);
}
static void inline
@@ -300,11 +300,12 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
return 0;
}
-asmlinkage unsigned long irix_sigreturn(struct pt_regs *regs)
+asmlinkage void
+irix_sigreturn(struct pt_regs *regs)
{
struct sigctx_irix5 *context, *magic;
unsigned long umask, mask;
- u64 *fregs, res;
+ u64 *fregs;
int sig, i, base = 0;
sigset_t blocked;
@@ -365,11 +366,7 @@ asmlinkage unsigned long irix_sigreturn(struct pt_regs *regs)
/* Unreached */
badframe:
- lock_kernel();
- do_exit(SIGSEGV);
- unlock_kernel();
-
- return res;
+ force_sig(SIGSEGV, current);
}
struct sigact_irix5 {
@@ -390,7 +387,7 @@ static inline void dump_sigact_irix5(struct sigact_irix5 *p)
asmlinkage int
irix_sigaction(int sig, const struct sigaction *act,
- struct sigaction *oact, unsigned long trampoline)
+ struct sigaction *oact, void *trampoline)
{
struct k_sigaction new_ka, old_ka;
int ret;
@@ -410,15 +407,14 @@ irix_sigaction(int sig, const struct sigaction *act,
return -EFAULT;
__copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t));
- new_ka.ka_restorer = NULL;
- }
- /*
- * 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;
+ /*
+ * Hmmm... methinks IRIX libc always passes a valid trampoline
+ * value for all invocations of sigaction. Will have to
+ * investigate. POSIX POSIX, die die die...
+ */
+ new_ka.sa.sa_restorer = trampoline;
+ }
/* XXX Implement SIG_SETMASK32 for IRIX compatibility */
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 1b99fa99f..b083e3686 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.14 1999/02/15 02:16:50 ralf Exp $
+/* $Id: irq.c,v 1.15 1999/02/25 21:50:49 tsbogend Exp $
*
* 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
@@ -356,7 +356,7 @@ static int i8259_irq_cannonicalize(int irq)
return ((irq == 2) ? 9 : irq);
}
-__initfunc(static void i8259_init(void))
+static void __init i8259_init(void)
{
/* Init master interrupt controller */
outb(0x11, 0x20); /* Start init sequence */
@@ -376,7 +376,7 @@ __initfunc(static void i8259_init(void))
outb(cached_21, 0x21);
}
-__initfunc(void init_IRQ(void))
+void __init init_IRQ(void)
{
irq_cannonicalize = i8259_irq_cannonicalize;
/* i8259_init(); */
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index a8c59ff78..8e1afd78f 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.12 1999/06/17 13:25:46 ralf Exp $
+/* $Id: process.c,v 1.14 1999/08/09 19:43:14 harald Exp $
*
* 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
@@ -34,18 +34,6 @@ struct task_struct *last_task_used_math = NULL;
asmlinkage void ret_from_sys_call(void);
-/*
- * Do necessary setup to start up a newly executed thread.
- */
-void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
-{
- /* New thread looses kernel privileges. */
- regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|KU_MASK)) | KU_USER;
- regs->cp0_epc = pc;
- regs->regs[29] = sp;
- current->tss.current_ds = USER_DS;
-}
-
void exit_thread(void)
{
/* Forget lazy fpu state */
@@ -66,10 +54,6 @@ void flush_thread(void)
}
}
-void release_thread(struct task_struct *dead_task)
-{
-}
-
int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
struct task_struct * p, struct pt_regs * regs)
{
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index c8e3d23b6..68084ab3d 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -1,4 +1,4 @@
-/* $Id: ptrace.c,v 1.15 1999/08/09 19:43:14 harald Exp $
+/* $Id: ptrace.c,v 1.16 1999/08/18 23:37:43 ralf Exp $
*
* 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
@@ -25,218 +25,6 @@
#include <asm/system.h>
#include <asm/uaccess.h>
-/*
- * This routine gets a long from any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- */
-static unsigned long get_long(struct task_struct * tsk,
- struct vm_area_struct * vma, unsigned long addr)
-{
- pgd_t *pgdir;
- pmd_t *pgmiddle;
- pte_t *pgtable;
- unsigned long page, retval;
-
-repeat:
- pgdir = pgd_offset(vma->vm_mm, addr);
- if (pgd_none(*pgdir)) {
- handle_mm_fault(tsk, vma, addr, 0);
- goto repeat;
- }
- if (pgd_bad(*pgdir)) {
- printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
- pgd_clear(pgdir);
- return 0;
- }
- pgmiddle = pmd_offset(pgdir, addr);
- if (pmd_none(*pgmiddle)) {
- handle_mm_fault(tsk, vma, addr, 0);
- goto repeat;
- }
- if (pmd_bad(*pgmiddle)) {
- printk("ptrace: bad page middle %08lx\n", pmd_val(*pgmiddle));
- pmd_clear(pgmiddle);
- return 0;
- }
- pgtable = pte_offset(pgmiddle, addr);
- if (!pte_present(*pgtable)) {
- handle_mm_fault(tsk, vma, addr, 0);
- goto repeat;
- }
- page = pte_page(*pgtable);
- /* This is a hack for non-kernel-mapped video buffers and similar */
- if (MAP_NR(page) >= MAP_NR(high_memory))
- return 0;
- page += addr & ~PAGE_MASK;
- /* We can't use flush_page_to_ram() since we're running in
- * another context ...
- */
- flush_cache_all();
- retval = *(unsigned long *) page;
- flush_cache_all(); /* VCED avoidance */
- return retval;
-}
-
-/*
- * This routine puts a long into any process space by following the page
- * tables. NOTE! You should check that the long isn't on a page boundary,
- * and that it is in the task area before calling this: this routine does
- * no checking.
- *
- * Now keeps R/W state of page so that a text page stays readonly
- * even if a debugger scribbles breakpoints into it. -M.U-
- */
-static void put_long(struct task_struct *tsk,
- struct vm_area_struct * vma, unsigned long addr,
- unsigned long data)
-{
- pgd_t *pgdir;
- pmd_t *pgmiddle;
- pte_t *pgtable;
- unsigned long page;
-
-repeat:
- pgdir = pgd_offset(vma->vm_mm, addr);
- if (!pgd_present(*pgdir)) {
- handle_mm_fault(tsk, vma, addr, 1);
- goto repeat;
- }
- if (pgd_bad(*pgdir)) {
- printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
- pgd_clear(pgdir);
- return;
- }
- pgmiddle = pmd_offset(pgdir, addr);
- if (pmd_none(*pgmiddle)) {
- handle_mm_fault(tsk, vma, addr, 1);
- goto repeat;
- }
- if (pmd_bad(*pgmiddle)) {
- printk("ptrace: bad page middle %08lx\n", pmd_val(*pgmiddle));
- pmd_clear(pgmiddle);
- return;
- }
- pgtable = pte_offset(pgmiddle, addr);
- if (!pte_present(*pgtable)) {
- handle_mm_fault(tsk, vma, addr, 1);
- goto repeat;
- }
- page = pte_page(*pgtable);
- if (!pte_write(*pgtable)) {
- handle_mm_fault(tsk, vma, addr, 1);
- goto repeat;
- }
- /* This is a hack for non-kernel-mapped video buffers and similar */
- if (MAP_NR(page) < MAP_NR(high_memory))
- flush_cache_all();
- *(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
- if (MAP_NR(page) < MAP_NR(high_memory))
- flush_cache_all();
- /*
- * We're bypassing pagetables, so we have to set the dirty bit
- * ourselves this should also re-instate whatever read-only mode
- * there was before
- */
- set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
- flush_tlb_page(vma, addr);
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls get_long() to read a long.
- */
-static int read_long(struct task_struct * tsk, unsigned long addr,
- unsigned long * result)
-{
- struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
- if (!vma)
- return -EIO;
- if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
- unsigned long low,high;
- struct vm_area_struct * vma_high = vma;
-
- if (addr + sizeof(long) >= vma->vm_end) {
- vma_high = vma->vm_next;
- if (!vma_high || vma_high->vm_start != vma->vm_end)
- return -EIO;
- }
- low = get_long(tsk, vma, addr & ~(sizeof(long)-1));
- high = get_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1));
- switch (addr & (sizeof(long)-1)) {
- case 1:
- low >>= 8;
- low |= high << 24;
- break;
- case 2:
- low >>= 16;
- low |= high << 16;
- break;
- case 3:
- low >>= 24;
- low |= high << 8;
- break;
- }
- *result = low;
- } else
- *result = get_long(tsk, vma, addr);
- return 0;
-}
-
-/*
- * This routine checks the page boundaries, and that the offset is
- * within the task area. It then calls put_long() to write a long.
- */
-static int write_long(struct task_struct * tsk, unsigned long addr,
- unsigned long data)
-{
- struct vm_area_struct * vma = find_extend_vma(tsk, addr);
-
- if (!vma)
- return -EIO;
- if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
- unsigned long low,high;
- struct vm_area_struct * vma_high = vma;
-
- if (addr + sizeof(long) >= vma->vm_end) {
- vma_high = vma->vm_next;
- if (!vma_high || vma_high->vm_start != vma->vm_end)
- return -EIO;
- }
- low = get_long(tsk, vma, addr & ~(sizeof(long)-1));
- high = get_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1));
- switch (addr & (sizeof(long)-1)) {
- case 0: /* shouldn't happen, but safety first */
- low = data;
- break;
- case 1:
- low &= 0x000000ff;
- low |= data << 8;
- high &= ~0xff;
- high |= data >> 24;
- break;
- case 2:
- low &= 0x0000ffff;
- low |= data << 16;
- high &= ~0xffff;
- high |= data >> 16;
- break;
- case 3:
- low &= 0x00ffffff;
- low |= data << 24;
- high &= ~0xffffff;
- high |= data >> 8;
- break;
- }
- put_long(tsk, vma, addr & ~(sizeof(long)-1),low);
- put_long(tsk, vma_high, (addr+sizeof(long)) & ~(sizeof(long)-1),high);
- } else
- put_long(tsk, vma, addr, data);
- return 0;
-}
-
asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
@@ -323,15 +111,16 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_PEEKTEXT: /* read word at location addr. */
case PTRACE_PEEKDATA: {
unsigned long tmp;
+ int copied;
- down(&child->mm->mmap_sem);
- res = read_long(child, addr, &tmp);
- up(&child->mm->mmap_sem);
- if (res < 0)
+ copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+ res = -EIO;
+ if (copied != sizeof(tmp))
goto out;
res = put_user(tmp,(unsigned long *) data);
+
goto out;
- }
+ }
/* Read the word at location addr in the USER area. */
case PTRACE_PEEKUSR: {
@@ -397,9 +186,11 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_POKETEXT: /* write the word at location addr. */
case PTRACE_POKEDATA:
- down(&child->mm->mmap_sem);
- res = write_long(child,addr,data);
- up(&child->mm->mmap_sem);
+ res = 0;
+ if (access_process_vm(child, addr, &data, sizeof(data), 1)
+ == sizeof(data))
+ goto out;
+ res = -EIO;
goto out;
case PTRACE_POKEUSR: {
diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S
index 74671f58c..efb00dce1 100644
--- a/arch/mips/kernel/r2300_fpu.S
+++ b/arch/mips/kernel/r2300_fpu.S
@@ -1,4 +1,5 @@
-/* $Id: r2300_fpu.S,v 1.5 1999/05/01 22:40:36 ralf Exp $
+/* $Id: r2300_fpu.S,v 1.6 1999/08/09 19:43:14 harald Exp $
+ *
* r2300_fpu.S: Save/restore floating point context for signal handlers.
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -14,6 +15,7 @@
* Copyright (c) 1998 Harald Koerfgen
*/
#include <asm/asm.h>
+#include <asm/errno.h>
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
#include <asm/offset.h>
@@ -29,7 +31,7 @@
.set mips1
/* Save floating point context */
LEAF(save_fp_context)
-
+ li v0, 0 # assume success
cfc1 t1,fcr31
EX(swc1 $f0,(SC_FPREGS+0)(a0))
EX(swc1 $f1,(SC_FPREGS+8)(a0))
@@ -81,6 +83,7 @@ LEAF(save_fp_context)
* stack frame which might have been changed by the user.
*/
LEAF(restore_fp_context)
+ li v0, 0 # assume success
EX(lw t0,SC_FPC_CSR(a0))
EX(lwc1 $f0,(SC_FPREGS+0)(a0))
EX(lwc1 $f1,(SC_FPREGS+8)(a0))
@@ -117,3 +120,9 @@ LEAF(restore_fp_context)
jr ra
ctc1 t0,fcr31
END(restore_fp_context)
+
+ .type fault@function
+ .ent fault
+fault: li v0, -EFAULT
+ jr ra
+ .end fault
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index 39ec93b57..4624416e7 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -1,4 +1,5 @@
-/*
+/* $Id: r4k_fpu.S,v 1.7 1999/08/18 23:37:44 ralf Exp $
+ *
* r4k_fpu.S: Save/restore floating point context for signal handlers.
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -9,10 +10,9 @@
*
* Multi-arch abstraction and asm macros for easier reading:
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: r4k_fpu.S,v 1.6 1999/08/09 19:43:15 harald Exp $
*/
#include <asm/asm.h>
+#include <asm/errno.h>
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
#include <asm/offset.h>
@@ -21,13 +21,14 @@
#define EX(a,b) \
9: a,##b; \
.section __ex_table,"a"; \
- PTR 9b,bad_stack; \
+ PTR 9b, fault; \
.previous
.set noreorder
.set mips3
/* Save floating point context */
LEAF(save_fp_context)
+ li v0, 0 # assume success
cfc1 t1,fcr31
/* Store the 16 even double precision registers */
@@ -67,6 +68,7 @@ LEAF(save_fp_context)
* stack frame which might have been changed by the user.
*/
LEAF(restore_fp_context)
+ li v0, 0 # assume success
EX(lw t0,SC_FPC_CSR(a0))
/*
@@ -92,3 +94,9 @@ LEAF(restore_fp_context)
jr ra
ctc1 t0,fcr31
END(restore_fp_context)
+
+ .type fault@function
+ .ent fault
+fault: li v0, -EFAULT
+ jr ra
+ .end fault
diff --git a/arch/mips/kernel/r4k_misc.S b/arch/mips/kernel/r4k_misc.S
index c791f3275..d83f85b81 100644
--- a/arch/mips/kernel/r4k_misc.S
+++ b/arch/mips/kernel/r4k_misc.S
@@ -1,19 +1,17 @@
-/*
+/* $Id: r4k_misc.S,v 1.6 1999/08/18 23:37:44 ralf Exp $
+ *
* r4k_misc.S: Misc. exception handling code for r4k.
*
* Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
*
* Multi-cpu abstraction and reworking:
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
- *
- * $Id: r4k_misc.S,v 1.5 1999/08/09 19:43:15 harald Exp $
*/
#include <asm/asm.h>
#include <asm/current.h>
#include <asm/offset.h>
#include <asm/bootinfo.h>
#include <asm/cachectl.h>
-#include <asm/current.h>
#include <asm/fpregdef.h>
#include <asm/mipsregs.h>
#include <asm/page.h>
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index b8a2b4303..fd6650b1c 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.17 1999/08/20 21:59:02 ralf Exp $
+/* $Id: setup.c,v 1.18 1999/09/18 20:48:03 harald Exp $
*
* 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
@@ -30,7 +30,6 @@
#endif
#include <linux/ide.h>
#ifdef CONFIG_RTC
-#include <linux/ioport.h>
#include <linux/timex.h>
#endif
@@ -67,15 +66,6 @@ char cyclecounter_available;
*/
int EISA_bus = 0;
-/*
- * Milo passes some information to the kernel that looks like as if it
- * had been returned by a Intel PC BIOS. Milo doesn't fill the passed
- * drive_info and Linux can find out about this anyway, so I'm going to
- * remove this sometime. screen_info contains information about the
- * resolution of the text screen. For VGA graphics based machine this
- * information is being use to continue the screen output just below
- * the BIOS printed text and with the same text resolution.
- */
struct screen_info screen_info;
#ifdef CONFIG_BLK_DEV_FD
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 6c63bea25..0a7190412 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -1,11 +1,12 @@
-/* $Id: signal.c,v 1.20 1999/08/09 19:43:15 harald Exp $
+/* $Id: signal.c,v 1.21 1999/08/24 22:54:21 ralf Exp $
*
- * linux/arch/mips/kernel/signal.c
+ * 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.
*
- * Copyright (C) 1991, 1992 Linus Torvalds
- * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle
- *
- * XXX Handle lazy fp context switches correctly.
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ * Copyright (C) 1994 - 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
*/
#include <linux/config.h>
#include <linux/sched.h>
@@ -24,16 +25,17 @@
#include <asm/pgtable.h>
#include <asm/stackframe.h>
#include <asm/uaccess.h>
+#include <asm/ucontext.h>
#define DEBUG_SIG 0
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
+extern asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr,
int options, unsigned long *ru);
-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);
+extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+extern asmlinkage int save_fp_context(struct sigcontext *sc);
+extern asmlinkage int restore_fp_context(struct sigcontext *sc);
/*
* Atomically swap in the new signal mask, and wait for a signal.
@@ -52,6 +54,7 @@ sys_sigsuspend(struct pt_regs regs)
spin_lock_irq(&current->sigmask_lock);
saveset = current->blocked;
current->blocked = newset;
+ recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
regs.regs[2] = EINTR;
@@ -67,17 +70,25 @@ sys_sigsuspend(struct pt_regs regs)
asmlinkage int
sys_rt_sigsuspend(struct pt_regs regs)
{
- sigset_t *uset, saveset, newset;
+ sigset_t *unewset, saveset, newset;
+ size_t sigsetsize;
save_static(&regs);
- uset = (sigset_t *) regs.regs[4];
- if (copy_from_user(&newset, uset, sizeof(sigset_t)))
+
+ /* XXX Don't preclude handling different sized sigset_t's. */
+ sigsetsize = regs.regs[5];
+ if (sigsetsize != sizeof(sigset_t))
+ return -EINVAL;
+
+ unewset = (sigset_t *) regs.regs[4];
+ 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.regs[2] = EINTR;
@@ -91,65 +102,74 @@ sys_rt_sigsuspend(struct pt_regs regs)
}
asmlinkage int
-sys_sigaction(int sig, const struct sigaction *act,
- struct sigaction *oact)
+sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
struct k_sigaction new_ka, old_ka;
int ret;
+ int err = 0;
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))
+ old_sigset_t mask;
+
+ if (!access_ok(VERIFY_READ, act, sizeof(*act)))
+ return -EFAULT;
+ err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler);
+ err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+ err |= __get_user(mask, &act->sa_mask.sig[0]);
+ err |= __get_user(new_ka.sa.sa_restorer, &act->sa_restorer);
+ if (err)
return -EFAULT;
- __copy_from_user(&mask, &act->sa_mask, sizeof(sigset_t));
- new_ka.ka_restorer = NULL;
+ 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_flags, &oact->sa_flags))
+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
+ return -EFAULT;
+ err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+ err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
+ err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
+ err |= __put_user(0, &oact->sa_mask.sig[1]);
+ err |= __put_user(0, &oact->sa_mask.sig[2]);
+ err |= __put_user(0, &oact->sa_mask.sig[3]);
+ err |= __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer);
+ if (err)
return -EFAULT;
- __copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask,
- sizeof(sigset_t));
}
return ret;
}
asmlinkage int
-sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+sys_sigaltstack(struct pt_regs regs)
{
- struct pt_regs *regs = (struct pt_regs *) &uss;
+ const stack_t *uss = (const stack_t *) regs.regs[4];
+ stack_t *uoss = (stack_t *) regs.regs[5];
+ unsigned long usp = regs.regs[29];
- return do_sigaltstack(uss, uoss, regs->regs[29]);
+ return do_sigaltstack(uss, uoss, usp);
}
-/*
- * 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)
+asmlinkage int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
{
- long long reg;
int owned_fp;
+ int err = 0;
+ u64 reg;
- __get_user(regs->cp0_epc, &context->sc_pc);
+ err |= __get_user(regs->cp0_epc, &sc->sc_pc);
- __get_user(reg, &context->sc_mdhi);
+ err |= __get_user(reg, &sc->sc_mdhi);
regs->hi = (int) reg;
- __get_user(reg, &context->sc_mdlo);
+ err |= __get_user(reg, &sc->sc_mdlo);
regs->lo = (int) reg;
-#define restore_gp_reg(i) __get_user(reg, &context->sc_regs[i]); \
- regs->regs[i] = (int) reg;
+#define restore_gp_reg(i) do { \
+ err |= __get_user(reg, &sc->sc_regs[i]); \
+ regs->regs[i] = reg; \
+} while(0);
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);
@@ -163,55 +183,40 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *context)
restore_gp_reg(31);
#undef restore_gp_reg
- /* FP depends on what FPU in what mode we have. */
- __get_user(owned_fp, &context->sc_ownedfp);
-#if 0
+ err |= __get_user(owned_fp, &sc->sc_ownedfp);
if (owned_fp) {
- restore_fp_context(context);
+ err |= restore_fp_context(sc);
last_task_used_math = current;
}
-#endif
-restore_fp_context(context);
+
+ return err;
}
-/*
- * 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;
+ u32 sf_ass[4]; /* argument save space for o32 */
+ u32 sf_code[2]; /* signal trampoline */
+ struct sigcontext sf_sc;
+ sigset_t sf_mask;
};
struct rt_sigframe {
- unsigned long ass[4];
- unsigned int code[4];
- struct sigcontext scc;
- // struct ucontext uc;
+ u32 rs_ass[4]; /* argument save space for o32 */
+ u32 rs_code[2]; /* signal trampoline */
+ struct siginfo rs_info;
+ struct ucontext rs_uc;
};
-asmlinkage int sys_sigreturn(struct pt_regs regs)
+asmlinkage void
+sys_sigreturn(struct pt_regs regs)
{
- struct sigcontext *context;
+ struct sigframe *frame;
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 1
- if (__get_user(blocked.sig[0], &context->sc_sigset[0]) ||
- __get_user(blocked.sig[1], &context->sc_sigset[1]) ||
- __get_user(blocked.sig[2], &context->sc_sigset[2]) ||
- __get_user(blocked.sig[3], &context->sc_sigset[3]))
+ frame = (struct sigframe *) regs.regs[29];
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
-#else
- if (__copy_from_user(&blocked, &context->sc_sigset, sizeof(blocked)))
+ if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
goto badframe;
-#endif
sigdelsetmask(&blocked, ~_BLOCKABLE);
spin_lock_irq(&current->sigmask_lock);
@@ -219,63 +224,79 @@ asmlinkage int sys_sigreturn(struct pt_regs regs)
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
- restore_sigcontext(&regs, context);
+ if (restore_sigcontext(&regs, &frame->sf_sc))
+ goto badframe;
/*
* Don't let your children do this ...
*/
__asm__ __volatile__(
- "move\t$29,%0\n\t"
+ "move\t$29, %0\n\t"
"j\tret_from_sys_call"
:/* no outputs */
:"r" (&regs));
/* Unreached */
badframe:
- lock_kernel();
- do_exit(SIGSEGV);
- unlock_kernel();
+ force_sig(SIGSEGV, current);
}
-/* same as sys_sigreturn for now */
-asmlinkage int sys_rt_sigreturn(struct pt_regs regs)
+asmlinkage void
+sys_rt_sigreturn(struct pt_regs regs)
{
- return -ENOSYS;
-}
+ struct rt_sigframe *frame;
+ sigset_t set;
+ stack_t st;
-#define scc_offset ((size_t)&((struct sigframe *)0)->scc)
+ frame = (struct rt_sigframe *) regs.regs[29];
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
+ goto badframe;
-/*
- * Set up the return code ...
- *
- * .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);
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sigmask_lock);
+ current->blocked = set;
+ recalc_sigpending(current);
+ spin_unlock_irq(&current->sigmask_lock);
+
+ if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
+ goto badframe;
+
+ if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
+ goto badframe;
+ /* It is more difficult to avoid calling this function than to
+ call it and ignore errors. */
+ do_sigaltstack(&st, NULL, regs.regs[29]);
/*
- * Flush caches so that the instructions will be correctly executed.
+ * Don't let your children do this ...
*/
- flush_cache_sigtramp((unsigned long) code);
+ __asm__ __volatile__(
+ "move\t$29, %0\n\t"
+ "j\tret_from_sys_call"
+ :/* no outputs */
+ :"r" (&regs));
+ /* Unreached */
+
+badframe:
+ force_sig(SIGSEGV, current);
}
-static void inline
-setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc, sigset_t *set)
+static int inline
+setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
{
int owned_fp;
+ int err = 0;
+ u64 reg;
- __put_user(regs->cp0_epc, &sc->sc_pc);
- __put_user(regs->cp0_status, &sc->sc_status); /* Status register */
+ err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+ err |= __put_user(regs->cp0_status, &sc->sc_status);
-#define save_gp_reg(i) __put_user(regs->regs[(i)], &sc->sc_regs[(i)])
+#define save_gp_reg(i) { \
+ reg = regs->regs[i]; \
+ err |= __put_user(reg, &sc->sc_regs[i]); \
+} while(0)
__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);
@@ -287,57 +308,93 @@ setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc, sigset_t *set)
save_gp_reg(31);
#undef save_gp_reg
- __put_user(regs->hi, &sc->sc_mdhi);
- __put_user(regs->lo, &sc->sc_mdlo);
- __put_user(regs->cp0_cause, &sc->sc_cause);
+ err |= __put_user(regs->hi, &sc->sc_mdhi);
+ err |= __put_user(regs->lo, &sc->sc_mdlo);
+ err |= __put_user(regs->cp0_cause, &sc->sc_cause);
+ err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
owned_fp = (current == last_task_used_math);
- __put_user(owned_fp, &sc->sc_ownedfp);
+ err |= __put_user(owned_fp, &sc->sc_ownedfp);
-#if 0
if (current->used_math) { /* fp is active. */
set_cp0_status(ST0_CU1, ST0_CU1);
- save_fp_context(sc); /* CPU-dependent */
+ err |= save_fp_context(sc);
last_task_used_math = NULL;
regs->cp0_status &= ~ST0_CU1;
current->used_math = 0;
}
-#endif
-set_cp0_status(ST0_CU1, ST0_CU1);
-save_fp_context(sc); /* CPU-dependent */
- __put_user(set->sig[0], &sc->sc_sigset[0]);
- __put_user(set->sig[1], &sc->sc_sigset[1]);
- __put_user(set->sig[2], &sc->sc_sigset[2]);
- __put_user(set->sig[3], &sc->sc_sigset[3]);
+ return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+ unsigned long sp;
+
+ /* Default to using normal stack */
+ sp = regs->regs[29];
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
+ sp = current->sas_ss_sp + current->sas_ss_size;
+
+ return (void *)((sp - frame_size) & ALMASK);
}
static void inline
setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
- int signr, sigset_t *oldmask)
+ int signr, sigset_t *set)
{
struct sigframe *frame;
- struct sigcontext *sc;
-
- /* Align the stackframe to an adequate boundary for the architecture. */
- frame = (struct sigframe *) (long) regs->regs[29];
- frame--;
- frame = (struct sigframe *)((unsigned long)frame & ALMASK);
-
- if (verify_area(VERIFY_WRITE, frame, sizeof (*frame)))
- goto segv_and_exit;
- sc = &frame->scc;
+ int err = 0;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+ goto give_sigsegv;
+
+ /* Set up to return from userspace. If provided, use a stub already
+ in userspace. */
+ if (ka->sa.sa_flags & SA_RESTORER)
+ regs->regs[31] = (unsigned long) ka->sa.sa_restorer;
+ else {
+ /*
+ * Set up the return code ...
+ *
+ * li v0, __NR_sigreturn
+ * syscall
+ */
+ err |= __put_user(0x24020000 + __NR_sigreturn,
+ frame->sf_code + 0);
+ err |= __put_user(0x0000000c ,
+ frame->sf_code + 1);
+ flush_cache_sigtramp((unsigned long) frame->sf_code);
+ }
- setup_trampoline(frame->code);
- setup_sigcontext(regs, &frame->scc, oldmask);
+ err |= setup_sigcontext(regs, &frame->sf_sc);
+ err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
+ if (err)
+ goto give_sigsegv;
- 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... */
+ /*
+ * Arguments to signal handler:
+ *
+ * a0 = signal number
+ * a1 = 0 (should be cause)
+ * a2 = pointer to struct sigcontext
+ *
+ * $25 and c0_epc point to the signal handler, $29 points to the
+ * struct sigframe.
+ */
+ regs->regs[ 4] = signr;
+ regs->regs[ 5] = 0;
+ regs->regs[ 6] = (unsigned long) &frame->sf_sc;
+ regs->regs[29] = (unsigned long) frame;
+ regs->regs[31] = (unsigned long) frame->sf_code;
+ regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
#if DEBUG_SIG
printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
@@ -345,22 +402,90 @@ setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
#endif
return;
-segv_and_exit:
- lock_kernel();
- do_exit(SIGSEGV);
- unlock_kernel();
+give_sigsegv:
+ if (signr == SIGSEGV)
+ ka->sa.sa_handler = SIG_DFL;
+ force_sig(SIGSEGV, current);
}
static void inline
setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
- int signr, sigset_t *oldmask, siginfo_t *info)
+ int signr, sigset_t *set, siginfo_t *info)
{
- printk("Aiee: setup_tr_frame wants to be written");
-}
+ struct rt_sigframe *frame;
+ int err = 0;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+ if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
+ goto give_sigsegv;
+
+ /* Set up to return from userspace. If provided, use a stub already
+ in userspace. */
+ if (ka->sa.sa_flags & SA_RESTORER)
+ regs->regs[31] = (unsigned long) ka->sa.sa_restorer;
+ else {
+ /*
+ * Set up the return code ...
+ *
+ * li v0, __NR_sigreturn
+ * syscall
+ */
+ err |= __put_user(0x24020000 + __NR_sigreturn,
+ frame->rs_code + 0);
+ err |= __put_user(0x0000000c ,
+ frame->rs_code + 1);
+ flush_cache_sigtramp((unsigned long) frame->rs_code);
+ }
-/* ------------------------------------------------------------------------- */
+ /* Create siginfo. */
+ err |= __copy_to_user(&frame->rs_info, info, sizeof(*info));
-static inline void handle_signal(unsigned long sig, struct k_sigaction *ka,
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->rs_uc.uc_flags);
+ err |= __put_user(0, &frame->rs_uc.uc_link);
+ err |= __put_user((void *)current->sas_ss_sp,
+ &frame->rs_uc.uc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(regs->regs[29]),
+ &frame->rs_uc.uc_stack.ss_flags);
+ err |= __put_user(current->sas_ss_size,
+ &frame->rs_uc.uc_stack.ss_size);
+ err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
+ err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
+
+ if (err)
+ goto give_sigsegv;
+
+ /*
+ * Arguments to signal handler:
+ *
+ * a0 = signal number
+ * a1 = 0 (should be cause)
+ * a2 = pointer to ucontext
+ *
+ * $25 and c0_epc point to the signal handler, $29 points to
+ * the struct rt_sigframe.
+ */
+ regs->regs[ 4] = signr;
+ regs->regs[ 5] = (unsigned long) &frame->rs_info;
+ regs->regs[ 6] = (unsigned long) &frame->rs_uc;
+ regs->regs[29] = (unsigned long) frame;
+ regs->regs[31] = (unsigned long) frame->rs_code;
+ regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+
+#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;
+
+give_sigsegv:
+ if (signr == SIGSEGV)
+ ka->sa.sa_handler = SIG_DFL;
+ force_sig(SIGSEGV, current);
+}
+
+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)
@@ -379,7 +504,8 @@ static inline void handle_signal(unsigned long sig, struct k_sigaction *ka,
}
}
-static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
+static inline void
+syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
{
switch(regs->regs[0]) {
case ERESTARTNOHAND:
@@ -407,7 +533,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
siginfo_t info;
#ifdef CONFIG_BINFMT_IRIX
- if (current->personality != PER_LINUX) /* XXX */
+ if (current->personality != PER_LINUX)
return do_irix_signal(oldset, regs);
#endif
@@ -533,13 +659,3 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
}
return 0;
}
-
-/*
- * Compatibility syscall. Can be replaced in libc.
- */
-asmlinkage int sys_pause(void)
-{
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- return -ERESTARTNOHAND;
-}
diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h
index 07a49ee8b..ef593845e 100644
--- a/arch/mips/kernel/syscalls.h
+++ b/arch/mips/kernel/syscalls.h
@@ -1,4 +1,4 @@
-/* $Id: syscalls.h,v 1.15 1998/09/19 19:16:17 ralf Exp $
+/* $Id: syscalls.h,v 1.16 1999/07/11 23:56:29 ralf Exp $
*
* 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
@@ -44,7 +44,7 @@ SYS(sys_stime, 1) /* 4025 */
SYS(sys_ptrace, 4)
SYS(sys_alarm, 1)
SYS(sys_fstat, 2)
-SYS(sys_pause, 0)
+SYS(sys_ni_syscall, 0)
SYS(sys_utime, 2) /* 4030 */
SYS(sys_ni_syscall, 0)
SYS(sys_ni_syscall, 0)
@@ -214,14 +214,14 @@ 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_rt_sigsuspend, 0)
SYS(sys_pread, 6) /* 4200 */
SYS(sys_pwrite, 6)
SYS(sys_chown, 3)
SYS(sys_getcwd, 2)
SYS(sys_capget, 2)
SYS(sys_capset, 2) /* 4205 */
-SYS(sys_sigaltstack, 2)
+SYS(sys_sigaltstack, 0)
SYS(sys_sendfile, 3)
SYS(sys_ni_syscall, 0)
SYS(sys_ni_syscall, 0)
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index cacb97115..f7cbbfc71 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.10 1999/08/09 19:43:16 harald Exp $
+/* $Id: fault.c,v 1.11 1999/08/18 23:37:45 ralf Exp $
*
* 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
@@ -43,7 +43,7 @@ unsigned long asid_cache = ASID_FIRST_VERSION;
* and the problem, and then passes it off to one of the appropriate
* routines.
*/
-asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
unsigned long address)
{
struct vm_area_struct * vma;
@@ -59,7 +59,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
goto no_context;
#if 0
printk("[%s:%d:%08lx:%ld:%08lx]\n", current->comm, current->pid,
- address, writeaccess, regs->cp0_epc);
+ address, write, regs->cp0_epc);
#endif
down(&mm->mmap_sem);
vma = find_vma(mm, address);
@@ -76,7 +76,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
* we can handle it..
*/
good_area:
- if (writeaccess) {
+ if (write) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
} else {
@@ -89,8 +89,13 @@ good_area:
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
- if (!handle_mm_fault(tsk, vma, address, writeaccess))
- goto do_sigbus;
+ {
+ int fault = handle_mm_fault(tsk, vma, address, write);
+ if (fault < 0)
+ goto out_of_memory;
+ if (!fault)
+ goto do_sigbus;
+ }
up(&mm->mmap_sem);
return;
@@ -104,12 +109,12 @@ bad_area:
if (user_mode(regs)) {
tsk->tss.cp0_badvaddr = address;
- tsk->tss.error_code = writeaccess;
+ tsk->tss.error_code = write;
#if 0
printk("do_page_fault() #2: sending SIGSEGV to %s for illegal %s\n"
"%08lx (epc == %08lx, ra == %08lx)\n",
tsk->comm,
- writeaccess ? "writeaccess to" : "readaccess from",
+ write ? "write access to" : "read access from",
address,
(unsigned long) regs->cp0_epc,
(unsigned long) regs->regs[31]);
@@ -140,13 +145,20 @@ no_context:
printk(KERN_ALERT "Unable to handle kernel paging request at virtual "
"address %08lx, epc == %08lx, ra == %08lx\n",
address, regs->cp0_epc, regs->regs[31]);
- die("Oops", regs, writeaccess);
+ die("Oops", regs, write);
do_exit(SIGKILL);
/*
* We ran out of memory, or some other thing happened to us that made
* us unable to handle the page fault gracefully.
*/
+out_of_memory:
+ up(&mm->mmap_sem);
+ printk("VM: killing process %s\n", tsk->comm);
+ if (user_mode(regs))
+ do_exit(SIGKILL);
+ goto no_context;
+
do_sigbus:
up(&mm->mmap_sem);
diff --git a/arch/mips/mm/r4xx0.c b/arch/mips/mm/r4xx0.c
index be843351e..e1c3251f8 100644
--- a/arch/mips/mm/r4xx0.c
+++ b/arch/mips/mm/r4xx0.c
@@ -1,4 +1,4 @@
-/* $Id: r4xx0.c,v 1.22 1999/06/17 13:25:51 ralf Exp $
+/* $Id: r4xx0.c,v 1.23 1999/08/09 19:43:16 harald Exp $
*
* 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
@@ -2202,7 +2202,7 @@ static void r4600v20k_flush_cache_sigtramp(unsigned long addr)
unsigned int flags;
daddr = addr & ~(dc_lsize - 1);
- save_and_cli(flags);
+ __save_and_cli(flags);
/* Clear internal cache refill buffer */
*(volatile unsigned int *)KSEG1;
@@ -2212,7 +2212,7 @@ static void r4600v20k_flush_cache_sigtramp(unsigned long addr)
iaddr = addr & ~(ic_lsize - 1);
protected_flush_icache_line(iaddr);
protected_flush_icache_line(iaddr + ic_lsize);
- restore_flags(flags);
+ __restore_flags(flags);
}
#undef DEBUG_TLB
diff --git a/arch/mips/sgi/kernel/indy_sc.c b/arch/mips/sgi/kernel/indy_sc.c
index 2aff56637..1fecee23f 100644
--- a/arch/mips/sgi/kernel/indy_sc.c
+++ b/arch/mips/sgi/kernel/indy_sc.c
@@ -1,4 +1,4 @@
-/* $Id: indy_sc.c,v 1.8 1999/05/10 17:40:16 ulfc Exp $
+/* $Id: indy_sc.c,v 1.9 1999/05/12 21:57:49 ulfc Exp $
*
* indy_sc.c: Indy cache managment functions.
*
@@ -9,7 +9,6 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
-#include <linux/autoconf.h>
#include <asm/bcache.h>
#include <asm/sgi.h>
diff --git a/arch/mips/tools/offset.c b/arch/mips/tools/offset.c
index f32f3e76e..ede1d5f93 100644
--- a/arch/mips/tools/offset.c
+++ b/arch/mips/tools/offset.c
@@ -1,9 +1,10 @@
-/* $Id: offset.c,v 1.9 1998/08/25 09:14:52 ralf Exp $
+/* $Id: offset.c,v 1.10 1999/08/18 23:37:46 ralf Exp $
*
* offset.c: Calculate pt_regs and task_struct offsets.
*
* Copyright (C) 1996 David S. Miller
- * Made portable by Ralf Baechle
+ * Copyright (C) 1997, 1998, 1999 Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
*/
#include <linux/types.h>
@@ -126,20 +127,17 @@ void output_mm_defines(void)
void output_sc_defines(void)
{
text("/* Linux sigcontext offsets. */");
- offset("#define SC_REGMASK ", struct sigcontext, sc_regmask);
- offset("#define SC_STATUS ", struct sigcontext, sc_status);
- offset("#define SC_PC ", struct sigcontext, sc_pc);
offset("#define SC_REGS ", struct sigcontext, sc_regs);
offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs);
+ offset("#define SC_MDHI ", struct sigcontext, sc_mdhi);
+ offset("#define SC_MDLO ", struct sigcontext, sc_mdlo);
+ offset("#define SC_PC ", struct sigcontext, sc_pc);
+ offset("#define SC_STATUS ", struct sigcontext, sc_status);
offset("#define SC_OWNEDFP ", struct sigcontext, sc_ownedfp);
offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr);
offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir);
- offset("#define SC_SSFLAGS ", struct sigcontext, sc_ssflags);
- offset("#define SC_MDHI ", struct sigcontext, sc_mdhi);
- offset("#define SC_MDLO ", struct sigcontext, sc_mdlo);
offset("#define SC_CAUSE ", struct sigcontext, sc_cause);
offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr);
- offset("#define SC_SIGSET ", struct sigcontext, sc_sigset);
linefeed;
}