summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r--arch/sparc64/kernel/power.c5
-rw-r--r--arch/sparc64/kernel/sys_sparc.c25
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c7
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c22
-rw-r--r--arch/sparc64/kernel/time.c6
5 files changed, 48 insertions, 17 deletions
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index e55466c77b6..0b9c70627ce 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -4,8 +4,6 @@
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
*/
-#define __KERNEL_SYSCALLS__
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -14,6 +12,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
+#include <linux/syscalls.h>
#include <asm/system.h>
#include <asm/auxio.h>
@@ -98,7 +97,7 @@ again:
/* Ok, down we go... */
button_pressed = 0;
- if (execve("/sbin/shutdown", argv, envp) < 0) {
+ if (kernel_execve("/sbin/shutdown", argv, envp) < 0) {
printk("powerd: shutdown execution failed\n");
add_wait_queue(&powerd_wait, &wait);
goto again;
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index c608c947e6c..a53d4abb4b4 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -31,6 +31,7 @@
#include <asm/utrap.h>
#include <asm/perfctr.h>
#include <asm/a.out.h>
+#include <asm/unistd.h>
/* #define DEBUG_UNIMP_SYSCALL */
@@ -712,13 +713,13 @@ asmlinkage long 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:
@@ -963,3 +964,23 @@ asmlinkage long sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1,
};
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 0x6d\n\t"
+ "sub %%g0, %%o0, %0\n\t"
+ "movcc %%xcc, %%o0, %0\n\t"
+ : "=r" (__res), "=&r" (__o0)
+ : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1)
+ : "cc");
+ return __res;
+}
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index c88ae23ce81..dbc6d1a3be1 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -337,12 +337,17 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
{
+ compat_ino_t ino;
int err;
if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) ||
!old_valid_dev(stat->rdev))
return -EOVERFLOW;
+ ino = stat->ino;
+ if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+ return -EOVERFLOW;
+
err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
err |= put_user(stat->ino, &statbuf->st_ino);
err |= put_user(stat->mode, &statbuf->st_mode);
@@ -1016,7 +1021,7 @@ struct __sysctl_args32 {
asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
{
-#ifndef CONFIG_SYSCTL
+#ifndef CONFIG_SYSCTL_SYSCALL
return -ENOSYS;
#else
struct __sysctl_args32 tmp;
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 87ebdf858a3..e414c8ef022 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -280,16 +280,20 @@ static int sunos_filldir(void * __buf, const char * name, int namlen,
struct sunos_dirent __user *dirent;
struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+ u32 d_ino;
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);
if (copy_to_user(dirent->d_name, name, namlen))
@@ -363,14 +367,18 @@ static int sunos_filldirentry(void * __buf, const char * name, int namlen,
struct sunos_direntry_callback * buf =
(struct sunos_direntry_callback *) __buf;
int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+ u32 d_ino;
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);
if (copy_to_user(dirent->d_name, name, namlen))
@@ -439,16 +447,16 @@ 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],
+ ret = copy_to_user(&name->sname[0], &utsname()->sysname[0],
sizeof(name->sname) - 1);
- ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0],
+ 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],
+ ret |= copy_to_user(&name->rel[0], &utsname()->release[0],
sizeof(name->rel) - 1);
- ret |= copy_to_user(&name->ver[0], &system_utsname.version[0],
+ ret |= copy_to_user(&name->ver[0], &utsname()->version[0],
sizeof(name->ver) - 1);
- ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0],
+ ret |= copy_to_user(&name->mach[0], &utsname()->machine[0],
sizeof(name->mach) - 1);
up_read(&uts_sem);
return (ret ? -EFAULT : 0);
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index b0b4feeec09..00f6fc4aaaf 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -53,8 +53,6 @@ void __iomem *mstk48t02_regs = NULL;
unsigned long ds1287_regs = 0UL;
#endif
-extern unsigned long wall_jiffies;
-
static void __iomem *mstk48t08_regs;
static void __iomem *mstk48t59_regs;
@@ -465,7 +463,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
profile_tick(CPU_PROFILING, regs);
update_process_times(user_mode(regs));
#endif
- do_timer(regs);
+ do_timer(1);
/* Guarantee that the following sequences execute
* uninterrupted.
@@ -496,7 +494,7 @@ void timer_tick_interrupt(struct pt_regs *regs)
{
write_seqlock(&xtime_lock);
- do_timer(regs);
+ do_timer(1);
timer_check_rtc();