diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-07-20 14:56:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-07-20 14:56:40 +0000 |
commit | e308faf24f68e262d92d294a01ddca7a17e76762 (patch) | |
tree | 22c47cb315811834861f013067878ff664e95abd /arch/alpha | |
parent | 30c6397ce63178fcb3e7963ac247f0a03132aca9 (diff) |
Sync with Linux 2.1.46.
Diffstat (limited to 'arch/alpha')
-rw-r--r-- | arch/alpha/defconfig | 8 | ||||
-rw-r--r-- | arch/alpha/kernel/osf_sys.c | 190 | ||||
-rw-r--r-- | arch/alpha/kernel/process.c | 5 | ||||
-rw-r--r-- | arch/alpha/kernel/traps.c | 20 | ||||
-rw-r--r-- | arch/alpha/mm/fault.c | 20 |
5 files changed, 138 insertions, 105 deletions
diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig index 0c3c65d28..a36ec98a9 100644 --- a/arch/alpha/defconfig +++ b/arch/alpha/defconfig @@ -66,7 +66,7 @@ CONFIG_BLK_DEV_FD=y # # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_MD is not set -CONFIG_BLK_DEV_RAM=y +# CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_BLK_DEV_EZ is not set @@ -83,6 +83,7 @@ CONFIG_INET=y # CONFIG_IP_ACCT is not set # CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set +# CONFIG_SYN_COOKIES is not set # # (it is safe to leave these untouched) @@ -196,8 +197,8 @@ CONFIG_DE4X5=y # CONFIG_QUOTA is not set # CONFIG_MINIX_FS is not set CONFIG_EXT2_FS=y -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_UMSDOS_FS is not set CONFIG_PROC_FS=y @@ -245,3 +246,4 @@ CONFIG_PSMOUSE=y # Kernel hacking # # CONFIG_PROFILE is not set +# CONFIG_MAGIC_SYSRQ is not set diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 3b3d8574b..f725e2aba 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -135,30 +135,46 @@ asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent *dirent, { int error; struct file *file; + struct dentry *dentry; + struct inode *inode; struct osf_dirent_callback buf; - if (fd >= NR_OPEN || !(file = current->files->fd[fd])) - return -EBADF; - if (!file->f_op || !file->f_op->readdir) - return -ENOTDIR; - error = verify_area(VERIFY_WRITE, dirent, count); - if (error) - return error; - if (basep) { - error = verify_area(VERIFY_WRITE, basep, sizeof(long)); - if (error) - return error; - } + error = -EBADF; + if (fd >= NR_OPEN) + goto out; + + file = current->files->fd[fd]; + if (!file) + goto out; + + dentry = file->f_dentry; + if (!dentry) + goto out; + + inode = dentry->d_inode; + if (!inode) + goto out; + buf.dirent = dirent; buf.basep = basep; buf.count = count; buf.error = 0; - error = file->f_op->readdir(file->f_inode, file, &buf, osf_filldir); + + error = -ENOTDIR; + if (!file->f_op || !file->f_op->readdir) + goto out; + + error = file->f_op->readdir(inode, file, &buf, osf_filldir); if (error < 0) - return error; + goto out; + + error = buf.error; if (count == buf.count) - return buf.error; - return count - buf.count; + goto out; + + error = count - buf.count; +out: + return error; } /* @@ -267,76 +283,73 @@ struct osf_statfs { __kernel_fsid_t f_fsid; } *osf_stat; -static void linux_to_osf_statfs(struct statfs *linux_stat, struct osf_statfs *osf_stat) +static int linux_to_osf_statfs(struct statfs *linux_stat, struct osf_statfs *osf_stat, unsigned long bufsiz) { - osf_stat->f_type = linux_stat->f_type; - osf_stat->f_flags = 0; /* mount flags */ + struct osf_statfs tmp_stat; + + tmp_stat.f_type = linux_stat->f_type; + tmp_stat.f_flags = 0; /* mount flags */ /* Linux doesn't provide a "fundamental filesystem block size": */ - osf_stat->f_fsize = linux_stat->f_bsize; - osf_stat->f_bsize = linux_stat->f_bsize; - osf_stat->f_blocks = linux_stat->f_blocks; - osf_stat->f_bfree = linux_stat->f_bfree; - osf_stat->f_bavail = linux_stat->f_bavail; - osf_stat->f_files = linux_stat->f_files; - osf_stat->f_ffree = linux_stat->f_ffree; - osf_stat->f_fsid = linux_stat->f_fsid; + tmp_stat.f_fsize = linux_stat->f_bsize; + tmp_stat.f_bsize = linux_stat->f_bsize; + tmp_stat.f_blocks = linux_stat->f_blocks; + tmp_stat.f_bfree = linux_stat->f_bfree; + tmp_stat.f_bavail = linux_stat->f_bavail; + tmp_stat.f_files = linux_stat->f_files; + tmp_stat.f_ffree = linux_stat->f_ffree; + tmp_stat.f_fsid = linux_stat->f_fsid; + if (bufsiz > sizeof(tmp_stat)) + bufsiz = sizeof(tmp_stat); + return copy_to_user(osf_stat, &tmp_stat, bufsiz) ? -EFAULT : 0; } +static int do_osf_statfs(struct dentry * dentry, struct osf_statfs *buffer, unsigned long bufsiz) +{ + struct statfs linux_stat; + struct inode * inode = dentry->d_inode; + struct super_block * sb = inode->i_sb; + int error; + + error = -ENOSYS; + if (sb->s_op->statfs) { + set_fs(KERNEL_DS); + error = sb->s_op->statfs(sb, &linux_stat, sizeof(linux_stat)); + set_fs(USER_DS); + if (!error) + error = linux_to_osf_statfs(&linux_stat, buffer, bufsiz); + } + return error; +} asmlinkage int osf_statfs(char *path, struct osf_statfs *buffer, unsigned long bufsiz) { - struct statfs linux_stat; - struct inode *inode; + struct dentry *dentry; int retval; lock_kernel(); - if (bufsiz > sizeof(struct osf_statfs)) - bufsiz = sizeof(struct osf_statfs); - retval = verify_area(VERIFY_WRITE, buffer, bufsiz); - if (retval) - goto out; - retval = namei(NAM_FOLLOW_LINK, path, &inode); - if (retval) - goto out; - retval = -ENOSYS; - if (!inode->i_sb->s_op->statfs) { - iput(inode); - goto out; + dentry = namei(path); + retval = PTR_ERR(dentry); + if (!IS_ERR(dentry)) { + retval = do_osf_statfs(dentry, buffer, bufsiz); + dput(dentry); } - inode->i_sb->s_op->statfs(inode->i_sb, &linux_stat, sizeof(linux_stat)); - linux_to_osf_statfs(&linux_stat, buffer); - iput(inode); - retval = 0; -out: unlock_kernel(); return retval; } asmlinkage int osf_fstatfs(unsigned long fd, struct osf_statfs *buffer, unsigned long bufsiz) { - struct statfs linux_stat; struct file *file; - struct inode *inode; + struct dentry *dentry; int retval; lock_kernel(); - retval = verify_area(VERIFY_WRITE, buffer, bufsiz); - if (retval) - goto out; - if (bufsiz > sizeof(struct osf_statfs)) - bufsiz = sizeof(struct osf_statfs); retval = -EBADF; if (fd >= NR_OPEN || !(file = current->files->fd[fd])) goto out; - retval = -ENOENT; - if (!(inode = file->f_inode)) - goto out; - retval = -ENOSYS; - if (!inode->i_sb->s_op->statfs) - goto out; - inode->i_sb->s_op->statfs(inode->i_sb, &linux_stat, sizeof(linux_stat)); - linux_to_osf_statfs(&linux_stat, buffer); - retval = 0; + dentry = file->f_dentry; + if (dentry) + retval = do_osf_statfs(dentry, buffer, bufsiz); out: unlock_kernel(); return retval; @@ -369,56 +382,60 @@ struct procfs_args { uid_t exroot; }; -static int getdev(const char *name, int rdonly, struct inode **ino) +static int getdev(const char *name, int rdonly, struct dentry **dp) { kdev_t dev; + struct dentry *dentry; struct inode *inode; struct file_operations *fops; int retval; - retval = namei(NAM_FOLLOW_LINK, name, &inode); - if (retval) + dentry = namei(name); + retval = PTR_ERR(dentry); + if (IS_ERR(dentry)) return retval; + + inode = dentry->d_inode; if (!S_ISBLK(inode->i_mode)) { - iput(inode); + dput(dentry); return -ENOTBLK; } if (IS_NODEV(inode)) { - iput(inode); + dput(dentry); return -EACCES; } dev = inode->i_rdev; if (MAJOR(dev) >= MAX_BLKDEV) { - iput(inode); + dput(dentry); return -ENXIO; } fops = get_blkfops(MAJOR(dev)); if (!fops) { - iput(inode); + dput(dentry); return -ENODEV; } if (fops->open) { struct file dummy; memset(&dummy, 0, sizeof(dummy)); - dummy.f_inode = inode; + dummy.f_dentry = dentry; dummy.f_mode = rdonly ? 1 : 3; retval = fops->open(inode, &dummy); if (retval) { - iput(inode); + dput(dentry); return retval; } } - *ino = inode; + *dp = dentry; return 0; } -static void putdev(struct inode *inode) +static void putdev(struct dentry *dentry) { struct file_operations *fops; - fops = get_blkfops(MAJOR(inode->i_rdev)); + fops = get_blkfops(MAJOR(dentry->d_inode->i_rdev)); if (fops->release) - fops->release(inode, NULL); + fops->release(dentry->d_inode, NULL); } /* @@ -429,40 +446,40 @@ static void putdev(struct inode *inode) static int osf_ufs_mount(char *dirname, struct ufs_args *args, int flags) { int retval; - struct inode *inode; + struct dentry *dentry; struct cdfs_args tmp; retval = verify_area(VERIFY_READ, args, sizeof(*args)); if (retval) return retval; copy_from_user(&tmp, args, sizeof(tmp)); - retval = getdev(tmp.devname, 0, &inode); + retval = getdev(tmp.devname, 0, &dentry); if (retval) return retval; - retval = do_mount(inode->i_rdev, tmp.devname, dirname, "ext2", flags, NULL); + retval = do_mount(dentry->d_inode->i_rdev, tmp.devname, dirname, "ext2", flags, NULL); if (retval) - putdev(inode); - iput(inode); + putdev(dentry); + dput(dentry); return retval; } static int osf_cdfs_mount(char *dirname, struct cdfs_args *args, int flags) { int retval; - struct inode *inode; + struct dentry * dentry; struct cdfs_args tmp; retval = verify_area(VERIFY_READ, args, sizeof(*args)); if (retval) return retval; copy_from_user(&tmp, args, sizeof(tmp)); - retval = getdev(tmp.devname, 1, &inode); + retval = getdev(tmp.devname, 1, &dentry); if (retval) return retval; - retval = do_mount(inode->i_rdev, tmp.devname, dirname, "iso9660", flags, NULL); + retval = do_mount(dentry->d_inode->i_rdev, tmp.devname, dirname, "iso9660", flags, NULL); if (retval) - putdev(inode); - iput(inode); + putdev(dentry); + dput(dentry); return retval; } @@ -876,6 +893,9 @@ asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer, return -EOPNOTSUPP; } +/* Dummy functions for now */ +#define wrfpcr(x) do { } while (0) +#define rdfpcr() 0 asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer, unsigned long nbytes, diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index b6c97e726..81744663d 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -308,8 +308,9 @@ asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2, char * filename; lock_kernel(); - error = getname((char *) a0, &filename); - if (error) + filename = getname((char *) a0); + error = PTR_ERR(filename); + if (IS_ERR(filename)) goto out; error = do_execve(filename, (char **) a1, (char **) a2, ®s); putname(filename); diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index 02fa5a35d..c3838a8bb 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -24,13 +24,14 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err, unsigned long *r9_15) { long i; - unsigned long sp, ra; + 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); + 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); @@ -54,7 +55,7 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err, 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 = %016lx\n", regs->gp, sp); + printk("gp = %016lx sp = %p\n", regs->gp, sp); printk("Code:"); pc = (unsigned int *) regs->pc; @@ -65,6 +66,19 @@ void die_if_kernel(char * str, struct pt_regs * regs, long err, printk("%c%08x%c",i?' ':'<',insn,i?' ':'>'); } printk("\n"); + printk("Trace:"); + while (0x1ff8 & (unsigned long) sp) { + extern unsigned long _stext, _etext; + unsigned long tmp = *sp; + sp++; + if (tmp < (unsigned long) &_stext) + continue; + if (tmp >= (unsigned long) &_etext) + continue; + printk(" [<%lx>]", tmp); + } + printk("\n"); + do_exit(SIGSEGV); } diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index a8bc34108..72d4224f7 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c @@ -67,8 +67,7 @@ asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr, long cause, struct pt_regs *regs) { struct vm_area_struct * vma; - struct task_struct *tsk = current; - struct mm_struct *mm = tsk->mm; + struct mm_struct *mm = current->mm; unsigned fixup; down(&mm->mmap_sem); @@ -97,7 +96,7 @@ good_area: if (!(vma->vm_flags & VM_WRITE)) goto bad_area; } - handle_mm_fault(tsk, vma, address, cause > 0); + handle_mm_fault(current, vma, address, cause > 0); up(&mm->mmap_sem); return; @@ -108,23 +107,20 @@ good_area: bad_area: up(&mm->mmap_sem); + if (user_mode(regs)) { + force_sig(SIGSEGV, current); + return; + } + /* Are we prepared to handle this fault as an exception? */ if ((fixup = search_exception_table(regs->pc)) != 0) { unsigned long newpc; newpc = fixup_exception(dpf_reg, fixup, regs->pc); - printk("Taking exception at [<%lx>] (%lx)\n", regs->pc, newpc); + printk("%s: Exception at [<%lx>] (%lx)\n", current->comm, regs->pc, newpc); regs->pc = newpc; return; } - if (user_mode(regs)) { - printk("%s: memory violation at pc=%08lx ra=%08lx " - "(bad address = %08lx)\n", - tsk->comm, regs->pc, regs->r26, address); - die_if_kernel("oops", regs, cause, (unsigned long*)regs - 16); - force_sig(SIGSEGV, tsk); - return; - } /* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. |