diff options
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r-- | arch/sparc/kernel/sys_solaris.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/sys_sparc.c | 27 | ||||
-rw-r--r-- | arch/sparc/kernel/sys_sunos.c | 31 |
3 files changed, 48 insertions, 12 deletions
diff --git a/arch/sparc/kernel/sys_solaris.c b/arch/sparc/kernel/sys_solaris.c index c09afd96dd9c8f..01b07bb440f074 100644 --- a/arch/sparc/kernel/sys_solaris.c +++ b/arch/sparc/kernel/sys_solaris.c @@ -1,5 +1,5 @@ /* - * linux/arch/sparc/sys_solaris.c + * linux/arch/sparc/kernel/sys_solaris.c * * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx) */ diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 896863fb208a1a..a954a0c0000024 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -24,6 +24,7 @@ #include <asm/uaccess.h> #include <asm/ipc.h> +#include <asm/unistd.h> /* #define DEBUG_UNIMP_SYSCALL */ @@ -475,16 +476,38 @@ asmlinkage int sys_getdomainname(char __user *name, int len) down_read(&uts_sem); - nlen = strlen(system_utsname.domainname) + 1; + nlen = strlen(utsname()->domainname) + 1; err = -EINVAL; if (nlen > len) goto out; err = -EFAULT; - if (!copy_to_user(name, system_utsname.domainname, nlen)) + if (!copy_to_user(name, utsname()->domainname, nlen)) err = 0; out: up_read(&uts_sem); return err; } + +/* + * Do a system call from kernel instead of calling sys_execve so we + * end up with proper pt_regs. + */ +int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +{ + long __res; + register long __g1 __asm__ ("g1") = __NR_execve; + register long __o0 __asm__ ("o0") = (long)(filename); + register long __o1 __asm__ ("o1") = (long)(argv); + register long __o2 __asm__ ("o2") = (long)(envp); + asm volatile ("t 0x10\n\t" + "bcc 1f\n\t" + "mov %%o0, %0\n\t" + "sub %%g0, %%o0, %0\n\t" + "1:\n\t" + : "=r" (__res), "=&r" (__o0) + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) + : "cc"); + return __res; +} diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index aa0fb2efb61542..6f3ac548ee66db 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c @@ -325,21 +325,25 @@ struct sunos_dirent_callback { #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) static int sunos_filldir(void * __buf, const char * name, int namlen, - loff_t offset, ino_t ino, unsigned int d_type) + loff_t offset, u64 ino, unsigned int d_type) { struct sunos_dirent __user *dirent; struct sunos_dirent_callback * buf = __buf; + unsigned long d_ino; int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; + d_ino = ino; + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) + return -EOVERFLOW; dirent = buf->previous; if (dirent) put_user(offset, &dirent->d_off); dirent = buf->curr; buf->previous = dirent; - put_user(ino, &dirent->d_ino); + put_user(d_ino, &dirent->d_ino); put_user(namlen, &dirent->d_namlen); put_user(reclen, &dirent->d_reclen); copy_to_user(dirent->d_name, name, namlen); @@ -406,19 +410,23 @@ struct sunos_direntry_callback { }; static int sunos_filldirentry(void * __buf, const char * name, int namlen, - loff_t offset, ino_t ino, unsigned int d_type) + loff_t offset, u64 ino, unsigned int d_type) { struct sunos_direntry __user *dirent; struct sunos_direntry_callback *buf = __buf; + unsigned long d_ino; int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; + d_ino = ino; + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) + return -EOVERFLOW; dirent = buf->previous; dirent = buf->curr; buf->previous = dirent; - put_user(ino, &dirent->d_ino); + put_user(d_ino, &dirent->d_ino); put_user(namlen, &dirent->d_namlen); put_user(reclen, &dirent->d_reclen); copy_to_user(dirent->d_name, name, namlen); @@ -483,13 +491,18 @@ asmlinkage int sunos_uname(struct sunos_utsname __user *name) { int ret; down_read(&uts_sem); - ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1); + ret = copy_to_user(&name->sname[0], &utsname()->sysname[0], + sizeof(name->sname) - 1); if (!ret) { - ret |= __copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1); + ret |= __copy_to_user(&name->nname[0], &utsname()->nodename[0], + sizeof(name->nname) - 1); ret |= __put_user('\0', &name->nname[8]); - ret |= __copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1); - ret |= __copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1); - ret |= __copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1); + ret |= __copy_to_user(&name->rel[0], &utsname()->release[0], + sizeof(name->rel) - 1); + ret |= __copy_to_user(&name->ver[0], &utsname()->version[0], + sizeof(name->ver) - 1); + ret |= __copy_to_user(&name->mach[0], &utsname()->machine[0], + sizeof(name->mach) - 1); } up_read(&uts_sem); return ret ? -EFAULT : 0; |